diff --git a/src/mesh/CellType.hpp b/src/mesh/CellType.hpp
index f0f214a60d9e9fb214e221b7dac1516b9c69b778..3a0f01520bba191ff4535dfb407ddda55edab3c9 100644
--- a/src/mesh/CellType.hpp
+++ b/src/mesh/CellType.hpp
@@ -12,10 +12,11 @@ enum class CellType : unsigned short
   Triangle,
   Quadrangle,
 
-  Tetrahedron,
-  Pyramid,
+  Diamond,
+  Hexahedron,
   Prism,
-  Hexahedron
+  Pyramid,
+  Tetrahedron
 };
 
 PUGS_INLINE
@@ -29,14 +30,16 @@ name(CellType cell_type)
     return "triangle";
   case CellType::Quadrangle:
     return "quadrangle";
-  case CellType::Tetrahedron:
-    return "tetrahedron";
-  case CellType::Pyramid:
-    return "pyramid";
-  case CellType::Prism:
-    return "prism";
+  case CellType::Diamond:
+    return "diamond";
   case CellType::Hexahedron:
     return "hexahedron";
+  case CellType::Prism:
+    return "prism";
+  case CellType::Pyramid:
+    return "pyramid";
+  case CellType::Tetrahedron:
+    return "tetrahedron";
   default:
     return "unknown cell type";
   }
