diff --git a/hysop/backend/host/python/operator/penalization.py b/hysop/backend/host/python/operator/penalization.py
index fddd21532dec3e3dd81a05ad11092098efe7e6ac..747f2118473e2544bfb4b0bbdb21868fe9c71fa6 100644
--- a/hysop/backend/host/python/operator/penalization.py
+++ b/hysop/backend/host/python/operator/penalization.py
@@ -13,38 +13,11 @@ from hysop.numerics.stencil.stencil_generator import StencilGenerator, CenteredS
 import numpy as np
 
 
-class PythonPenalizeVorticity(HostOperator):
-    """
-
-    """
-    __default_method = {
-        SpaceDiscretization: SpaceDiscretization.FDC4
-    }
-
-    __available_methods = {
-        SpaceDiscretization: (InstanceOf(SpaceDiscretization), InstanceOf(int))
-    }
-
-    @classmethod
-    def default_method(cls):
-        dm = super(PythonPenalizeVorticity, cls).default_method()
-        dm.update(cls.__default_method)
-        return dm
-
-    @classmethod
-    def available_methods(cls):
-        am = super(PythonPenalizeVorticity, cls).available_methods()
-        am.update(cls.__available_methods)
-        return am
-
+class CommonPenalization(object):
     @debug
-    def __init__(self, obstacles, variables,
-                 velocity, vorticity,
+    def __init__(self, obstacles,
                  dt, coeff=None, ubar=None, formulation=None, **kwds):
-        check_instance(velocity, Field)
-        check_instance(vorticity, Field)
-        check_instance(variables, dict, keys=Field,
-                       values=CartesianTopologyDescriptors)
+        super(CommonPenalization, self).__init__()
         check_instance(dt, ScalarParameter)
         check_instance(coeff, (ScalarParameter, float, type(lambda x: x)), allow_none=True)
         check_instance(ubar, TensorParameter, allow_none=True)
@@ -52,11 +25,6 @@ class PythonPenalizeVorticity(HostOperator):
         check_instance(obstacles, (tuple, dict), values=Field,
                        keys=(ScalarParameter, float, type(lambda x: x)), check_kwds=False)
 
-        input_fields = {velocity: variables[velocity],
-                        vorticity: variables[vorticity]}
-        output_fields = {vorticity: variables[vorticity]}
-        input_params = {dt.name: dt}
-
         if isinstance(coeff, ScalarParameter):
             self.coeff = lambda o: coeff()*o
         elif isinstance(coeff, type(lambda x: x)):
@@ -81,7 +49,6 @@ class PythonPenalizeVorticity(HostOperator):
                 obs[self.coeff] = o
         for o in obs.values():
             assert o.nb_components == 1
-            input_fields[o] = variables[o]
         self._ubar = ubar
         if ubar is None:
             self._ubar = TensorParameter(
@@ -93,13 +60,69 @@ class PythonPenalizeVorticity(HostOperator):
         else:
             self._compute_penalization = self._compute_penalization_exact
 
+        self.obstacles = obs
+
+    def _compute_penalization_implicit(self):
+        dt = self.dt()
+        self.tmp[...] = 0.
+        for c, o in self.dobstacles.iteritems():
+            self.tmp[...] += (-dt) * c(o) / (1.0 + dt * c(o))
+
+    def _compute_penalization_exact(self):
+        dt = self.dt()
+        self.tmp[...] = 1.
+        for c, o in self.dobstacles.iteritems():
+            self.tmp[...] *= np.exp(-dt*c(o))
+        self.tmp[...] -= 1.
+
+
+class PythonPenalizeVorticity(HostOperator, CommonPenalization):
+    """
+
+    """
+    __default_method = {
+        SpaceDiscretization: SpaceDiscretization.FDC4
+    }
+
+    __available_methods = {
+        SpaceDiscretization: (InstanceOf(SpaceDiscretization), InstanceOf(int))
+    }
+
+    @classmethod
+    def default_method(cls):
+        dm = super(PythonPenalizeVorticity, cls).default_method()
+        dm.update(cls.__default_method)
+        return dm
+
+    @classmethod
+    def available_methods(cls):
+        am = super(PythonPenalizeVorticity, cls).available_methods()
+        am.update(cls.__available_methods)
+        return am
+
+    @debug
+    def __init__(self, obstacles, variables,
+                 velocity, vorticity,
+                 dt, coeff=None, ubar=None, formulation=None, **kwds):
+        check_instance(velocity, Field)
+        check_instance(vorticity, Field)
+        check_instance(variables, dict, keys=Field,
+                       values=CartesianTopologyDescriptors)
+
+        input_fields = {velocity: variables[velocity],
+                        vorticity: variables[vorticity]}
+        output_fields = {vorticity: variables[vorticity]}
+        input_params = {dt.name: dt}
+        for o in (obstacles.values() if isinstance(obstacles, dict) else obstacles):
+            input_fields[o] = variables[o]
+
         self.velocity = velocity
         self.vorticity = vorticity
-        self.obstacles = obs
         self.dt = dt
         super(PythonPenalizeVorticity, self).__init__(
             input_fields=input_fields, output_fields=output_fields,
-            input_params=input_params, **kwds)
+            input_params=input_params,
+            obstacles=obstacles, dt=dt, coeff=coeff, ubar=ubar, formulation=formulation, **kwds)
 
     @debug
     def handle_method(self, method):
@@ -185,19 +208,6 @@ class PythonPenalizeVorticity(HostOperator):
     def supports_mpi(cls):
         return True
 
-    def _compute_penalization_implicit(self):
-        dt = self.dt()
-        self.tmp[...] = 0.
-        for c, o in self.dobstacles.iteritems():
-            self.tmp[...] += (-dt) * c(o) / (1.0 + dt * c(o))
-
-    def _compute_penalization_exact(self):
-        dt = self.dt()
-        self.tmp[...] = 1.
-        for c, o in self.dobstacles.iteritems():
-            self.tmp[...] *= np.exp(-dt*c(o))
-        self.tmp[...] -= 1.
-
     @op_apply
     def apply(self, **kwds):
         super(PythonPenalizeVorticity, self).apply(**kwds)
@@ -205,7 +215,7 @@ class PythonPenalizeVorticity(HostOperator):
 
         # Penalize velocity
         self._compute_penalization()
-        for ubar, v, tmp in zip(self._ubar(), self.V, self.tmp_v):
+        for ubar, v, tmp in zip(self._ubar()[::-1], self.V, self.tmp_v):
             tmp[...] = (v - ubar) * self.tmp
 
         self._compute_vorticity()
@@ -246,7 +256,7 @@ class PythonPenalizeVorticity(HostOperator):
         self.W[0][...] += -self.tmp
 
 
-class PythonPenalizeVelocity(HostOperator):
+class PythonPenalizeVelocity(HostOperator, CommonPenalization):
     """
 
     """
@@ -277,108 +287,32 @@ class PythonPenalizeVelocity(HostOperator):
         check_instance(velocity, Field)
         check_instance(variables, dict, keys=Field,
                        values=CartesianTopologyDescriptors)
-        check_instance(dt, ScalarParameter)
-        check_instance(coeff, (ScalarParameter, float, type(lambda x: x)), allow_none=True)
-        check_instance(ubar, TensorParameter, allow_none=True)
-        check_instance(formulation, PenalizationFormulation, allow_none=True)
-        check_instance(obstacles, (tuple, dict), values=Field,
-                       keys=(ScalarParameter, float, type(lambda x: x)), check_kwds=False)
 
         input_fields = {velocity: variables[velocity], }
         output_fields = {velocity: variables[velocity]}
         input_params = {dt.name: dt}
-
-        if isinstance(coeff, ScalarParameter):
-            self.coeff = lambda o: coeff()*o
-        elif isinstance(coeff, type(lambda x: x)):
-            self.coeff = coeff
-        elif not coeff is None:
-            c = ScalarParameter("penal_coeff", initial_value=coeff)
-            self.coeff = lambda o: c()*o
-
-        if isinstance(obstacles, dict):
-            obs = {}
-            for c, o in obstacles.iteritems():
-                if isinstance(c, ScalarParameter):
-                    obs[lambda x: c()*x] = o
-                elif isinstance(c, type(lambda x: x)):
-                    obs[c] = o
-                elif not c is None:
-                    _ = ScalarParameter("penal_coeff", initial_value=c)
-                    obs[lambda x: _()*x] = o
-        else:
-            obs = {}
-            for o in obstacles:
-                obs[self.coeff] = o
-        for o in obs.values():
-            assert o.nb_components == 1
+        for o in (obstacles.values() if isinstance(obstacles, dict) else obstacles):
             input_fields[o] = variables[o]
-        self._ubar = ubar
-        if ubar is None:
-            self._ubar = TensorParameter(
-                name="ubar", shape=(velocity.dim,),
-                quiet=True, dtype=velocity.dtype,
-                initial_value=(0.,)*velocity.dim)
-        if formulation is None or formulation is PenalizationFormulation.IMPLICIT:
-            self._compute_penalization = self._compute_penalization_implicit
-        else:
-            self._compute_penalization = self._compute_penalization_exact
 
         self.velocity = velocity
-        self.obstacles = obs
         self.dt = dt
         super(PythonPenalizeVelocity, self).__init__(
             input_fields=input_fields, output_fields=output_fields,
-            input_params=input_params, **kwds)
-
-    @debug
-    def handle_method(self, method):
-        super(PythonPenalizeVelocity, self).handle_method(method)
-        self.space_discretization = method.pop(SpaceDiscretization)
-        csg = CenteredStencilGenerator()
-        csg.configure(dtype=MPQ, dim=1)
-        try:
-            self.order = int(str(self.space_discretization)[3:])
-        except:
-            self.order = self.space_discretization
-        self.stencil = tuple(csg.generate_exact_stencil(
-            derivative=1,
-            order=self.order) for _ in range(3))
-
-    @debug
-    def get_field_requirements(self):
-        requirements = super(PythonPenalizeVelocity,
-                             self).get_field_requirements()
-        stencil = self.stencil[0]
-        G = max(max(a, b) for a, b in zip(stencil.L, stencil.R))
-        for is_input, (field, td, req) in requirements.iter_requirements():
-            min_ghosts = (max(g, G) for g in req.min_ghosts.copy())
-            req.min_ghosts = min_ghosts
-            req.axes = (tuple(range(field.dim)), )
-        return requirements
+            input_params=input_params,
+            obstacles=obstacles, dt=dt, coeff=coeff, ubar=ubar, formulation=formulation, **kwds)
 
     @debug
     def discretize(self):
         if self.discretized:
             return
         super(PythonPenalizeVelocity, self).discretize()
