diff --git a/HySoP/hysop/numerics/finite_differences.py b/HySoP/hysop/numerics/finite_differences.py
index bc05d712a6ce3ab699c29d48e5ed014bb1a53007..d90cbec11caeea71c7914499000ebd77622dcf28 100644
--- a/HySoP/hysop/numerics/finite_differences.py
+++ b/HySoP/hysop/numerics/finite_differences.py
@@ -82,6 +82,16 @@ class FiniteDifference(object):
         mesh on which finite-differences will be applied.
         """
 
+    def computeIndices_reduced(self, indices, reduced_shape):
+        """
+        @param indices : a list of slices (see for example
+        parmepy.mpi.mesh.Mesh iCompute) that represent the local
+        mesh on which finite-differences will be applied.
+        """
+        self.computeIndices(indices)
+        self.indices = [slice(0, reduced_shape[d])
+                        for d in xrange(len(reduced_shape))]
+
     @abstractmethod
     def compute(self, tab, cdir, result):
         """
diff --git a/HySoP/hysop/operator/discrete/drag_and_lift.py b/HySoP/hysop/operator/discrete/drag_and_lift.py
index 2cd8b4afc892c3a64ea4da2a5ee173451f0d412e..d0e1267a02e32e8ae65a5ce9f5bdcb68929964c3 100644
--- a/HySoP/hysop/operator/discrete/drag_and_lift.py
+++ b/HySoP/hysop/operator/discrete/drag_and_lift.py
@@ -33,6 +33,11 @@ class Forces(DiscreteOperator):
         control
         """
         super(Forces, self).__init__(**kwds)
+        # topology common to all variables
+        self.input = self.variables
+        self._topology = self.input[0].topology
+        assert (self._topology.ghosts() >= 1).all()
+
         # deal with obstacles, volume of control ...
         self._indices = self._init_indices(obstacles)
 
@@ -46,10 +51,6 @@ class Forces(DiscreteOperator):
         ## The force we want to compute (lift(s) and drag)
         self.force = npw.zeros(self._dim)
 
-        # topology common to all variables
-        self._topology = self.input[0].topology
-        assert (self._topology.ghosts() >= 1).all()
-
         # list of np arrays to be synchronized
         self._datalist = []
         for v in self.input:
@@ -65,7 +66,6 @@ class Forces(DiscreteOperator):
         # true if the operator needs to work on the current process.
         # Updated in derived class.
         self._on_proc = True
-        self.input = self.variables
         # Set how reduction will be performed
         # Default = reduction over all process.
         # \todo : add param to choose this option
@@ -88,19 +88,7 @@ class Forces(DiscreteOperator):
         pass
 
     def _set_work_arrays(self, rwork=None, iwork=None):
-
-        v_ind = self.input[0].topology.mesh.iCompute
-        shape_v = self.input[0].data[0][v_ind].shape
-        # setup for rwork, iwork is useless.
-        if rwork is None:
-            # ---  Local allocation ---
-            self._rwork = [npw.zeros(shape_v)]
-        else:
-            assert isinstance(rwork, list), 'rwork must be a list.'
-            # --- External rwork ---
-            self._rwork = rwork
-            assert len(self._rwork) == 1
-            assert self._rwork[0].shape == shape_v
+        pass
 
     def _mpi_allsum(self):
         """
@@ -270,19 +258,21 @@ class NocaForces(Forces):
                                                  self._topology)
 
     def _set_work_arrays(self, rwork=None, iwork=None):
-
-        v_ind = self.velocity.topology.mesh.iCompute
-        shape_v = self.velocity.data[0][v_ind].shape
+        shape_v = [None, ] * self._dim
+        for i in xrange(self._dim):
+            v_ind = self._voc.surf[2 * i].mesh[self._topology].ind4integ
+            shape_v[i] = self.velocity.data[i][v_ind].shape
         # setup for rwork, iwork is useless.
         if rwork is None:
             # ---  Local allocation ---
-            self._rwork = [npw.zeros(shape_v)]
+            self._rwork = [npw.zeros(shape_v[d]) for d in xrange(self._dim)]
         else:
             assert isinstance(rwork, list), 'rwork must be a list.'
             # --- External rwork ---
             self._rwork = rwork