diff --git a/src/mesh/MeshBuilderBase.cpp b/src/mesh/MeshBuilderBase.cpp
index 74b2e0a2d71e9a56f8447b8b93e7578f72c93702..33236a9e2619d546c3bd6db1e7dbd307afa5da23 100644
--- a/src/mesh/MeshBuilderBase.cpp
+++ b/src/mesh/MeshBuilderBase.cpp
@@ -96,25 +96,6 @@ MeshBuilderBase::_computeCellFaceAndFaceNodeConnectivities(ConnectivityDescripto
       }
     } else if constexpr (Dimension == 3) {
       switch (descriptor.cell_type_vector[j]) {
-      case CellType::Tetrahedron: {
-        cell_nb_faces[j] = 4;
-        // face 0
-        Face f0({cell_nodes[1], cell_nodes[2], cell_nodes[3]}, node_number_vector);
-        face_cells_map[f0].emplace_back(std::make_tuple(j, 0, f0.reversed()));
-
-        // face 1
-        Face f1({cell_nodes[0], cell_nodes[3], cell_nodes[2]}, node_number_vector);
-        face_cells_map[f1].emplace_back(std::make_tuple(j, 1, f1.reversed()));
-
-        // face 2
-        Face f2({cell_nodes[0], cell_nodes[1], cell_nodes[3]}, node_number_vector);
-        face_cells_map[f2].emplace_back(std::make_tuple(j, 2, f2.reversed()));
-
-        // face 3
-        Face f3({cell_nodes[0], cell_nodes[2], cell_nodes[1]}, node_number_vector);
-        face_cells_map[f3].emplace_back(std::make_tuple(j, 3, f3.reversed()));
-        break;
-      }
       case CellType::Hexahedron: {
         // face 0
         Face f0({cell_nodes[3], cell_nodes[2], cell_nodes[1], cell_nodes[0]}, node_number_vector);
@@ -143,6 +124,69 @@ MeshBuilderBase::_computeCellFaceAndFaceNodeConnectivities(ConnectivityDescripto
         cell_nb_faces[j] = 6;
         break;
       }
+      case CellType::Tetrahedron: {
+        cell_nb_faces[j] = 4;
+        // face 0
+        Face f0({cell_nodes[1], cell_nodes[2], cell_nodes[3]}, node_number_vector);
+        face_cells_map[f0].emplace_back(std::make_tuple(j, 0, f0.reversed()));
+
+        // face 1
+        Face f1({cell_nodes[0], cell_nodes[3], cell_nodes[2]}, node_number_vector);
+        face_cells_map[f1].emplace_back(std::make_tuple(j, 1, f1.reversed()));
+
+        // face 2
+        Face f2({cell_nodes[0], cell_nodes[1], cell_nodes[3]}, node_number_vector);
+        face_cells_map[f2].emplace_back(std::make_tuple(j, 2, f2.reversed()));
+
+        // face 3
+        Face f3({cell_nodes[0], cell_nodes[2], cell_nodes[1]}, node_number_vector);
+        face_cells_map[f3].emplace_back(std::make_tuple(j, 3, f3.reversed()));
+        break;
+      }
+      case CellType::Pyramid: {
+        cell_nb_faces[j] = cell_nodes.size();
+        std::vector<unsigned int> base_nodes;
+        std::copy_n(cell_nodes.begin(), cell_nodes.size() - 1, std::back_inserter(base_nodes));
+
+        // base face
+        {
+          Face base_face(base_nodes, node_number_vector);
+          face_cells_map[base_face].emplace_back(std::make_tuple(j, 0, base_face.reversed()));
+        }
+        // side faces
+        const auto pyramid_vertex = cell_nodes[cell_nodes.size() - 1];
+        for (size_t i_node = 0; i_node < base_nodes.size(); ++i_node) {
+          Face side_face({base_nodes[(i_node + 1) % base_nodes.size()], base_nodes[i_node], pyramid_vertex},
+                         node_number_vector);
+          face_cells_map[side_face].emplace_back(std::make_tuple(j, i_node + 1, side_face.reversed()));
+        }
+        break;
+      }
+      case CellType::Diamond: {
+        cell_nb_faces[j] = 2 * (cell_nodes.size() - 2);
+        std::vector<unsigned int> base_nodes;
+        std::copy_n(cell_nodes.begin() + 1, cell_nodes.size() - 2, std::back_inserter(base_nodes));
+
+        {   // top faces
+          const auto top_vertex = cell_nodes[cell_nodes.size() - 1];
+          for (size_t i_node = 0; i_node < base_nodes.size(); ++i_node) {
+            Face top_face({base_nodes[i_node], base_nodes[(i_node + 1) % base_nodes.size()], top_vertex},
+                          node_number_vector);
+            face_cells_map[top_face].emplace_back(std::make_tuple(j, i_node, top_face.reversed()));
+          }
+        }
+
+        {   // bottom faces
+          const auto bottom_vertex = cell_nodes[0];
+          for (size_t i_node = 0; i_node < base_nodes.size(); ++i_node) {
+            Face bottom_face({base_nodes[(i_node + 1) % base_nodes.size()], base_nodes[i_node], bottom_vertex},
+                             node_number_vector);
+            face_cells_map[bottom_face].emplace_back(
+              std::make_tuple(j, i_node + base_nodes.size(), bottom_face.reversed()));
+          }
+        }
+        break;
+      }
       default: {
         std::ostringstream error_msg;
         error_msg << name(descriptor.cell_type_vector[j]) << ": unexpected cell type in dimension 3";
diff --git a/src/mesh/MeshBuilderBase.hpp b/src/mesh/MeshBuilderBase.hpp
index 4ba31798190303b082ff5711d55e21a03c11d2ae..03eae11d52dda3e593e6e8dba7e589e3c5f40ab1 100644
--- a/src/mesh/MeshBuilderBase.hpp
+++ b/src/mesh/MeshBuilderBase.hpp
@@ -44,7 +44,6 @@ class MeshBuilderBase::ConnectivityFace<2>
 {
  public:
   friend struct Hash;
-  friend class CartesianMeshBuilder;
 
   struct Hash
   {
@@ -122,10 +121,9 @@ class MeshBuilderBase::ConnectivityFace<2>
 template <>
 class MeshBuilderBase::ConnectivityFace<3>
 {
- private:
-  friend class GmshReader;
-  friend class CartesianMeshBuilder;
+ public:
   friend struct Hash;
+
   struct Hash
   {
     size_t