-        dim = self.velocity.dim
         self.dvelocity = self.input_discrete_tensor_fields[self.velocity]
 
         dv = self.dvelocity
-        stencil = self.stencil[0]
-        G = max(max(a, b) for a, b in zip(stencil.L, stencil.R))
-        view = dv.local_slices(ghosts=(G, )*dim)
-        V = tuple(Vi[view] for Vi in dv.buffers)
-        self.V = V
         self.dobstacles = {}
         for c, o in self.obstacles.iteritems():
             o_df = self.input_discrete_fields[o]
-            self.dobstacles[c] = o_df.data[0][o_df.local_slices(
-                ghosts=(G, )*dim)]
-
-        for s, dx in zip(self.stencil, dv.space_step):
-            s.replace_symbols({s.dx: dx})
+            self.dobstacles[c] = o_df.data[0]
 
         self.v_ghost_exchanger = dv.build_ghost_exchanger()
 
@@ -386,14 +320,13 @@ class PythonPenalizeVelocity(HostOperator):
     def get_work_properties(self):
         requests = super(PythonPenalizeVelocity, self).get_work_properties()
         buffers = MemoryRequest.empty_like(
-            a=self.V[0], nb_components=4, backend=self.dvelocity.backend)
+            a=self.dvelocity.buffers[0], nb_components=1, backend=self.dvelocity.backend)
         requests.push_mem_request('Wtmp', buffers)
         return requests
 
     def setup(self, work):
         super(PythonPenalizeVelocity, self).setup(work=work)
         Wtmp = work.get_buffer(self, 'Wtmp', handle=True)
