]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Added GridIn::read_msh()
authorLuca Heltai <luca.heltai@sissa.it>
Thu, 28 Jan 2021 11:34:02 +0000 (12:34 +0100)
committerLuca Heltai <luca.heltai@sissa.it>
Thu, 28 Jan 2021 11:34:02 +0000 (12:34 +0100)
include/deal.II/grid/grid_in.h
source/grid/grid_in.cc
tests/gmsh/gmsh_api_03.cc [new file with mode: 0644]
tests/gmsh/gmsh_api_03.with_gmsh_with_api=on.output [new file with mode: 0644]
tests/gmsh/gmsh_api_04.cc [new file with mode: 0644]
tests/gmsh/gmsh_api_04.with_gmsh_with_api=on.output [new file with mode: 0644]

index 03f7a9e5dcaa5e685186d50160fab6b1473b337a..465f786f0a20731da494abe24bd89c4eeb2745cc 100644 (file)
@@ -521,6 +521,65 @@ public:
   void
   read_msh(std::istream &in);
 
+#ifdef DEAL_II_GMSH_WITH_API
+  /**
+   * Read grid data using Gmsh API. Any file supported by Gmsh can be passed as
+   * argument. The format is deduced from the filename extension.
+   *
+   * This function interprets non-named physical ids (gmsh format < 4.0) as
+   * material or boundary ids (similarly to what happens with the other
+   * read_msh() function). If you want to specify non default manifold or
+   * boundary ids, you must group all entities that require a non default
+   * boundary or manifold id into named physical groups, where the name is
+   * interpreted using the function Patterns::Tools::to_value() applied to a
+   * `std::map<std::string, int>`. The keys can be either `MaterialID` (if the
+   * physical group refers to object of dimension `dim`), `BoundaryID` (if the
+   * group refers to objects of dimension < `dim`), or `ManifoldID`.
+   *
+   * From the Gmsh documentation, the formats of the physical tags follows the
+   * following conventions:
+   * @code
+   * $PhysicalNames // same as MSH version 2
+   *   numPhysicalNames(ASCII int)
+   *   dimension(ASCII int) physicalTag(ASCII int) "name"(127 characters max)
+   *   ...
+   * $EndPhysicalNames
+   * @endcode
+   *
+   * For example, the following snippet of mesh file
+   * @code
+   * MeshFormat
+   * 4.1 0 8
+   * $EndMeshFormat
+   * $PhysicalNames
+   * 4
+   * 1 1 "ManifoldID:0"
+   * 1 2 "BoundaryID: -1, ManifoldID: 1"
+   * 2 3 "ManifoldID: 1"
+   * 2 4 "MaterialID: 2, ManifoldID: 1"
+   * $EndPhysicalNames
+   * $Entities
+   * ...
+   * @endcode
+   *
+   * refers to a two dimensional grid where:
+   * - a portion of the boundary of dimension 1 has physical tag 1, and manifold
+   *   id 0
+   * - some internal faces (lines of dimension 1) have manifold id 1
+   * - some elements have manifold id 1 (and material id equal to the default
+   *   value, i.e., zero)
+   * - some elements have manifold id 1 and material id equal to 2
+   *
+   * If the physical groups are not named, then the behaviour is the same as
+   * the other read_msh() function, i.e., the physical tag itself is interpreted
+   * as a boundary or material id.
+   *
+   * @ingroup simplex
+   */
+  void
+  read_msh(const std::string &filename);
+#endif
+
   /**
    * Read grid data from a file containing tecplot ASCII data. This also works
    * in the absence of any tecplot installation.
index 2eec0e3195837ba696f7a72c8a842462caf7863c..a0b57ff5b20e1108d144d69a3cdaaa1a8a6ab0f0 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <deal.II/base/exceptions.h>
 #include <deal.II/base/path_search.h>
+#include <deal.II/base/patterns.h>
 #include <deal.II/base/utilities.h>
 
 #include <deal.II/grid/grid_in.h>
 #include <boost/property_tree/xml_parser.hpp>
 #include <boost/serialization/serialization.hpp>
 
+#ifdef DEAL_II_GMSH_WITH_API
+#  include <gmsh.h>
+#endif
+
 #include <algorithm>
 #include <cctype>
 #include <fstream>
@@ -2178,6 +2183,219 @@ GridIn<dim, spacedim>::read_msh(std::istream &in)
 
 
 
+#ifdef DEAL_II_GMSH_WITH_API
+template <int dim, int spacedim>
+void
+GridIn<dim, spacedim>::read_msh(const std::string &fname)
+{
+  Assert(tria != nullptr, ExcNoTriangulationSelected());
+  // gmsh -> deal.II types
+  const std::map<int, std::uint8_t> gmsh_to_dealii_type = {
+    {{15, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {7, 5}, {6, 6}, {5, 7}}};
+
+  // Vertex renumbering, by dealii type
+  const std::vector<std::vector<unsigned int>> gmsh_to_dealii = {
+    {{{0}},
+     {{0, 1}},
+     {{0, 1, 2}},
+     {{0, 1, 3, 2}},
+     {{0, 1, 2, 3}},
+     {{0, 1, 3, 2, 4}},
+     {{0, 1, 2, 3, 4, 5}},
+     {{0, 1, 3, 2, 4, 5, 7, 6}}}};
+
+  std::vector<Point<spacedim>>               vertices;
+  std::vector<CellData<dim>>                 cells;
+  SubCellData                                subcelldata;
+  std::map<unsigned int, types::boundary_id> boundary_ids_1d;
+
+  gmsh::initialize();
+  gmsh::option::setNumber("General.Verbosity", 0);
+  gmsh::open(fname);
+
+  AssertThrow(gmsh::model::getDimension() == dim,
+              ExcMessage("You are trying to read a gmsh file with dimension " +
+                         std::to_string(gmsh::model::getDimension()) +
+                         " into a grid of dimension " + std::to_string(dim)));
+
+  // Read all nodes, and store them in our vector of vertices. Before we do
+  // that, make sure all tags are consecutive
+  {
+    gmsh::model::mesh::removeDuplicateNodes();
+    gmsh::model::mesh::renumberNodes();
+    std::vector<std::size_t> node_tags;
+    std::vector<double>      coord;
+    std::vector<double>      parametricCoord;
+    gmsh::model::mesh::getNodes(
+      node_tags, coord, parametricCoord, -1, -1, false, false);
+    vertices.resize(node_tags.size());
+    for (unsigned int i = 0; i < node_tags.size(); ++i)
+      {
+        // Check that renumbering worked!
+        AssertDimension(node_tags[i], i + 1);
+        for (unsigned int d = 0; d < spacedim; ++d)
+          vertices[i][d] = coord[i * 3 + d];
+#  ifdef DEBUG
+        // Make sure the embedded dimension is right
+        for (unsigned int d = spacedim; d < 3; ++d)
+          Assert(coord[i * 3 + d] == 0,
+                 ExcMessage("The grid you are reading contains nodes that are "
+                            "nonzero in the coordinate with index " +
+                            std::to_string(d) +
+                            ", but you are trying to save "
+                            "it on a grid embedded in a " +
+                            std::to_string(spacedim) + " dimensional space."));
+#  endif
+      }
+  }
+
+  // Get all the elementary entities in the model, as a vector of (dimension,
+  // tag) pairs:
+  std::vector<std::pair<int, int>> entities;
+  gmsh::model::getEntities(entities);
+
+  for (const auto &e : entities)
+    {
+      // Dimension and tag of the entity:
+      const int &entity_dim = e.first;
+      const int &entity_tag = e.second;
+
+      types::manifold_id manifold_id = numbers::flat_manifold_id;
+      types::boundary_id boundary_id = 0;
+
+      // Get the physical tags, to deduce boundary, material, and manifold_id
+      std::vector<int> physical_tags;
+      gmsh::model::getPhysicalGroupsForEntity(entity_dim,
+                                              entity_tag,
+                                              physical_tags);
+
+      // Now fill manifold id and boundary or material id
+      if (physical_tags.size())
+        for (auto physical_tag : physical_tags)
+          {
+            std::string name;
+            gmsh::model::getPhysicalName(entity_dim, physical_tag, name);
+            if (!name.empty())
+              try
+                {
+                  std::map<std::string, int> id_names;
+                  Patterns::Tools::to_value(name, id_names);
+                  bool throw_anyway      = false;
+                  bool found_boundary_id = false;
+                  // If the above did not throw, we keep going, and retrieve
+                  // all the information that we know how to translate.
+                  for (const auto &it : id_names)
+                    {
+                      const auto &name = it.first;
+                      const auto &id   = it.second;
+                      if (entity_dim == dim && name == "MaterialID")
+                        {
+                          boundary_id = static_cast<types::boundary_id>(id);
+                          found_boundary_id = true;
+                        }
+                      else if (entity_dim < dim && name == "BoundaryID")
+                        {
+                          boundary_id = static_cast<types::boundary_id>(id);
+                          found_boundary_id = true;
+                        }
+                      else if (name == "ManifoldID")
+                        manifold_id = static_cast<types::manifold_id>(id);
+                      else
+                        // We did not recognize one of the keys. We'll fall
+                        // back to setting the boundary id to the physical tag
+                        // after reading all strings.
+                        throw_anyway = true;
+                    }
+                  // If we didn't find a BoundaryID:XX or MaterialID:XX, and
+                  // something was found but not recognized, then we set the
+                  // material id or boundary id in the catch block below, using
+                  // directly the physical tag
+                  if (throw_anyway && !found_boundary_id)
+                    throw;
+                }
+              catch (...)
+                {
+                  // When the above didn't work, we revert to the old
+                  // behaviour: the physical tag itself is interpreted either
+                  // as a material_id or a boundary_id, and no manifold id is
+                  // known
+                  boundary_id = physical_tag;
+                }
+          }
+
+      // Get the mesh elements for the entity (dim, tag):
+      std::vector<int>                      element_types;
+      std::vector<std::vector<std::size_t>> element_ids, element_nodes;
+      gmsh::model::mesh::getElements(
+        element_types, element_ids, element_nodes, entity_dim, entity_tag);
+
+      for (unsigned int i = 0; i < element_types.size(); ++i)
+        {
+          const auto &type       = gmsh_to_dealii_type.at(element_types[i]);
+          const auto  n_vertices = gmsh_to_dealii[type].size();
+          const auto &elements   = element_ids[i];
+          const auto &nodes      = element_nodes[i];
+          for (unsigned int j = 0; j < elements.size(); ++j)
+            {
+              if (entity_dim == dim)
+                {
+                  cells.emplace_back(n_vertices);
+                  auto &cell = cells.back();
+                  for (unsigned int v = 0; v < n_vertices; ++v)
+                    cell.vertices[v] =
+                      nodes[n_vertices * j + gmsh_to_dealii[type][v]] - 1;
+                  cell.manifold_id = manifold_id;
+                  cell.material_id = boundary_id;
+                }
+              else if (entity_dim == 2)
+                {
+                  subcelldata.boundary_quads.emplace_back(n_vertices);
+                  auto &face = subcelldata.boundary_quads.back();
+                  for (unsigned int v = 0; v < n_vertices; ++v)
+                    face.vertices[v] =
+                      nodes[n_vertices * j + gmsh_to_dealii[type][v]] - 1;
+
+                  face.manifold_id = manifold_id;
+                  face.boundary_id = boundary_id;
+                }
+              else if (entity_dim == 1)
+                {
+                  subcelldata.boundary_lines.emplace_back(n_vertices);
+                  auto &line = subcelldata.boundary_lines.back();
+                  for (unsigned int v = 0; v < n_vertices; ++v)
+                    line.vertices[v] =
+                      nodes[n_vertices * j + gmsh_to_dealii[type][v]] - 1;
+
+                  line.manifold_id = manifold_id;
+                  line.boundary_id = boundary_id;
+                }
+              else if (entity_dim == 0)
+                {
+                  // This should only happen in one dimension.
+                  AssertDimension(dim, 1);
+                  for (unsigned int j = 0; j < elements.size(); ++j)
+                    boundary_ids_1d[nodes[j] - 1] = boundary_id;
+                }
+            }
+        }
+    }
+
+  Assert(subcelldata.check_consistency(dim), ExcInternalError());
+
+  tria->create_triangulation(vertices, cells, subcelldata);
+
+  // in 1d, we also have to attach boundary ids to vertices, which does not
+  // currently work through the call above
+  if (dim == 1)
+    assign_1d_boundary_ids(boundary_ids_1d, *tria);
+
+  gmsh::clear();
+  gmsh::finalize();
+}
+#endif
+
+
+
 template <int dim, int spacedim>
 void
 GridIn<dim, spacedim>::parse_tecplot_header(
diff --git a/tests/gmsh/gmsh_api_03.cc b/tests/gmsh/gmsh_api_03.cc
new file mode 100644 (file)
index 0000000..af2483b
--- /dev/null
@@ -0,0 +1,65 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2021 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+// Create a hyper ball, use gmsh to output it and to read it back in.
+
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_in.h>
+#include <deal.II/grid/grid_out.h>
+#include <deal.II/grid/tria.h>
+
+#include "../tests.h"
+
+template <int dim, int spacedim>
+void
+test(const Triangulation<dim, spacedim> &tria)
+{
+  GridOut go;
+  go.write_msh(tria, "output.msh");
+
+  Triangulation<dim, spacedim> tria2;
+  GridIn<dim, spacedim>        gi(tria2);
+  gi.read_msh("output.msh");
+
+  go.write_msh(tria2, "output2.msh");
+
+  deallog << "Original mesh: " << std::endl;
+  cat_file("output.msh");
+  deallog << "Regenerated mesh: " << std::endl;
+  cat_file("output2.msh");
+}
+
+
+
+int
+main()
+{
+  initlog();
+  {
+    Triangulation<2> tria;
+    GridGenerator::hyper_ball(tria);
+    test(tria);
+  }
+  {
+    Triangulation<2, 3> tria;
+    GridGenerator::hyper_sphere(tria);
+    test(tria);
+  }
+  {
+    Triangulation<3, 3> tria;
+    GridGenerator::hyper_ball(tria);
+    test(tria);
+  }
+}
diff --git a/tests/gmsh/gmsh_api_03.with_gmsh_with_api=on.output b/tests/gmsh/gmsh_api_03.with_gmsh_with_api=on.output
new file mode 100644 (file)
index 0000000..7a7a768
--- /dev/null
@@ -0,0 +1,451 @@
+
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+2
+1 1 "ManifoldID:0"
+2 2 "ManifoldID:1"
+$EndPhysicalNames
+$Entities
+0 1 2 0
+1 -0.7071067811865475 -0.7071067811865475 0 0.7071067811865475 0.7071067811865475 0 1 1 0 
+2 -0.7071067811865475 -0.7071067811865475 0 0.7071067811865475 0.7071067811865475 0 1 2 0 
+3 -0.2928932188134525 -0.2928932188134525 0 0.2928932188134525 0.2928932188134525 0 1 3 0 
+$EndEntities
+$Nodes
+3 8 1 8
+1 1 0 4
+1
+2
+7
+8
+-0.7071067811865475 -0.7071067811865475 0
+0.7071067811865475 -0.7071067811865475 0
+-0.7071067811865475 0.7071067811865475 0
+0.7071067811865475 0.7071067811865475 0
+2 2 0 4
+3
+4
+5
+6
+-0.2928932188134525 -0.2928932188134525 0
+0.2928932188134525 -0.2928932188134525 0
+-0.2928932188134525 0.2928932188134525 0
+0.2928932188134525 0.2928932188134525 0
+2 3 0 0
+$EndNodes
+$Elements
+3 9 1 9
+1 1 1 4
+2 1 2 
+4 1 7 
+7 2 8 
+9 7 8 
+2 2 3 4
+1 1 2 4 3 
+3 1 3 5 7 
+6 2 8 6 4 
+8 7 5 6 8 
+2 3 3 1
+5 3 4 6 5 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+2
+1 1 "ManifoldID:0"
+2 2 "ManifoldID:1"
+$EndPhysicalNames
+$Entities
+0 1 2 0
+1 -0.7071067811865475 -0.7071067811865475 0 0.7071067811865475 0.7071067811865475 0 1 1 0 
+2 -0.7071067811865475 -0.7071067811865475 0 0.7071067811865475 0.7071067811865475 0 1 2 0 
+3 -0.2928932188134525 -0.2928932188134525 0 0.2928932188134525 0.2928932188134525 0 1 3 0 
+$EndEntities
+$Nodes
+3 8 1 8
+1 1 0 4
+1
+2
+3
+4
+-0.7071067811865475 -0.7071067811865475 0
+0.7071067811865475 -0.7071067811865475 0
+-0.7071067811865475 0.7071067811865475 0
+0.7071067811865475 0.7071067811865475 0
+2 2 0 4
+5
+6
+7
+8
+-0.2928932188134525 -0.2928932188134525 0
+0.2928932188134525 -0.2928932188134525 0
+-0.2928932188134525 0.2928932188134525 0
+0.2928932188134525 0.2928932188134525 0
+2 3 0 0
+$EndNodes
+$Elements
+3 9 1 9
+1 1 1 4
+2 1 2 
+4 1 3 
+6 2 4 
+8 3 4 
+2 2 3 4
+1 1 2 6 5 
+3 1 5 7 3 
+5 2 4 8 6 
+7 3 7 8 4 
+2 3 3 1
+9 5 6 8 7 
+$EndElements
+
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+2
+1 1 "BoundaryID:-1, ManifoldID:0"
+2 2 "ManifoldID:0"
+$EndPhysicalNames
+$Entities
+0 1 1 0
+2 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 1 0 
+1 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 2 0 
+$EndEntities
+$Nodes
+2 8 1 8
+1 2 0 8
+1
+2
+3
+4
+5
+6
+7
+8
+-0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+-0.5773502691896258 0.5773502691896258 -0.5773502691896258
+0.5773502691896258 0.5773502691896258 -0.5773502691896258
+0.5773502691896258 -0.5773502691896258 0.5773502691896258
+0.5773502691896258 0.5773502691896258 0.5773502691896258
+-0.5773502691896258 -0.5773502691896258 0.5773502691896258
+-0.5773502691896258 0.5773502691896258 0.5773502691896258
+2 1 0 0
+$EndNodes
+$Elements
+2 30 1 30
+1 2 1 24
+2 1 2 
+3 3 4 
+4 1 3 
+5 2 4 
+7 2 5 
+8 4 6 
+9 2 4 
+10 5 6 
+12 7 8 
+13 5 6 
+14 7 5 
+15 8 6 
+17 1 3 
+18 7 8 
+19 1 7 
+20 3 8 
+22 1 7 
+23 2 5 
+24 1 2 
+25 7 5 
+27 3 4 
+28 8 6 
+29 3 8 
+30 4 6 
+2 1 3 6
+1 1 3 4 2 
+6 2 4 6 5 
+11 7 5 6 8 
+16 1 7 8 3 
+21 1 2 5 7 
+26 3 8 6 4 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+2
+1 1 "BoundaryID:-1, ManifoldID:0"
+2 2 "ManifoldID:0"
+$EndPhysicalNames
+$Entities
+0 1 1 0
+2 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 1 0 
+1 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 2 0 
+$EndEntities
+$Nodes
+2 8 1 8
+1 2 0 8
+1
+2
+3
+4
+5
+6
+7
+8
+-0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+-0.5773502691896258 0.5773502691896258 -0.5773502691896258
+0.5773502691896258 0.5773502691896258 -0.5773502691896258
+0.5773502691896258 -0.5773502691896258 0.5773502691896258
+0.5773502691896258 0.5773502691896258 0.5773502691896258
+-0.5773502691896258 -0.5773502691896258 0.5773502691896258
+-0.5773502691896258 0.5773502691896258 0.5773502691896258
+2 1 0 0
+$EndNodes
+$Elements
+2 30 1 30
+1 2 1 24
+2 1 2 
+3 3 4 
+4 1 3 
+5 2 4 
+7 2 5 
+8 4 6 
+9 2 4 
+10 5 6 
+12 7 8 
+13 5 6 
+14 7 5 
+15 8 6 
+17 1 3 
+18 7 8 
+19 1 7 
+20 3 8 
+22 1 7 
+23 2 5 
+24 1 2 
+25 7 5 
+27 3 4 
+28 8 6 
+29 3 8 
+30 4 6 
+2 1 3 6
+1 1 3 4 2 
+6 2 4 6 5 
+11 7 5 6 8 
+16 1 7 8 3 
+21 1 2 5 7 
+26 3 8 6 4 
+$EndElements
+
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+3
+1 1 "ManifoldID:0"
+2 2 "ManifoldID:0"
+3 3 "ManifoldID:1"
+$EndPhysicalNames
+$Entities
+0 1 1 2
+1 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 1 0 
+1 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 2 0 
+2 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 3 0 
+3 -0.2113248654051872 -0.2113248654051872 -0.2113248654051872 0.2113248654051872 0.2113248654051872 0.2113248654051872 1 4 0 
+$EndEntities
+$Nodes
+4 16 1 16
+1 1 0 8
+9
+10
+11
+12
+13
+14
+15
+16
+-0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+0.5773502691896258 -0.5773502691896258 0.5773502691896258
+-0.5773502691896258 -0.5773502691896258 0.5773502691896258
+-0.5773502691896258 0.5773502691896258 -0.5773502691896258
+0.5773502691896258 0.5773502691896258 -0.5773502691896258
+0.5773502691896258 0.5773502691896258 0.5773502691896258
+-0.5773502691896258 0.5773502691896258 0.5773502691896258
+2 1 0 0
+3 2 0 8
+1
+2
+3
+4
+5
+6
+7
+8
+-0.2113248654051872 -0.2113248654051872 -0.2113248654051872
+0.2113248654051872 -0.2113248654051872 -0.2113248654051872
+0.2113248654051872 -0.2113248654051872 0.2113248654051872
+-0.2113248654051872 -0.2113248654051872 0.2113248654051872
+-0.2113248654051872 0.2113248654051872 -0.2113248654051872
+0.2113248654051872 0.2113248654051872 -0.2113248654051872
+0.2113248654051872 0.2113248654051872 0.2113248654051872
+-0.2113248654051872 0.2113248654051872 0.2113248654051872
+3 3 0 0
+$EndNodes
+$Elements
+4 37 1 37
+1 1 1 24
+4 9 13 
+5 10 14 
+6 9 10 
+7 13 14 
+10 10 14 
+11 11 15 
+12 10 11 
+13 14 15 
+16 12 11 
+17 16 15 
+18 12 16 
+19 11 15 
+22 9 13 
+23 12 16 
+24 9 12 
+25 13 16 
+28 9 10 
+29 12 11 
+30 9 12 
+31 10 11 
+34 13 14 
+35 16 15 
+36 13 16 
+37 14 15 
+2 1 3 6
+3 9 10 14 13 
+9 10 11 15 14 
+15 12 16 15 11 
+21 9 13 16 12 
+27 9 12 11 10 
+33 13 14 15 16 
+3 2 5 6
+2 9 10 14 13 1 2 6 5 
+8 10 14 6 2 11 15 7 3 
+14 12 11 3 4 16 15 7 8 
+20 9 1 5 13 12 4 8 16 
+26 9 10 2 1 12 11 3 4 
+32 13 5 6 14 16 8 7 15 
+3 3 5 1
+1 1 2 6 5 4 3 7 8 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+3
+1 1 "ManifoldID:0"
+2 2 "ManifoldID:0"
+3 3 "ManifoldID:1"
+$EndPhysicalNames
+$Entities
+0 1 1 2
+1 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 1 0 
+1 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 2 0 
+2 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258 0.5773502691896258 0.5773502691896258 0.5773502691896258 1 3 0 
+3 -0.2113248654051872 -0.2113248654051872 -0.2113248654051872 0.2113248654051872 0.2113248654051872 0.2113248654051872 1 4 0 
+$EndEntities
+$Nodes
+4 16 1 16
+1 1 0 8
+1
+2
+3
+4
+5
+6
+7
+8
+-0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+0.5773502691896258 -0.5773502691896258 0.5773502691896258
+-0.5773502691896258 -0.5773502691896258 0.5773502691896258
+-0.5773502691896258 0.5773502691896258 -0.5773502691896258
+0.5773502691896258 0.5773502691896258 -0.5773502691896258
+0.5773502691896258 0.5773502691896258 0.5773502691896258
+-0.5773502691896258 0.5773502691896258 0.5773502691896258
+2 1 0 0
+3 2 0 8
+9
+10
+11
+12
+13
+14
+15
+16
+-0.2113248654051872 -0.2113248654051872 -0.2113248654051872
+0.2113248654051872 -0.2113248654051872 -0.2113248654051872
+0.2113248654051872 -0.2113248654051872 0.2113248654051872
+-0.2113248654051872 -0.2113248654051872 0.2113248654051872
+-0.2113248654051872 0.2113248654051872 -0.2113248654051872
+0.2113248654051872 0.2113248654051872 -0.2113248654051872
+0.2113248654051872 0.2113248654051872 0.2113248654051872
+-0.2113248654051872 0.2113248654051872 0.2113248654051872
+3 3 0 0
+$EndNodes
+$Elements
+4 37 1 37
+1 1 1 24
+3 1 5 
+4 2 6 
+5 1 2 
+6 5 6 
+9 2 6 
+10 3 7 
+11 2 3 
+12 6 7 
+15 4 3 
+16 8 7 
+17 4 8 
+18 3 7 
+21 1 5 
+22 4 8 
+23 1 4 
+24 5 8 
+27 1 2 
+28 4 3 
+29 1 4 
+30 2 3 
+33 5 6 
+34 8 7 
+35 5 8 
+36 6 7 
+2 1 3 6
+2 1 2 6 5 
+8 2 3 7 6 
+14 4 8 7 3 
+20 1 5 8 4 
+26 1 4 3 2 
+32 5 6 7 8 
+3 2 5 6
+1 1 2 6 5 9 10 14 13 
+7 2 6 14 10 3 7 15 11 
+13 4 3 11 12 8 7 15 16 
+19 1 9 13 5 4 12 16 8 
+25 1 2 10 9 4 3 11 12 
+31 5 13 14 6 8 16 15 7 
+3 3 5 1
+37 9 10 14 13 12 11 15 16 
+$EndElements
+
diff --git a/tests/gmsh/gmsh_api_04.cc b/tests/gmsh/gmsh_api_04.cc
new file mode 100644 (file)
index 0000000..76c8db5
--- /dev/null
@@ -0,0 +1,86 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2021 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+// Create all reference cells, and output them with gmsh.
+
+#include <deal.II/grid/grid_in.h>
+#include <deal.II/grid/grid_out.h>
+#include <deal.II/grid/reference_cell.h>
+#include <deal.II/grid/tria.h>
+
+#include "../tests.h"
+
+template <int dim, int spacedim>
+void
+test(const std::uint8_t kind, const std::string out = "")
+{
+  deallog << "Testing kind(" << (int)kind << ") in dimensions "
+          << "<" << dim << "," << spacedim << ">" << std::endl;
+
+  Triangulation<dim, spacedim> tria;
+  ReferenceCell::make_triangulation(
+    ReferenceCell::internal::make_reference_cell_from_int(kind), tria);
+
+  GridOut go;
+  go.write_msh(tria, "output.msh");
+
+  Triangulation<dim, spacedim> tria2;
+  GridIn<dim, spacedim>        gi(tria2);
+  gi.read_msh("output.msh");
+
+  go.write_msh(tria2, "output2.msh");
+
+  deallog << "Original mesh: " << std::endl;
+  cat_file("output.msh");
+  deallog << "Regenerated mesh: " << std::endl;
+  cat_file("output2.msh");
+
+  // Uncomment to inspect each file separately
+  // if (out != "")
+  //   go.write_msh(tria2, out);
+  (void)out;
+}
+
+int
+main()
+{
+  initlog();
+
+  // Generate and print all reference cells
+  // Lines
+  test<1, 1>(1, "line_11.msh");
+  test<1, 2>(1, "line_12.msh");
+  test<1, 3>(1, "line_13.msh");
+
+  // Triangles
+  test<2, 2>(2, "tri_22.msh");
+  test<2, 3>(2, "tri_23.msh");
+
+  // Quads
+  test<2, 2>(3, "quad_22.msh");
+  test<2, 3>(3, "quad_23.msh");
+
+  // Tet
+  test<3, 3>(4, "tet_3.msh");
+
+  // Pyramid
+  test<3, 3>(5, "pyramid_3.msh");
+
+  // Wedge
+  test<3, 3>(6, "wedge_3.msh");
+
+  // Hex
+  test<3, 3>(7, "hex_3.msh");
+}
diff --git a/tests/gmsh/gmsh_api_04.with_gmsh_with_api=on.output b/tests/gmsh/gmsh_api_04.with_gmsh_with_api=on.output
new file mode 100644 (file)
index 0000000..c1c89d1
--- /dev/null
@@ -0,0 +1,616 @@
+
+DEAL::Testing kind(1) in dimensions <1,1>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+1
+0 1 "BoundaryID:1"
+$EndPhysicalNames
+$Entities
+1 1 0 0
+2 0 0 0 1 1 
+1 0 0 0 1 0 0 1 2 0 
+$EndEntities
+$Nodes
+2 2 1 2
+0 2 0 0
+1 1 0 2
+1
+2
+0 0 0
+1 0 0
+$EndNodes
+$Elements
+1 1 1 1
+1 1 1 1
+1 1 2 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+1
+0 1 "BoundaryID:1"
+$EndPhysicalNames
+$Entities
+1 1 0 0
+2 0 0 0 1 1 
+1 0 0 0 1 0 0 1 2 0 
+$EndEntities
+$Nodes
+2 2 1 2
+0 2 0 0
+1 1 0 2
+1
+2
+0 0 0
+1 0 0
+$EndNodes
+$Elements
+1 1 1 1
+1 1 1 1
+1 1 2 
+$EndElements
+
+DEAL::Testing kind(1) in dimensions <1,2>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+1
+0 1 "BoundaryID:1"
+$EndPhysicalNames
+$Entities
+1 1 0 0
+2 0 0 0 1 1 
+1 0 0 0 1 0 0 1 2 0 
+$EndEntities
+$Nodes
+2 2 1 2
+0 2 0 0
+1 1 0 2
+1
+2
+0 0 0
+1 0 0
+$EndNodes
+$Elements
+1 1 1 1
+1 1 1 1
+1 1 2 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+1
+0 1 "BoundaryID:1"
+$EndPhysicalNames
+$Entities
+1 1 0 0
+2 0 0 0 1 1 
+1 0 0 0 1 0 0 1 2 0 
+$EndEntities
+$Nodes
+2 2 1 2
+0 2 0 0
+1 1 0 2
+1
+2
+0 0 0
+1 0 0
+$EndNodes
+$Elements
+1 1 1 1
+1 1 1 1
+1 1 2 
+$EndElements
+
+DEAL::Testing kind(1) in dimensions <1,3>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+1
+0 1 "BoundaryID:1"
+$EndPhysicalNames
+$Entities
+1 1 0 0
+2 0 0 0 1 1 
+1 0 0 0 1 0 0 1 2 0 
+$EndEntities
+$Nodes
+2 2 1 2
+0 2 0 0
+1 1 0 2
+1
+2
+0 0 0
+1 0 0
+$EndNodes
+$Elements
+1 1 1 1
+1 1 1 1
+1 1 2 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$PhysicalNames
+1
+0 1 "BoundaryID:1"
+$EndPhysicalNames
+$Entities
+1 1 0 0
+2 0 0 0 1 1 
+1 0 0 0 1 0 0 1 2 0 
+$EndEntities
+$Nodes
+2 2 1 2
+0 2 0 0
+1 1 0 2
+1
+2
+0 0 0
+1 0 0
+$EndNodes
+$Elements
+1 1 1 1
+1 1 1 1
+1 1 2 
+$EndElements
+
+DEAL::Testing kind(2) in dimensions <2,2>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 1 0
+1 0 0 0 1 1 0 1 1 0 
+$EndEntities
+$Nodes
+1 3 1 3
+2 1 0 3
+1
+2
+3
+0 0 0
+1 0 0
+0 1 0
+$EndNodes
+$Elements
+1 1 1 1
+2 1 2 1
+1 1 2 3 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 1 0
+1 0 0 0 1 1 0 1 1 0 
+$EndEntities
+$Nodes
+1 3 1 3
+2 1 0 3
+1
+2
+3
+0 0 0
+1 0 0
+0 1 0
+$EndNodes
+$Elements
+1 1 1 1
+2 1 2 1
+1 1 2 3 
+$EndElements
+
+DEAL::Testing kind(2) in dimensions <2,3>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 1 0
+1 0 0 0 1 1 0 1 1 0 
+$EndEntities
+$Nodes
+1 3 1 3
+2 1 0 3
+1
+2
+3
+0 0 0
+1 0 0
+0 1 0
+$EndNodes
+$Elements
+1 1 1 1
+2 1 2 1
+1 1 2 3 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 1 0
+1 0 0 0 1 1 0 1 1 0 
+$EndEntities
+$Nodes
+1 3 1 3
+2 1 0 3
+1
+2
+3
+0 0 0
+1 0 0
+0 1 0
+$EndNodes
+$Elements
+1 1 1 1
+2 1 2 1
+1 1 2 3 
+$EndElements
+
+DEAL::Testing kind(3) in dimensions <2,2>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 1 0
+1 0 0 0 1 1 0 1 1 0 
+$EndEntities
+$Nodes
+1 4 1 4
+2 1 0 4
+1
+2
+3
+4
+0 0 0
+1 0 0
+0 1 0
+1 1 0
+$EndNodes
+$Elements
+1 1 1 1
+2 1 3 1
+1 1 2 4 3 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 1 0
+1 0 0 0 1 1 0 1 1 0 
+$EndEntities
+$Nodes
+1 4 1 4
+2 1 0 4
+1
+2
+3
+4
+0 0 0
+1 0 0
+0 1 0
+1 1 0
+$EndNodes
+$Elements
+1 1 1 1
+2 1 3 1
+1 1 2 4 3 
+$EndElements
+
+DEAL::Testing kind(3) in dimensions <2,3>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 1 0
+1 0 0 0 1 1 0 1 1 0 
+$EndEntities
+$Nodes
+1 4 1 4
+2 1 0 4
+1
+2
+3
+4
+0 0 0
+1 0 0
+0 1 0
+1 1 0
+$EndNodes
+$Elements
+1 1 1 1
+2 1 3 1
+1 1 2 4 3 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 1 0
+1 0 0 0 1 1 0 1 1 0 
+$EndEntities
+$Nodes
+1 4 1 4
+2 1 0 4
+1
+2
+3
+4
+0 0 0
+1 0 0
+0 1 0
+1 1 0
+$EndNodes
+$Elements
+1 1 1 1
+2 1 3 1
+1 1 2 4 3 
+$EndElements
+
+DEAL::Testing kind(4) in dimensions <3,3>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 0 1
+1 0 0 0 1 1 1 1 1 0 
+$EndEntities
+$Nodes
+1 4 1 4
+3 1 0 4
+1
+2
+3
+4
+0 0 0
+1 0 0
+0 1 0
+0 0 1
+$EndNodes
+$Elements
+1 1 1 1
+3 1 4 1
+1 1 2 3 4 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 0 1
+1 0 0 0 1 1 1 1 1 0 
+$EndEntities
+$Nodes
+1 4 1 4
+3 1 0 4
+1
+2
+3
+4
+0 0 0
+1 0 0
+0 1 0
+0 0 1
+$EndNodes
+$Elements
+1 1 1 1
+3 1 4 1
+1 1 2 3 4 
+$EndElements
+
+DEAL::Testing kind(5) in dimensions <3,3>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 0 1
+1 -1 -1 0 1 1 1 1 1 0 
+$EndEntities
+$Nodes
+1 5 1 5
+3 1 0 5
+1
+2
+3
+4
+5
+-1 -1 0
+1 -1 0
+-1 1 0
+1 1 0
+0 0 1
+$EndNodes
+$Elements
+1 1 1 1
+3 1 7 1
+1 1 2 4 3 5 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 0 1
+1 -1 -1 0 1 1 1 1 1 0 
+$EndEntities
+$Nodes
+1 5 1 5
+3 1 0 5
+1
+2
+3
+4
+5
+-1 -1 0
+1 -1 0
+-1 1 0
+1 1 0
+0 0 1
+$EndNodes
+$Elements
+1 1 1 1
+3 1 7 1
+1 1 2 4 3 5 
+$EndElements
+
+DEAL::Testing kind(6) in dimensions <3,3>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 0 1
+1 0 0 0 1 1 1 1 1 0 
+$EndEntities
+$Nodes
+1 6 1 6
+3 1 0 6
+1
+2
+3
+4
+5
+6
+1 0 0
+0 1 0
+0 0 0
+1 0 1
+0 1 1
+0 0 1
+$EndNodes
+$Elements
+1 1 1 1
+3 1 6 1
+1 1 2 3 4 5 6 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 0 1
+1 0 0 0 1 1 1 1 1 0 
+$EndEntities
+$Nodes
+1 6 1 6
+3 1 0 6
+1
+2
+3
+4
+5
+6
+1 0 0
+0 1 0
+0 0 0
+1 0 1
+0 1 1
+0 0 1
+$EndNodes
+$Elements
+1 1 1 1
+3 1 6 1
+1 1 2 3 4 5 6 
+$EndElements
+
+DEAL::Testing kind(7) in dimensions <3,3>
+DEAL::Original mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 0 1
+1 0 0 0 1 1 1 1 1 0 
+$EndEntities
+$Nodes
+1 8 1 8
+3 1 0 8
+1
+2
+3
+4
+5
+6
+7
+8
+0 0 0
+1 0 0
+0 1 0
+1 1 0
+0 0 1
+1 0 1
+0 1 1
+1 1 1
+$EndNodes
+$Elements
+1 1 1 1
+3 1 5 1
+1 1 2 4 3 5 6 8 7 
+$EndElements
+
+DEAL::Regenerated mesh: 
+$MeshFormat
+4.1 0 8
+$EndMeshFormat
+$Entities
+0 0 0 1
+1 0 0 0 1 1 1 1 1 0 
+$EndEntities
+$Nodes
+1 8 1 8
+3 1 0 8
+1
+2
+3
+4
+5
+6
+7
+8
+0 0 0
+1 0 0
+0 1 0
+1 1 0
+0 0 1
+1 0 1
+0 1 1
+1 1 1
+$EndNodes
+$Elements
+1 1 1 1
+3 1 5 1
+1 1 2 4 3 5 6 8 7 
+$EndElements
+

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.