diff --git a/tutorials/poisson_robin_no_overlap/CMakeLists.txt b/tutorials/poisson_robin_no_overlap/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3ed63f13623e9d7ed45010b2a7ffd418461a2b0c
--- /dev/null
+++ b/tutorials/poisson_robin_no_overlap/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
+
+project(tuto CXX)
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../tutorial.cmake)
+
+add_executable(tuto main.cpp ${EXTRA_INCS})
+target_link_libraries(tuto ${EXTRA_LIBS})
diff --git a/tutorials/poisson_robin_no_overlap/README.md b/tutorials/poisson_robin_no_overlap/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..cc49cc5f69f2ef2c94642fb22c58c033bb24a62c
--- /dev/null
+++ b/tutorials/poisson_robin_no_overlap/README.md
@@ -0,0 +1,6 @@
+# Poisson Equation with overlap and Dirichlet 
+
+We solve a homogeneous Poisson (i.e. Laplace) equation with domain decomposition.
+The domain is a 2 by one rectangle, with boundary conditions $`u(0, y) = 0, u(2, y) = 2`$ and homogeneous von Neumann conditions on the other edges. The analytical solution is $`u(x,y) = x`$.
+
+This tutorial illustrates overlapping DDM. The first domain solves the equation for $`x`$ ranging from 0 to 1.2, and the other domain from 0.8 to 2. They exchange data over the center of the domain (0.8 to 1.2), which provide the boundary conditions on the inner boundaries.
\ No newline at end of file
diff --git a/tutorials/poisson_robin_no_overlap/domain.geo b/tutorials/poisson_robin_no_overlap/domain.geo
new file mode 100644
index 0000000000000000000000000000000000000000..805d938ef162b3b014b9b1b633cd9fd9f44ac643
--- /dev/null
+++ b/tutorials/poisson_robin_no_overlap/domain.geo
@@ -0,0 +1,45 @@
+// Gmsh project created on Fri Oct  7 15:45:08 2022
+//+
+Point(1) = {0, 0, 0, 0.05};
+//+
+Point(2) = {1, 0, 0, 0.05};
+//+
+Point(3) = {2, 0, 0, 0.05};
+//+
+Point(4) = {2, 1, 0, 0.05};
+//+
+Point(5) = {1, 1, 0, 0.05};
+//+
+Point(6) = {0, 1, 0, 0.05};
+//+
+Line(1) = {1, 2};
+//+
+Line(2) = {2, 3};
+//+
+Line(3) = {4, 3};
+//+
+Line(4) = {4, 5};
+//+
+Line(5) = {5, 6};
+//+
+Line(6) = {6, 1};
+//+
+Line(7) = {2, 5};
+//+
+Physical Curve("left", 8) = {6};
+//+
+Physical Curve("interface", 9) = {7};
+//+
+Physical Curve("right", 10) = {3};
+//+
+Curve Loop(1) = {6, 1, 7, 5};
+//+
+Plane Surface(1) = {1};
+//+
+Curve Loop(2) = {4, -7, 2, -3};
+//+
+Plane Surface(2) = {2};
+//+
+Physical Surface("omega0", 11) = {1};
+//+
+Physical Surface("omega1", 12) = {2};
diff --git a/tutorials/poisson_robin_no_overlap/main.cpp b/tutorials/poisson_robin_no_overlap/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0e3690747079d48695b0650b1897694db3d5a180
--- /dev/null
+++ b/tutorials/poisson_robin_no_overlap/main.cpp
@@ -0,0 +1,128 @@
+#include "gmsh.h"
+
+#include <gmshddm/Formulation.h>
+#include <gmshddm/GmshDdm.h>
+#include <gmshddm/MPIInterface.h>
+#include <gmshfem/Message.h>
+
+
+using namespace gmshddm;
+using namespace gmshddm::common;
+using namespace gmshddm::domain;
+using namespace gmshddm::problem;
+using namespace gmshddm::field;
+using namespace gmshddm::mpi;
+
+using namespace gmshfem;
+using namespace gmshfem::domain;
+using namespace gmshfem::equation;
+using namespace gmshfem::problem;
+using namespace gmshfem::field;
+using namespace gmshfem::function;
+using namespace gmshfem::post;
+
+
+int main(int argc, char **argv)
+{
+  GmshDdm gmshDdm(argc, argv);
+
+  unsigned int nDom = 2;
+  int order = 1;
+  double lc = 0.05;
+  std::string gauss = "Gauss10";
+
+  gmshDdm.userDefinedParameter(nDom, "nDom");
+  gmshDdm.userDefinedParameter(order, "order");
+  gmshDdm.userDefinedParameter(lc, "lc");
+  gmshDdm.userDefinedParameter(gauss, "gauss");
+
+  gmsh::open("../domain.geo"); // Assume we run from the "build" subfolder
+  gmsh::model::mesh::generate();
+
+  // Domains are partitions of the x-axis.
+  Domain omega0("omega0");
+  Domain omega1("omega1");
+
+  // Curves
+  Domain left("left"); // 0 to 1.2
+  Domain interface("interface"); // 0.8 to 1.2
+  Domain right("right"); // 0.8 to 2
+
+  
+
+  Subdomain omega(nDom);
+  Interface sigma(nDom);
+  omega(0) = omega0;// | interface;
+  omega(1) = omega1;// | interface;
+
+  sigma(0, 1) = interface;
+  sigma(1, 0) = interface;
+
+  std::vector< std::vector< unsigned int > > topology(nDom);
+  topology[0] = {1};
+  topology[1] = {0};
+
+  // Create DDM formulation
+  // And BCs on the subdomain problems
+  gmshddm::problem::Formulation< std::complex< double > > formulation("Laplace", topology);
+  SubdomainField< std::complex< double >, Form::Form0 > u("u", omega,  FunctionSpaceTypeForm0::HierarchicalH1, order);
+
+  // Toy problem with solution u(x,y) = x
+  u(0).addConstraint(left, 0);
+  u(1).addConstraint(right, 0);
+  auto trueSolution = 0.5 * x<std::complex< double >>() * (2.0 - x<std::complex< double >>());
+
+
+  InterfaceField< std::complex< double >, Form::Form0 > g("g", sigma, FunctionSpaceTypeForm0::HierarchicalH1, order);
+  formulation.addInterfaceField(g);
+
+
+  // First domain
+  // Laplacian(u) = -1 on the domain, and u matches g(1,0) on the interface
+  formulation(0).integral(grad(dof(u(0))), grad(tf(u(0))), omega(0)|interface, gauss);
+  formulation(0).integral(-1.0, tf(u(0)), omega(0)|interface, gauss);
+
+  formulation(0).integral((formulation.artificialSource(-g(1, 0))), tf(u(0)), interface, gauss);
+  //formulation(0).integral(dof(u(0)), tf(u(0)), interface, gauss);
+
+  // First interface (What 0 sends to 1)
+  // Compute g(0,1) such that g(0,1) + g(1,0) = 2 u(0)
+  formulation(0, 1).integral(-dof(g(0, 1)), tf(g(0, 1)), sigma(0, 1), gauss);
+  formulation(0, 1).integral(-formulation.artificialSource(g(1, 0)), tf(g(0, 1)), sigma(0, 1), gauss);
+  formulation(0, 1).integral((2 * u(0)), tf(g(0, 1)), sigma(0, 1), gauss);
+  //formulation(0, 1).integral((2* grad(u(0))) * normal<std::complex<double>>(), tf(g(0, 1)), sigma(0, 1), gauss);
+
+
+  // Second domain
+  formulation(1).integral(grad(dof(u(1))), grad(tf(u(1))), omega(1)|interface, gauss);
+  formulation(1).integral(-1.0, tf(u(1)), omega(1)|interface, gauss);
+
+  formulation(1).integral(formulation.artificialSource(-g(0, 1)), tf(u(1)), interface, gauss);
+  //formulation(1).integral(dof(u(1)), tf(u(1)), interface, gauss);
+
+  // Second interface
+  formulation(1, 0).integral(-dof(g(1, 0)), tf(g(1, 0)), sigma(1, 0), gauss);
+  formulation(1, 0).integral(-formulation.artificialSource(g(0, 1)), tf(g(1, 0)), sigma(1, 0), gauss);
+  formulation(1, 0).integral((2*u(1)), tf(g(1, 0)), sigma(1, 0), gauss);
+  //formulation(1, 0).integral((2* grad(u(1))) * normal<std::complex<double>>(), tf(g(0, 1)), sigma(0, 1), gauss);
+
+
+  formulation.pre();
+  int iterMax = 1000;
+  gmshDdm.userDefinedParameter(iterMax, "iter");
+  formulation.solve("gmres", 1e-6, iterMax);
+
+
+  for(unsigned int i = 0; i < nDom; ++i) {
+    if(isItMySubdomain(i)) {
+      save(u(i), omega(i), "u_" + std::to_string(i));
+      save(u(i) - trueSolution, omega(i), "err_" + std::to_string(i));
+      save(g(i, 1-i), sigma(i,1-i), "g");
+    }
+  }
+
+  save(trueSolution, omega(0) | omega(1) | interface, "true_sol");
+
+
+  return 0;
+}