-        self.tmp_v = Wtmp[0:3]
         self.tmp = Wtmp[-1]
 
     @classmethod
@@ -404,19 +337,6 @@ class PythonPenalizeVelocity(HostOperator):
     def supports_mpi(cls):
         return True
 
-    def _compute_penalization_implicit(self):
-        dt = self.dt()
-        self.tmp[...] = 0.
-        for c, o in self.dobstacles.iteritems():
-            self.tmp[...] += (-dt) * c(o) / (1.0 + dt * c(o))
-
-    def _compute_penalization_exact(self):
-        dt = self.dt()
-        self.tmp[...] = 1.
-        for c, o in self.dobstacles.iteritems():
-            self.tmp[...] *= np.exp(-dt*c(o))
-        self.tmp[...] -= 1.
-
     @op_apply
     def apply(self, **kwds):
         super(PythonPenalizeVelocity, self).apply(**kwds)
@@ -424,6 +344,6 @@ class PythonPenalizeVelocity(HostOperator):
 
         # Penalize velocity
         self._compute_penalization()
-        for ubar, v, tmp in zip(self._ubar(), self.V, self.tmp_v):
-            tmp[...] = (v - ubar) * self.tmp
+        for ubar, v in zip(self._ubar()[::-1], self.dvelocity.buffers):
+            v[...] = (v - ubar) * self.tmp
         self.v_ghost_exchanger()
diff --git a/hysop/problem.py b/hysop/problem.py
index 877ede4d7ec4f6e28dfa25a4efcd6acd99b7ce43..6e16c55258b27f5b2c48ad63e95364b1a92235fc 100644
--- a/hysop/problem.py
+++ b/hysop/problem.py
@@ -148,7 +148,8 @@ class Problem(ComputationalGraph):
                 if all((df in initialized) for df in dfield.discrete_fields()):
                     # all contained scalar fields were already initialized
                     continue
-                elif mpi_params and mpi_params.task_id != dfield.topology.task_id:
+                elif mpi_params and not all([mpi_params.task_id == df.topology.task_id
+                                             for df in dfield.discrete_fields()]):
                     # Topology task does not matches given mpi_params task
                     continue
                 else: