diff --git a/src/mesh/GmshReader.cpp b/src/mesh/GmshReader.cpp
index d45e6c90b844082fef7708ba55924be2f599e3e2..931285274c3e83423993f8d66b3ac9cbfc17799e 100644
--- a/src/mesh/GmshReader.cpp
+++ b/src/mesh/GmshReader.cpp
@@ -140,6 +140,63 @@ ErrorHandler(const std::string& filename,
 }
 
 
+template <int Dimension>
+void GmshReader::_dispatch()
+{
+  using ConnectivityType = Connectivity<Dimension>;
+  using Rd = TinyVector<Dimension>;
+  using MeshType = Mesh<ConnectivityType>;
+
+  if (not m_mesh) {
+    std::shared_ptr<ConnectivityType> connectivity(new ConnectivityType({},{}));
+    NodeValue<Rd> xr;
+    m_mesh = std::shared_ptr<IMesh>(new MeshType(connectivity, xr));
+  }
+
+  const MeshType& mesh = static_cast<const MeshType&>(*m_mesh);
+
+  CSRGraph mesh_graph = mesh.cellToCellGraph();
+
+  CellValue<int> cell_parts(mesh.connectivity());
+
+  const int reader_rank
+      = [&]() {
+          Array<int> parts = allGather(static_cast<int>(cell_parts.size()));
+          std::set<int> part_set;
+          for (size_t i=0; i<parts.size(); ++i) {
+            if (parts[i] != 0) { part_set.insert(i); }
+          }
+          if (part_set.size() != 1) {
+            perr() << "mesh should be read by one processor\n";
+          }
+          return *begin(part_set);
+        } ();
+
+  pout() << "Mesh read by process " << rang::style::bold << reader_rank << rang::style::reset << '\n';
+
+  Partitioner P;
+  Array<int> cell_new_owner = broadcast(P.partition(mesh_graph), reader_rank);
+
+  for (int i_rank=0; i_rank<commSize(); ++i_rank) {
+    if (commRank() == i_rank) {
+      size_t cpt=0;
+      std::cout << i_rank << " -> ";
+      for (size_t i=0; i<cell_new_owner.size(); ++i) {
+        if (commRank() == cell_new_owner[i]) {
+          std::cout << i << ' ';
+          cpt++;
+        }
+      }
+      std::cout << " [" << cpt << "]\n" << std::flush;
+    }
+    barrier();
+  }
+
+  Messenger::destroy();
+  std::exit(0);
+}
+
+
 GmshReader::GmshReader(const std::string& filename)
     : m_filename(filename)
 {
@@ -329,104 +386,24 @@ GmshReader::GmshReader(const std::string& filename)
 
             return *begin(dimension_set);
           }();
-    if (not m_mesh) {
-      switch(mesh_dimension) {
-        case 1: {
-          std::shared_ptr<Connectivity1D> connectivity(new Connectivity1D({},{}));
-          using Rd = TinyVector<1>;
-          NodeValue<Rd> xr;
-          m_mesh = std::shared_ptr<IMesh>(new Mesh<Connectivity1D>(connectivity, xr));
-          break;
-        }
-        case 2: {
-          std::shared_ptr<Connectivity2D> connectivity(new Connectivity2D({},{}));
-          using Rd = TinyVector<2>;
-          NodeValue<Rd> xr;
-          m_mesh = std::shared_ptr<IMesh>(new Mesh<Connectivity2D>(connectivity, xr));
-          break;
-        }
-        case 3: {
-          std::shared_ptr<Connectivity3D> connectivity(new Connectivity3D({},{}));
-          using Rd = TinyVector<3>;
-          NodeValue<Rd> xr;
-          m_mesh = std::shared_ptr<IMesh>(new Mesh<Connectivity3D>(connectivity, xr));
-          break;
-        }
-        default:{
-          perr() << "unexpected mesh dimension\n";
-          Messenger::destroy();
-          std::exit(1);
-        }
-      }
-    }
-    CSRGraph mesh_graph;
-    mesh_graph = m_mesh->cellToCellGraph();
-
-    CellValue<int> cell_parts;
-    switch(m_mesh->meshDimension())
-    {
+    switch (mesh_dimension) {
       case 1: {
-        Mesh<Connectivity1D>& mesh = dynamic_cast<Mesh<Connectivity1D>&>(*m_mesh);
-        CellValue<int> mesh_cell_parts(mesh.connectivity());
-        cell_parts = mesh_cell_parts;
+        this->_dispatch<1>();
         break;
       }
       case 2: {
-        Mesh<Connectivity2D>& mesh = dynamic_cast<Mesh<Connectivity2D>&>(*m_mesh);
-        CellValue<int> mesh_cell_parts(mesh.connectivity());
-        cell_parts = mesh_cell_parts;
+        this->_dispatch<2>();
         break;
       }
       case 3: {
-        Mesh<Connectivity3D>& mesh = dynamic_cast<Mesh<Connectivity3D>&>(*m_mesh);
-        CellValue<int> mesh_cell_parts(mesh.connectivity());
-        cell_parts = mesh_cell_parts;
+        this->_dispatch<3>();
         break;
       }
-      default:{
-        perr() << "unexpected mesh dimension\n";
-        Messenger::destroy();
+      default: {
+        perr() << "unexpected dimension " << mesh_dimension << '\n';
         std::exit(1);
       }
     }
-
-    const int reader_rank
-        = [&]() {
-            Array<int> parts = allGather(static_cast<int>(cell_parts.size()));
-            std::set<int> part_set;
-            for (size_t i=0; i<parts.size(); ++i) {
-              if (parts[i] != 0) {
-                part_set.insert(i);
-              }
-            }
-            if (part_set.size() != 1) {
-              perr() << "mesh should be read by one processor\n";
-            }
-            return *begin(part_set);
-          } ();
-
-    pout() << "Mesh read by process " << rang::style::bold << reader_rank << rang::style::reset << '\n';
-
-    Partitioner P;
-    Array<int> cell_new_owner = broadcast(P.partition(mesh_graph), reader_rank);
-
-    for (int i_rank=0; i_rank<commSize(); ++i_rank) {
-      if (commRank() == i_rank) {
-        size_t cpt=0;
-        std::cout << i_rank << " -> ";
-        for (size_t i=0; i<cell_new_owner.size(); ++i) {
-          if (commRank() == cell_new_owner[i]) {
-            std::cout << i << ' ';
-            cpt++;
-          }
-        }
-        std::cout << " [" << cpt << "]\n" << std::flush;
-      }
-      barrier();
-    }
-
-    Messenger::destroy();
-    std::exit(0);
   }
 }
 
diff --git a/src/mesh/GmshReader.hpp b/src/mesh/GmshReader.hpp
index ba9ffe2502b4df46f59308f411747c7c2deaaac0..7364878a1e6d8f62e881eeaa7897911992fb3fac 100644
--- a/src/mesh/GmshReader.hpp
+++ b/src/mesh/GmshReader.hpp
@@ -246,6 +246,9 @@ private:
    */
   void __readPhysicalNames2_2();
 
+  template <int Dimension>
+  void _dispatch();
+
   std::shared_ptr<IMesh> m_mesh;
 public:
 
@@ -256,8 +259,6 @@ public:
 
   GmshReader(const std::string& filename);
   ~GmshReader() = default;
-
-
 };
 
 #endif // GMSH_READER_HPP