diff --git a/AMDiS/src/parallel/PetscSolverFeti.cc b/AMDiS/src/parallel/PetscSolverFeti.cc
index 1423195786b8bb2ca4dd72bb98ff926ac1649870..59ef2bb442bdfcab3c2570a3e35a3ebaaedd36eb 100644
--- a/AMDiS/src/parallel/PetscSolverFeti.cc
+++ b/AMDiS/src/parallel/PetscSolverFeti.cc
@@ -768,9 +768,9 @@ namespace AMDiS {
     fetiData.subSolver = subdomain;
     fetiData.ksp_schur_primal = &ksp_schur_primal;
 
-    localDofMap.createVec(fetiData.tmp_vec_b, nGlobalOverallInterior);
+    localDofMap.createVec(fetiData.tmp_vec_b0, nGlobalOverallInterior);
     lagrangeMap.createVec(fetiData.tmp_vec_lagrange);
-    primalDofMap.createVec(fetiData.tmp_vec_primal);
+    primalDofMap.createVec(fetiData.tmp_vec_primal0);
 
     if (enableStokesMode == false) {      
       MatCreateShell(mpiCommGlobal,
@@ -782,6 +782,10 @@ namespace AMDiS {
       MatShellSetOperation(mat_feti, MATOP_MULT, 
 			   (void(*)(void))petscMultMatFeti);
     }  else {
+      localDofMap.createVec(fetiData.tmp_vec_b1, nGlobalOverallInterior);
+      primalDofMap.createVec(fetiData.tmp_vec_primal1);
+      interfaceDofMap.createVec(fetiData.tmp_vec_interface);
+
       MatCreateShell(mpiCommGlobal,
 		     interfaceDofMap.getRankDofs() + lagrangeMap.getRankDofs(), 
 		     interfaceDofMap.getRankDofs() + lagrangeMap.getRankDofs(),
@@ -789,7 +793,7 @@ namespace AMDiS {
 		     interfaceDofMap.getOverallDofs() + lagrangeMap.getOverallDofs(),
 		     &fetiData, &mat_feti);
       MatShellSetOperation(mat_feti, MATOP_MULT, 
-			   (void(*)(void))petscMultMatFetiInterface);
+			   (void(*)(void))petscMultMatFetiInterface);      
     }
 
     KSPCreate(mpiCommGlobal, &ksp_feti);
@@ -799,6 +803,27 @@ namespace AMDiS {
     KSPSetTolerances(ksp_feti, 0, 1e-8, 1e+3, 1000);
     KSPSetFromOptions(ksp_feti);
 
+    if (enableStokesMode) {
+      Vec nullSpaceInterface;
+      Vec nullSpaceLagrange;
+      Vec nullSpaceBasis;
+
+      interfaceDofMap.createVec(nullSpaceInterface);
+      VecSet(nullSpaceInterface, 1.0);
+
+      lagrangeMap.createVec(nullSpaceLagrange);
+      VecSet(nullSpaceLagrange, 0.0);
+
+      Vec vecArray[2] = {nullSpaceInterface, nullSpaceLagrange};
+      VecCreateNest(mpiCommGlobal, 2, PETSC_NULL, vecArray, &nullSpaceBasis);
+
+      
+      MatNullSpace matNullspace;
+      MatNullSpaceCreate(mpiCommGlobal, PETSC_FALSE, 1, &nullSpaceBasis, &matNullspace);
+      MatSetNullSpace(mat_feti, matNullspace);
+      KSPSetNullSpace(ksp_feti, matNullspace);
+    }
+
 
     // === Create FETI-DP preconditioner object. ===
 
@@ -913,9 +938,16 @@ namespace AMDiS {
     fetiData.subSolver = NULL;
     fetiData.ksp_schur_primal = PETSC_NULL;
 
-    VecDestroy(&fetiData.tmp_vec_b);
+    VecDestroy(&fetiData.tmp_vec_b0);
     VecDestroy(&fetiData.tmp_vec_lagrange);
-    VecDestroy(&fetiData.tmp_vec_primal);
+    VecDestroy(&fetiData.tmp_vec_primal0);
+
+    if (enableStokesMode) {
+      VecDestroy(&fetiData.tmp_vec_b1);
+      VecDestroy(&fetiData.tmp_vec_primal1);
+      VecDestroy(&fetiData.tmp_vec_interface);
+    }
+
     MatDestroy(&mat_feti);
     KSPDestroy(&ksp_feti);
 
@@ -1520,30 +1552,39 @@ namespace AMDiS {
 	  FetiTimings::fetiPreconditioner);
     }
 
+
     // === Solve for u_primals. ===
 
-    VecCopy(subdomain->getVecRhsCoarse(), tmp_primal0);
-    subdomain->solveGlobal(subdomain->getVecRhsInterior(), tmp_b0);
-    MatMult(subdomain->getMatCoarseInterior(), tmp_b0, tmp_primal1);
-    VecAXPBY(tmp_primal0, -1.0, 1.0, tmp_primal1);
-    MatMultTranspose(mat_lagrange, vecSol, tmp_b0);
-    subdomain->solveGlobal(tmp_b0, tmp_b0);
-    MatMult(subdomain->getMatCoarseInterior(), tmp_b0, tmp_primal1);
+    if (!enableStokesMode) {
+      MatMultTranspose(mat_lagrange, vecSol, tmp_b0);
+      VecAYPX(tmp_b0, -1.0, subdomain->getVecRhsInterior());  
+    } else {
+      MatMultTranspose(mat_lagrange, vecSolLagrange, tmp_b0);
+      VecAYPX(tmp_b0, -1.0, subdomain->getVecRhsInterior());  
+
+      MatMult(subdomain->getMatInteriorCoarse(1), vecSolInterface, tmp_b1);
+      VecAXPY(tmp_b0, -1.0, tmp_b1);
+    }
+  
+    subdomain->solveGlobal(tmp_b0, tmp_b1);
+    MatMult(subdomain->getMatCoarseInterior(), tmp_b1, tmp_primal0);
+    VecAYPX(tmp_primal0, -1.0, subdomain->getVecRhsCoarse());
+
+    if (enableStokesMode) {
+      MatMult(subdomain->getMatCoarse(0, 1), vecSolInterface, tmp_primal1);
+      VecAXPY(tmp_primal0, -1.0, tmp_primal1);
+    }
 
-    VecAXPBY(tmp_primal0, 1.0, 1.0, tmp_primal1);
     KSPSolve(ksp_schur_primal, tmp_primal0, tmp_primal0);
 
-    
-    // === Solve for u_b. ===
 
-    VecCopy(subdomain->getVecRhsInterior(), tmp_b0);
-    MatMultTranspose(mat_lagrange, vecSol, tmp_b1);
-    VecAXPBY(tmp_b0, -1.0, 1.0, tmp_b1);
+    // === Solve for u_b. ===
 
     MatMult(subdomain->getMatInteriorCoarse(), tmp_primal0, tmp_b1);
-    VecAXPBY(tmp_b0, -1.0, 1.0, tmp_b1);
+    VecAXPY(tmp_b0, -1.0, tmp_b1);
     subdomain->solveGlobal(tmp_b0, tmp_b0);
 
+
     // === And recover AMDiS solution vectors. ===
 
     recoverSolution(tmp_b0, tmp_primal0, vec);
diff --git a/AMDiS/src/parallel/PetscSolverFetiOperators.cc b/AMDiS/src/parallel/PetscSolverFetiOperators.cc
index 83ec0837198c472953d945576f691e36d8e745b7..1cf7a349ca4f07763ad3812bc3ac005583b9f1dc 100644
--- a/AMDiS/src/parallel/PetscSolverFetiOperators.cc
+++ b/AMDiS/src/parallel/PetscSolverFetiOperators.cc
@@ -48,30 +48,30 @@ namespace AMDiS {
     MatShellGetContext(mat, &ctx);
     FetiData* data = static_cast<FetiData*>(ctx);
 
-    MatMultTranspose(*(data->mat_lagrange), x, data->tmp_vec_b);
+    MatMultTranspose(*(data->mat_lagrange), x, data->tmp_vec_b0);
 
     double wtime01 = MPI::Wtime();
-    data->subSolver->solveGlobal(data->tmp_vec_b, data->tmp_vec_b);
+    data->subSolver->solveGlobal(data->tmp_vec_b0, data->tmp_vec_b0);
 
     FetiTimings::fetiSolve01 += (MPI::Wtime() - wtime01);
 
-    MatMult(*(data->mat_lagrange), data->tmp_vec_b, data->tmp_vec_lagrange);
+    MatMult(*(data->mat_lagrange), data->tmp_vec_b0, data->tmp_vec_lagrange);
 
     MatMult(data->subSolver->getMatCoarseInterior(), 
-	    data->tmp_vec_b, data->tmp_vec_primal);
+	    data->tmp_vec_b0, data->tmp_vec_primal0);
 
     wtime01 = MPI::Wtime();
-    KSPSolve(*(data->ksp_schur_primal), data->tmp_vec_primal, data->tmp_vec_primal);
+    KSPSolve(*(data->ksp_schur_primal), data->tmp_vec_primal0, data->tmp_vec_primal0);
     FetiTimings::fetiSolve02 += (MPI::Wtime() - wtime01);
 
     MatMult(data->subSolver->getMatInteriorCoarse(), 
-	    data->tmp_vec_primal, data->tmp_vec_b);
+	    data->tmp_vec_primal0, data->tmp_vec_b0);
 
     wtime01 = MPI::Wtime();
-    data->subSolver->solveGlobal(data->tmp_vec_b, data->tmp_vec_b);
+    data->subSolver->solveGlobal(data->tmp_vec_b0, data->tmp_vec_b0);
     FetiTimings::fetiSolve01 += (MPI::Wtime() - wtime01);
 
-    MatMult(*(data->mat_lagrange), data->tmp_vec_b, y);
+    MatMult(*(data->mat_lagrange), data->tmp_vec_b0, y);
 
     VecAXPBY(y, 1.0, 1.0, data->tmp_vec_lagrange);
 
@@ -97,32 +97,68 @@ namespace AMDiS {
     MatShellGetContext(mat, &ctx);
     FetiData* data = static_cast<FetiData*>(ctx);
 
-    MatMultTranspose(*(data->mat_lagrange), x_lagrange, data->tmp_vec_b);
 
-    double wtime01 = MPI::Wtime();
-    data->subSolver->solveGlobal(data->tmp_vec_b, data->tmp_vec_b);
+    // === Calculation of v_{B} ===
 
-    FetiTimings::fetiSolve01 += (MPI::Wtime() - wtime01);
+    // tmp_vec_b0 = J^{T} \lambda
+    MatMultTranspose(*(data->mat_lagrange), x_lagrange, data->tmp_vec_b0);
+    // tmp_vec_b1 = A_{B\Gamma} u_{\Gamma}
+    MatMult(data->subSolver->getMatInteriorCoarse(1), x_interface, data->tmp_vec_b1);
+    // tmp_vec_b0 = A_{B\Gamma} u_{\Gamma} + J^{T} \lambda
+    VecAXPY(data->tmp_vec_b0, 1.0, data->tmp_vec_b1);
+
+
+    // == Calculation of v_{\Pi}
+    
+    // tmp_vec_primal0 = A_{\Pi\Gamma} u_{\Gamma}
+    MatMult(data->subSolver->getMatCoarse(0, 1), x_interface, data->tmp_vec_primal0);
+    
+
+    // === Calculate action of FETI-DP operator ===
 
-    MatMult(*(data->mat_lagrange), data->tmp_vec_b, data->tmp_vec_lagrange);
+    double wtime01 = MPI::Wtime();
+    // tmp_vec_b0 = A_{BB}^{-1} v_{B}
+    data->subSolver->solveGlobal(data->tmp_vec_b0, data->tmp_vec_b0);
+    FetiTimings::fetiSolve01 += (MPI::Wtime() - wtime01);
 
+    // tmp_vec_primal1 = A_{\Pi B} A_{BB}^{-1} v_{B}
     MatMult(data->subSolver->getMatCoarseInterior(), 
-	    data->tmp_vec_b, data->tmp_vec_primal);
+	    data->tmp_vec_b0, data->tmp_vec_primal1);
+
+    // tmp_vec_primal0 = v_{\Pi} - A_{\Pi B} A_{BB}^{-1} v_{B}
+    VecAXPY(data->tmp_vec_primal0, -1.0, data->tmp_vec_primal1);
 
     wtime01 = MPI::Wtime();
-    KSPSolve(*(data->ksp_schur_primal), data->tmp_vec_primal, data->tmp_vec_primal);
+    // tmp_vec_primal0 = S_{\Pi\Pi}^{-1} (v_{\Pi} - A_{\Pi B} A_{BB}^{-1} v_{B})
+    KSPSolve(*(data->ksp_schur_primal), data->tmp_vec_primal0, data->tmp_vec_primal0);
     FetiTimings::fetiSolve02 += (MPI::Wtime() - wtime01);
 
+    // tmp_vec_b1 = A_{B\Pi} S_{\Pi\Pi}^{-1} (v_{\Pi} - A_{\Pi B} A_{BB}^{-1} v_{B})
     MatMult(data->subSolver->getMatInteriorCoarse(), 
-	    data->tmp_vec_primal, data->tmp_vec_b);
+	    data->tmp_vec_primal0, data->tmp_vec_b1);
 
     wtime01 = MPI::Wtime();
-    data->subSolver->solveGlobal(data->tmp_vec_b, data->tmp_vec_b);
+    // tmp_vec_b1 = A_{BB}^{-1} A_{B\Pi} S_{\Pi\Pi}^{-1} (v_{\Pi} - A_{\Pi B} A_{BB}^{-1} v_{B})
+    data->subSolver->solveGlobal(data->tmp_vec_b1, data->tmp_vec_b1);
     FetiTimings::fetiSolve01 += (MPI::Wtime() - wtime01);
 
-    MatMult(*(data->mat_lagrange), data->tmp_vec_b, y_lagrange);
+    // tmp_vec_b0 = A_{BB}^{-1} v_{B} - A_{BB}^{-1} A_{B\Pi} S_{\Pi\Pi}^{-1} (v_{\Pi} - A_{\Pi B} A_{BB}^{-1} v_{B})
+    VecAXPY(data->tmp_vec_b0, -1.0, data->tmp_vec_b1);
+
+
+    // === Calculate projection to interface and constraint variable ===
+
+    // y_interface = A_{\Gamma B} tmp_vec_b0
+    MatMult(data->subSolver->getMatCoarseInterior(1), data->tmp_vec_b0, y_interface);
+
+    // tmp_vec_primal0 = S_{\Pi\Pi}^{-1} (v_{\Pi} - A_{\Pi B} A_{BB}^{-1} v_{B})
+    // tmp_vec_interface = A_{\Gamma \Pi} tmp_vec_primal0
+    MatMult(data->subSolver->getMatCoarse(1, 0), data->tmp_vec_primal0, data->tmp_vec_interface);
+    // y_interface = A_{\Gamma B} tmp_vec_b0 + A_{\Gamma \Pi} tmp_vec_primal0
+    VecAXPY(y_interface, 1.0, data->tmp_vec_interface);
 
-    VecAXPBY(y_lagrange, 1.0, 1.0, data->tmp_vec_lagrange);
+    // y_lagrange = J tmp_vec_b0
+    MatMult(*(data->mat_lagrange), data->tmp_vec_b0, y_lagrange);
 
     FetiTimings::fetiSolve += (MPI::Wtime() - wtime);
 
diff --git a/AMDiS/src/parallel/PetscSolverFetiStructs.h b/AMDiS/src/parallel/PetscSolverFetiStructs.h
index 340f7c13a0e33d86c3fa9e16c98e9c48611ab803..3da72354227174ee24e7827f8d34311cc73bcd77 100644
--- a/AMDiS/src/parallel/PetscSolverFetiStructs.h
+++ b/AMDiS/src/parallel/PetscSolverFetiStructs.h
@@ -57,14 +57,16 @@ namespace AMDiS {
     Mat *mat_lagrange;
 
     /// Temporal vectors on the B variables.
-    Vec tmp_vec_b;
+    Vec tmp_vec_b0, tmp_vec_b1;
 
     /// Temporal vector on the primal variables.
-    Vec tmp_vec_primal;
+    Vec tmp_vec_primal0, tmp_vec_primal1;
 
     /// Temporal vector on the lagrange variables.
     Vec tmp_vec_lagrange;
 
+    Vec tmp_vec_interface;
+
     PetscSolver* subSolver;
 
     /// Pointer to the solver of the schur complement on the primal variables.
diff --git a/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc b/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc
index 75379f2b8cc4be899858186a103a2d6684eeb86b..b9da1f97ceb0086880cefb0f707931281c119243 100644
--- a/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc
+++ b/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc
@@ -161,22 +161,12 @@ namespace AMDiS {
 	    bool isColCoarse = 
 	      isCoarseSpace(colComponent, feSpaces[colComponent], col(*icursor));
 
-	    if (isColCoarse) {
-	      if (isRowCoarse) {
-		cols.push_back(col(*icursor));
-		values.push_back(value(*icursor));
-	      } else {
-		colsOther.push_back(col(*icursor));
-		valuesOther.push_back(value(*icursor));
-	      }
+	    if (isColCoarse == isRowCoarse) {
+	      cols.push_back(col(*icursor));
+	      values.push_back(value(*icursor));
 	    } else {
-	      if (isRowCoarse) {
-		colsOther.push_back(col(*icursor));
-		valuesOther.push_back(value(*icursor));
-	      } else {
-		cols.push_back(col(*icursor));
-		values.push_back(value(*icursor));
-	      }
+	      colsOther.push_back(col(*icursor));
+	      valuesOther.push_back(value(*icursor));
 	    }
 	  }  // for each nnz in row
 
@@ -341,8 +331,9 @@ namespace AMDiS {
 	MatNullSpaceCreate(mpiCommGlobal, PETSC_TRUE, 0, PETSC_NULL, &matNullspace);
       }
 
-      MatSetNullSpace(getMatInterior(), matNullspace);
-      KSPSetNullSpace(kspInterior, matNullspace);
+      MSG("NULLSPACE IS NOT REMOVED!\n");
+      // MatSetNullSpace(getMatInterior(), matNullspace);
+      // KSPSetNullSpace(kspInterior, matNullspace);
 
       // === Remove null space, if requested. ===