-            assert len(self._rwork) == 1
-            assert self._rwork[0].shape == shape_v
+            assert len(self._rwork) == self._dim
+            for i in xrange(self._dim):
+                assert self._rwork[i].shape == shape_v[i]
 
     def _noca(self, dt):
         """
@@ -354,21 +344,21 @@ class NocaForces(Forces):
         # Last part
         # Update fd schemes in order to compute laplacian and other derivatives
         # only on the surface (i.e. for list of indices in sl)
-        self._laplacian.fd_scheme.computeIndices(sl)
+        self._laplacian.fd_scheme.computeIndices_reduced(sl, buff.shape)
         for j in i_t:
-            self._rwork[...] = self._laplacian(vd[j], self._rwork)
+            buff[...] = self._laplacian(vd[j], buff)
             res[i_n] += self._coeff * self.nu * normal\
-                * npw.real_sum(coords[j] * self._rwork[sl])
-            res[j] -= self._coeff * self.nu * normal * coords[i_n] * \
-                npw.real_sum(self._rwork[sl])
-        self._fd_scheme.computeIndices(sl)
-        self._fd_scheme.compute(vd[i_n], i_n, self._rwork)
-        res[i_n] += 2.0 * normal * self.nu * npw.real_sum(self._rwork[sl])
+                * npw.real_sum(coords[j] * buff)
+            res[j] -= self._coeff * self.nu * normal * x0 * \
+                npw.real_sum(buff)
+        self._fd_scheme.computeIndices_reduced(sl, buff.shape)
+        self._fd_scheme.compute(vd[i_n], i_n, buff)
+        res[i_n] += 2.0 * normal * self.nu * npw.real_sum(buff)
         for j in i_t:
-            self._fd_scheme.compute(vd[i_n], j, self._rwork)
-            res[j] += normal * self.nu * npw.real_sum(self._rwork[sl])
-            self._fd_scheme.compute(vd[j], i_n, self._rwork)
-            res[j] += normal * self.nu * npw.real_sum(self._rwork[sl])
+            self._fd_scheme.compute(vd[i_n], j, buff)
+            res[j] += normal * self.nu * npw.real_sum(buff)
+            self._fd_scheme.compute(vd[j], i_n, buff)
+            res[j] += normal * self.nu * npw.real_sum(buff)
 
         res *= dsurf
         return res
diff --git a/HySoP/hysop/operator/drag_and_lift.py b/HySoP/hysop/operator/drag_and_lift.py
index 99ab378dca46f3859b8802f3f9655b1cbe6ff62a..2f97c4b9b8c2d6c1e93ed9aa54bb8c6cf454f835 100644
--- a/HySoP/hysop/operator/drag_and_lift.py
+++ b/HySoP/hysop/operator/drag_and_lift.py
@@ -37,7 +37,7 @@ class Forces(Computational):
         vd = self.discreteFields[self.input[0]]
         v_ind = vd.topology.mesh.iCompute
         shape_v = vd[0][v_ind].shape
-        return {'rwork': [shape_v], 'iwork': None}
+        return {'rwork': None, 'iwork': None}
 
     def discretize(self):
         super(Forces, self)._standard_discretize(self._min_ghosts)
@@ -159,10 +159,15 @@ class NocaForces(Forces):
             msg = 'The operator must be discretized '
             msg += 'before any call to this function.'
             raise RuntimeError(msg)
-        vd = self.discreteFields[self.input[0]]
-        v_ind = vd.topology.mesh.iCompute
-        shape_v = vd[0][v_ind].shape
-        return {'rwork': [shape_v], 'iwork': None}
+
+        shape_v = [None, ] * self.domain.dimension
+        slist = self._voc.surf
+        toporef = self.discreteFields[self.velocity].topology
+        for i in xrange(self.domain.dimension):
+            v_ind = slist[2 * i].mesh[toporef].ind4integ
+            shape_v[i] = self.velocity.data[i][v_ind].shape
+        # setup for rwork, iwork is useless.
+        return {'rwork': shape_v, 'iwork': None}
 
     @opsetup
     def setup(self, rwork=None, iwork=None):
diff --git a/HySoP/hysop/operator/tests/test_drag_and_lift.py b/HySoP/hysop/operator/tests/test_drag_and_lift.py
index 150c1019934fd5c90d9292d0517e1be2a4da35ea..c7645fa2e7570767d56f55f3b7709f7132726acd 100644
--- a/HySoP/hysop/operator/tests/test_drag_and_lift.py
+++ b/HySoP/hysop/operator/tests/test_drag_and_lift.py
@@ -75,6 +75,7 @@ def init_vort(discr, fileref):
     vdref = veloref.discretize(topo)
     return topo, wdref, vdref
 
+
 def check_drag(penal, wref, vref, vorti, velo):
     penal.discretize()
     penal.setup()
@@ -109,7 +110,8 @@ def test_momentum_forces_3D():
 
     penal.discretize()
     penal.setup()
-    dg = MomentumForces(velocity=velo, discretization=topo, subsets=[hsphere])
+    dg = MomentumForces(velocity=velo, discretization=topo,
+                        obstacles=[hsphere])
     dg.discretize()
     dg.setup()
     simu = Simulation(nbIter=3)