diff --git a/HySoP/hysop/fields/scalar.py b/HySoP/hysop/fields/scalar.py
index 02f69b4f3d6aa4e79e8c69858e0c94f94169a099..0140004776d7451ea3714e6519ca0d06fbc0a051 100644
--- a/HySoP/hysop/fields/scalar.py
+++ b/HySoP/hysop/fields/scalar.py
@@ -82,7 +82,7 @@ class ScalarField(DiscreteField):
 
             else:
                 self.data[...] = np.asarray(
-                    formula(*(self.topology.mesh.coords + args)),
+                    v_formula(self.topology.mesh.coords, *args),
                     dtype=PARMES_REAL,
                     order=ORDER)
         else:
diff --git a/HySoP/hysop/gpu/gpu_particle_advection.py b/HySoP/hysop/gpu/gpu_particle_advection.py
index 53d06030f3a71870c2265a1598704721c70a3001..8d23b5798dfe5c0f0471d677816c768bfc5e07b6 100644
--- a/HySoP/hysop/gpu/gpu_particle_advection.py
+++ b/HySoP/hysop/gpu/gpu_particle_advection.py
@@ -10,8 +10,8 @@ from parmepy.operator.discrete.particle_advection import ParticleAdvection
 from parmepy.gpu import PARMES_REAL_GPU, cl
 from parmepy.gpu.tools import get_opencl_environment
 from parmepy.gpu.gpu_kernel import KernelLauncher
-from parmepy.gpu.gpu_kernel import KernelListLauncher
-from parmepy.numerics.splitting import Splitting
+#from parmepy.gpu.gpu_kernel import KernelListLauncher
+#from parmepy.numerics.splitting import Splitting
 
 
 class GPUParticleAdvection(ParticleAdvection):
diff --git a/HySoP/hysop/mpi/mesh.py b/HySoP/hysop/mpi/mesh.py
index 99b8fdc1c9dcdb69db20557a3915577c9e29913a..9137455380ba3f9e26cfe2a150cc71c9850c252a 100644
--- a/HySoP/hysop/mpi/mesh.py
+++ b/HySoP/hysop/mpi/mesh.py
@@ -56,7 +56,8 @@ class SubMesh(object):
 
         self.end = self.origin + self.space_step * (self.resolution - 1)
         if self.dim == 1:
-            self.coords = np.linspace(self.origin, self.end, self.resolution)
+            cx = np.linspace(self.origin, self.end, self.resolution)
+            self.coords = tuple([cx,])
         elif self.dim == 2:
             cx = np.linspace(self.origin[0], self.end[0],
                              self.resolution[0])[:, np.newaxis]
diff --git a/HySoP/hysop/numerics/integrators/runge_kutta2.py b/HySoP/hysop/numerics/integrators/runge_kutta2.py
index 24e6bec3592d9cff118a4f554ada5654b4794bae..80471ce9f434d2efbedea22836f35469e45139be 100755
--- a/HySoP/hysop/numerics/integrators/runge_kutta2.py
+++ b/HySoP/hysop/numerics/integrators/runge_kutta2.py
@@ -74,7 +74,8 @@ class RK2_scalar(ODESolver):
         ODESolver.__init__(self, f)
         self.name = 'RK2'
 
-    def __call__(self, f, t, dt, y, res=None, work=None, **f_kwargs):
+    def __call__(self, f, t, dt, y, res=None, work=None, yprime=None,
+                 **f_kwargs):
 
         """
         Integration step for RK2 Method.
@@ -86,13 +87,17 @@ class RK2_scalar(ODESolver):
         @param y : function Y(t,space).
         @param res : result (may be allocated when not None).
         @param work : allocated working array.
+        @param yprime : y'(t) already computed (avoid 1st call to f)
         @param f_kwargs : Parameters for right-hand side computing.
         """
         if res is None:
             res = np.empty_like(y)
         if work is None:
             work = np.empty_like(y)
-        work[...] = f(t, y, res=work, **f_kwargs)
+        if yprime is None:
+            work[...] = f(t, y, res=work, **f_kwargs)
+        else:
+            work[...] = yprime
         work[...] *= 0.5 * dt
         res[...] = y
         res[...] += dt * f(t + 0.5 * dt, y + work, **f_kwargs)
diff --git a/HySoP/hysop/numerics/interpolation.py b/HySoP/hysop/numerics/interpolation.py
index 3561ac2ae0ef18472345c384648e0a1673391f8f..246e72f54336b586e0a3c9ae3c09fc169ab6d386 100644
--- a/HySoP/hysop/numerics/interpolation.py
+++ b/HySoP/hysop/numerics/interpolation.py
@@ -39,9 +39,10 @@ class Linear(NumMethod):
                 i_row, i_col = np.indices(x.shape)
             if self.d == 0:
                 floor = res
-                floor[...] = np.floor(
-                    (x - self.origin[self.d]) / self.dx[self.d])
-                i_y[...] = (x - self.origin[self.d]) / self.dx[self.d] - floor
+                floor[...] = (x - self.origin[self.d]) / self.dx[self.d]
+                i_y[...] = floor
+                floor[...] = np.floor(floor)
+                i_y[...] -= floor
                 i_row[...] = floor.astype(np.int32) % x.shape[self.d]
                 i_col[...] = np.indices((x.shape[1],))[0][np.newaxis, :]
                 res[...] = self.field.data[self.d][i_row, i_col] * (1. - i_y)
@@ -49,9 +50,10 @@ class Linear(NumMethod):
                 res[...] += self.field.data[self.d][i_row, i_col] * i_y
             else:
                 floor = res
-                floor[...] = np.floor(
-                    (x - self.origin[self.d]) / self.dx[self.d])
-                i_y[...] = (x - self.origin[self.d]) / self.dx[self.d] - floor
+                floor[...] = (x - self.origin[self.d]) / self.dx[self.d]
+                i_y[...] = floor
+                floor[...] = np.floor(floor)
+                i_y[...] -= floor
                 i_col[...] = floor.astype(np.int32) % x.shape[self.d]
                 i_row[...] = np.indices((x.shape[0],))[0][:, np.newaxis]
                 res[...] = self.field.data[self.d][i_row, i_col] * (1. - i_y)
@@ -63,9 +65,10 @@ class Linear(NumMethod):
                 i_row, i_col, i_dep = np.indices(x.shape)
             if self.d == 0:
                 floor = res
-                floor[...] = np.floor(
-                    (x - self.origin[self.d]) / self.dx[self.d])
-                i_y[...] = (x - self.origin[self.d]) / self.dx[self.d] - floor
+                floor[...] = (x - self.origin[self.d]) / self.dx[self.d]
+                i_y[...] = floor
+                floor[...] = np.floor(floor)
+                i_y[...] -= floor
                 i_row[...] = floor.astype(np.int32) % x.shape[self.d]
                 i_col[...] = \
                     np.indices((x.shape[1],))[0][np.newaxis, :, np.newaxis]
@@ -78,9 +81,10 @@ class Linear(NumMethod):
                     self.field.data[self.d][i_row, i_col, i_dep] * i_y
             elif self.d == 1:
                 floor = res
-                floor[...] = np.floor(
-                    (x - self.origin[self.d]) / self.dx[self.d])
-                i_y[...] = (x - self.origin[self.d]) / self.dx[self.d] - floor
+                floor[...] = (x - self.origin[self.d]) / self.dx[self.d]
+                i_y[...] = floor
+                floor[...] = np.floor(floor)
+                i_y[...] -= floor
                 i_col[...] = floor.astype(np.int32) % x.shape[self.d]
                 i_row[...] = \
                     np.indices((x.shape[0],))[0][:, np.newaxis, np.newaxis]
@@ -93,9 +97,10 @@ class Linear(NumMethod):
                     self.field.data[self.d][i_row, i_col, i_dep] * i_y
             else:
                 floor = res
-                floor[...] = np.floor(
-                    (x - self.origin[self.d]) / self.dx[self.d])
-                i_y[...] = (x - self.origin[self.d]) / self.dx[self.d] - floor
+                floor[...] = (x - self.origin[self.d]) / self.dx[self.d]
+                i_y[...] = floor
+                floor[...] = np.floor(floor)
+                i_y[...] -= floor
                 i_dep[...] = floor.astype(np.int32) % x.shape[self.d]
                 i_row[...] = \
                     np.indices((x.shape[0],))[0][:, np.newaxis, np.newaxis]
@@ -107,4 +112,17 @@ class Linear(NumMethod):
                 res[...] += \
                     self.field.data[self.d][i_row, i_col, i_dep] * i_y
 
+        else:
+            if i_row is None:
+                i_row = np.indices(x.shape)
+            floor = res
+            floor[...] = (x - self.origin[self.d]) / self.dx[self.d]
+            i_y[...] = floor
+            floor[...] = np.floor(floor)
+            i_y[...] -= floor
+            i_row[...] = floor.astype(np.int32) % x.shape[self.d]
+            res[...] = self.field.data[i_row] * (1. - i_y)
+            i_row[...] = (i_row + 1) % x.shape[self.d]
+            res[...] += self.field.data[i_row] * i_y
+
         return res
diff --git a/HySoP/hysop/numerics/remeshing/l6star.py b/HySoP/hysop/numerics/remeshing/l6star.py
deleted file mode 100644
index 6f179ea4edb2f3b9adbedba721ca82ffafd52c9c..0000000000000000000000000000000000000000
--- a/HySoP/hysop/numerics/remeshing/l6star.py
+++ /dev/null
@@ -1,187 +0,0 @@
-"""
-@file l6star.py
-"""
-from parmepy.constants import np, PARMES_REAL, ORDER
-from parmepy.numerics.remeshing.remeshing import Remeshing
-
-
-class L6Star(Remeshing):
-    """Remshing with Lambda6star function"""
-
-    def __init__(self, dim, dx, origin):
-        Remeshing.__init__(self, dim)
-        self.name = 'Lambda6star'
-        self.dx = dx
-        self.origin = origin
-        self._alpha = lambda y, s: s * (((-12. + (4. + (15. + (140. + (-370.
-            + (312. - 89. * y) * y) * y) * y) * y) * y) * y) / 720.)
-        self._beta = lambda y, s: s * (((108. + (-54. + (-120. + (-955. +
-            (2581. + (-2183. + 623. * y) * y) * y) * y) * y) * y ) * y) / 720.)
-        self._gamma = lambda y, s: s * (((-180. + (180. + (65. + (950. +
-            (-2574. + (2182. - 623. * y) * y) * y) * y) * y) * y) * y) / 240.)
-        self._delta = lambda y, s: s * ( 1. + ((-196. + (-959. + (2569. +
-            (-2181. + 623. * y) * y) * y) * y * y ) * y * y) / 144.)
-        self._eta = lambda y, s: s * (((108. + (108. + (-39. + (976. + (-2566.
-            + (2180. - 623. * y) * y) * y) * y) * y) * y) * y) / 144.)
-        self._zeta = lambda y, s: s * (((-36. + (-18. + (40. + (-995. + (2565.
-            + (-2179. + 623. * y) * y) * y) * y) * y) * y) * y) / 240.)
-        self._theta = lambda y, s: s * (((12. + (4. + (-15. + (1010. + (-2566.
-            + (2178. - 623. * y) * y) * y) * y) * y) * y) * y) / 720.)
-        self._iota = lambda y, s: s * (((-145. + (367. + (-311. + 89. * y)
-            * y) * y) * y * y * y * y) / 720.)
-
-    def __call__(self, ppos, pscal, d):
-
-        """
-        Remesh particles at position ppos with scalar
-        pscal along direction d.
-
-        @param ppos : particle position
-        @param pscal : particle scalar
-        @param d : splitting direction
-        """
-        if len(ppos.shape) == 2:
-            size = ppos.shape
-            index = np.indices(size)
-            floor = np.floor(ppos / self.dx[d])
-            y = np.array(ppos / self.dx[d] - floor,
-                         dtype=PARMES_REAL, order=ORDER)
-            result = np.zeros(size, dtype=PARMES_REAL, order=ORDER)
-            ind = floor.astype(np.int32) % size[d]
-
-            # alpha
-            index[d] = (ind - 3) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl]] = \
-                    result[index[0][sl], index[1][sl]] +\
-                    self._alpha(y, pscal)[sl]
-
-            # beta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl]] = \
-                    result[index[0][sl], index[1][sl]] +\
-                    self._beta(y, pscal)[sl]
-
-            # gamma
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl]] = \
-                    result[index[0][sl], index[1][sl]] +\
-                    self._gamma(y, pscal)[sl]
-
-            # delta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl]] = \
-                    result[index[0][sl], index[1][sl]] +\
-                    self._delta(y, pscal)[sl]
-
-            # eta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl]] = \
-                    result[index[0][sl], index[1][sl]] +\
-                    self._eta(y, pscal)[sl]
-
-            # zeta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl]] = \
-                    result[index[0][sl], index[1][sl]] +\
-                    self._zeta(y, pscal)[sl]
-
-            # theta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl]] = \
-                    result[index[0][sl], index[1][sl]] +\
-                    self._theta(y, pscal)[sl]
-
-            # iota
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl]] = \
-                    result[index[0][sl], index[1][sl]] +\
-                    self._iota(y, pscal)[sl]
-        else:
-            size = ppos.shape
-            index = np.indices(size)
-            floor = np.floor(ppos / self.dx[d])
-            y = np.array(ppos / self.dx[d] - floor,
-                         dtype=PARMES_REAL, order=ORDER)
-            result = np.zeros(size, dtype=PARMES_REAL, order=ORDER)
-            ind = floor.astype(np.int32) % size[d]
-
-            # alpha
-            index[d] = (ind - 3) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl], index[2][sl]] = \
-                    result[index[0][sl], index[1][sl], index[2][sl]] + \
-                    self._alpha(y, pscal)[sl]
-
-            # beta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl], index[2][sl]] = \
-                    result[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._beta(y, pscal)[sl]
-
-            # gamma
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl], index[2][sl]] = \
-                    result[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._gamma(y, pscal)[sl]
-
-            # delta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl], index[2][sl]] = \
-                    result[index[0][sl], index[1][sl], index[2][sl]] + \
-                    self._delta(y, pscal)[sl]
-
-            # eta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl], index[2][sl]] = \
-                    result[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._eta(y, pscal)[sl]
-
-            # zeta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl], index[2][sl]] = \
-                    result[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._zeta(y, pscal)[sl]
-
-            # theta
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl], index[2][sl]] = \
-                    result[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._theta(y, pscal)[sl]
-
-            # iota
-            index[d] = (index[d] + 1) % size[d]
-            for i in xrange(size[d]):
-                sl = self.slice_i_along_d(i, d)
-                result[index[0][sl], index[1][sl], index[2][sl]] = \
-                    result[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._iota(y, pscal)[sl]
-        return result
diff --git a/HySoP/hysop/numerics/remeshing/m4prime.py b/HySoP/hysop/numerics/remeshing/m4prime.py
deleted file mode 100644
index 949edca08f1d5ffec6092090c975d9492c498f54..0000000000000000000000000000000000000000
--- a/HySoP/hysop/numerics/remeshing/m4prime.py
+++ /dev/null
@@ -1,171 +0,0 @@
-"""
-@file m4prime.py
-"""
-from parmepy.constants import np, PARMES_REAL, ORDER
-from parmepy.numerics.remeshing.remeshing import Remeshing
-
-
-class M4Prime(Remeshing):
-    """Remshing with M4prime function"""
-
-    def __init__(self, dim, dx, origin):
-        Remeshing.__init__(self, dim)
-        self.name = 'M4Prime'
-        self.dx = dx
-        self.origin = origin
-        self._alpha = lambda y, s: s * ((y * (y * (-y + 2.) - 1.)) / 2.)
-        self._beta = lambda y, s: s * ((y * y * (3. * y - 5.) + 2.) / 2.)
-        self._gamma = lambda y, s: s * ((y * (y * (-3. * y + 4.) + 1.)) / 2.)
-        self._delta = lambda y, s: s * ((y * y * (y - 1.)) / 2.)
-
-    def __call__(self, ppos, origin, pscal, d, res=None,
-                 i_row=None, i_col=None, i_dep=None, i_y=None):
-
-        """
-        Remesh particles at position ppos with scalar
-        pscal along direction d.
-
-        @param ppos : particle position
-        @param pscal : particle scalar
-        @param d : splitting direction
-        @param i_row : allocated working array (rows indices array).
-        @param i_col : allocated working array (columns indices array).
-        @param i_dep : allocated working array (depth indices array).
-        @param i_y : allocated working array (distance to left grid point).
-        """
-        shape = ppos.shape
-        if len(ppos.shape) == 2:
-            index = [i_row, i_col]
-            if d == 0:
-                index[1][...] = np.indices((shape[1],))[0][np.newaxis, :]
-            else:
-                index[0][...] = np.indices((shape[0],))[0][:, np.newaxis]
-            floor = res
-            floor[...] = np.floor((ppos - origin) / self.dx[d])
-            i_y[...] = ((ppos - origin) / self.dx[d]) - floor
-
-            # alpha
-            index[d][...] = (floor.astype(np.int32) - 1) % shape[d]
-            res[...] = 0.
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._alpha(i_y, pscal)[sl]
-
-            # beta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._beta(i_y, pscal)[sl]
-
-            # gamma
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._gamma(i_y, pscal)[sl]
-
-            # delta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._delta(i_y, pscal)[sl]
-
-        elif len(ppos.shape) == 3:
-            index = [i_row, i_col, i_dep]
-            if d == 0:
-                index[1][...] = \
-                    np.indices((shape[1],))[0][np.newaxis, :, np.newaxis]
-                index[2][...] = \
-                    np.indices((shape[2],))[0][np.newaxis, np.newaxis, :]
-            elif d == 1:
-                index[0][...] = \
-                    np.indices((shape[0],))[0][:, np.newaxis, np.newaxis]
-                index[2][...] = \
-                    np.indices((shape[2],))[0][np.newaxis, np.newaxis, :]
-            else:
-                index[0][...] = \
-                    np.indices((shape[0],))[0][:, np.newaxis, np.newaxis]
-                index[1][...] = \
-                    np.indices((shape[1],))[0][np.newaxis, :, np.newaxis]
-            floor = res
-            floor[...] = np.floor((ppos - origin) / self.dx[d])
-            i_y[...] = ((ppos - origin) / self.dx[d]) - floor
-
-            # alpha
-            index[d][...] = (floor.astype(np.int32) - 1) % shape[d]
-            res[...] = 0.
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] + \
-                    self._alpha(i_y, pscal)[sl]
-
-            # beta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._beta(i_y, pscal)[sl]
-
-            # gamma
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._gamma(i_y, pscal)[sl]
-
-            # delta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] + \
-                    self._delta(i_y, pscal)[sl]
-
-        else:
-            index = [i_row]
-            floor = res
-            floor[...] = np.floor((ppos - origin) / self.dx[d])
-            i_y[...] = ((ppos - origin) / self.dx[d]) - floor
-
-            # alpha
-            index[d][...] = (floor.astype(np.int32) - 1) % shape[d]
-            res[...] = 0.
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._alpha(i_y, pscal)[sl]
-
-            # beta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._beta(i_y, pscal)[sl]
-
-            # gamma
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._gamma(i_y, pscal)[sl]
-
-            # delta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._delta(i_y, pscal)[sl]
diff --git a/HySoP/hysop/numerics/remeshing/m6prime.py b/HySoP/hysop/numerics/remeshing/m6prime.py
deleted file mode 100644
index e320b373313fb0267cd51ea1a81387490fc7b2db..0000000000000000000000000000000000000000
--- a/HySoP/hysop/numerics/remeshing/m6prime.py
+++ /dev/null
@@ -1,225 +0,0 @@
-"""
-@file m6prime.py
-"""
-from parmepy.constants import np
-from parmepy.numerics.remeshing.remeshing import Remeshing
-
-
-class M6Prime(Remeshing):
-    """Remshing with M6prime function"""
-
-    def __init__(self, dim, dx, origin):
-        Remeshing.__init__(self, dim)
-        self.name = 'M6Prime'
-        self.dx = dx
-        self.origin = origin
-        self._alpha = lambda y, s: s * y * (
-            y * (y * (y * (13. - 5. * y) - 9.) - 1.) + 2.) / 24.
-        self._beta = lambda y, s: s * y * (
-            y * (y * (y * (25. * y - 64.) + 39.) + 16.) - 16.) / 24.
-        self._gamma = lambda y, s: s * (
-            y * y * (y * (y * (126. - 50. * y) - 70.) - 30.) / 24. + 1.)
-        self._delta = lambda y, s: s * y * (
-            y * (y * (y * (50. * y - 124.) + 66.) + 16.) + 16.) / 24.
-        self._eta = lambda y, s: s * y * (
-            y * (y * (y * (61. - 25. * y) - 33.) - 1.) - 2.) / 24.
-        self._zeta = lambda y, s: s * y * y * y * (
-            y * (5. * y - 12.) + 7.) / 24.
-
-    def __call__(self, ppos, origin, pscal, d, res=None,
-                 i_row=None, i_col=None, i_dep=None, i_y=None):
-
-        """
-        Remesh particles at position ppos with scalar
-        pscal along direction d.
-
-        @param ppos : particle position
-        @param pscal : particle scalar
-        @param d : splitting direction
-        @param i_row : allocated working array (rows indices array).
-        @param i_col : allocated working array (columns indices array).
-        @param i_dep : allocated working array (depth indices array).
-        @param i_y : allocated working array (distance to left grid point).
-        """
-        shape = ppos.shape
-        if len(shape) == 2:
-            index = [i_row, i_col]
-            if d == 0:
-                index[1][...] = np.indices((shape[1],))[0][np.newaxis, :]
-            else:
-                index[0][...] = np.indices((shape[0],))[0][:, np.newaxis]
-            floor = res
-            floor[...] = np.floor((ppos - origin) / self.dx[d])
-            i_y[...] = ((ppos - origin) / self.dx[d]) - floor
-
-            # alpha
-            index[d][...] = (floor.astype(np.int32) - 2) % shape[d]
-            res[...] = 0.
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._alpha(i_y, pscal)[sl]
-
-            # beta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._beta(i_y, pscal)[sl]
-
-            # gamma
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._gamma(i_y, pscal)[sl]
-
-            # delta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._delta(i_y, pscal)[sl]
-
-            # eta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._eta(i_y, pscal)[sl]
-
-            # zeta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._zeta(i_y, pscal)[sl]
-        elif len(ppos.shape) == 3:
-            index = [i_row, i_col, i_dep]
-            if d == 0:
-                index[1][...] = \
-                    np.indices((shape[1],))[0][np.newaxis, :, np.newaxis]
-                index[2][...] = \
-                    np.indices((shape[2],))[0][np.newaxis, np.newaxis, :]
-            elif d == 1:
-                index[0][...] = \
-                    np.indices((shape[0],))[0][:, np.newaxis, np.newaxis]
-                index[2][...] = \
-                    np.indices((shape[2],))[0][np.newaxis, np.newaxis, :]
-            else:
-                index[0][...] = \
-                    np.indices((shape[0],))[0][:, np.newaxis, np.newaxis]
-                index[1][...] = \
-                    np.indices((shape[1],))[0][np.newaxis, :, np.newaxis]
-            floor = res
-            floor[...] = np.floor((ppos - origin) / self.dx[d])
-            i_y[...] = ((ppos - origin) / self.dx[d]) - floor
-
-            # alpha
-            index[d][...] = (floor.astype(np.int32) - 2) % shape[d]
-            res[...] = 0.
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] + \
-                    self._alpha(i_y, pscal)[sl]
-
-            # beta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._beta(i_y, pscal)[sl]
-
-            # gamma
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._gamma(i_y, pscal)[sl]
-
-            # delta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] + \
-                    self._delta(i_y, pscal)[sl]
-
-            # eta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._eta(i_y, pscal)[sl]
-
-            # zeta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._zeta(i_y, pscal)[sl]
-        else:
-            index = [i_row]
-            floor = res
-            floor[...] = np.floor((ppos - origin) / self.dx[d])
-            i_y[...] = ((ppos - origin) / self.dx[d]) - floor
-
-            # alpha
-            index[d][...] = (floor.astype(np.int32) - 2) % shape[d]
-            res[...] = 0.
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._alpha(i_y, pscal)[sl]
-
-            # beta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._beta(i_y, pscal)[sl]
-
-            # gamma
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._gamma(i_y, pscal)[sl]
-
-            # delta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._delta(i_y, pscal)[sl]
-
-            # eta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._eta(i_y, pscal)[sl]
-
-            # zeta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._zeta(i_y, pscal)[sl]
diff --git a/HySoP/hysop/numerics/remeshing/m8prime.py b/HySoP/hysop/numerics/remeshing/m8prime.py
deleted file mode 100644
index e5527e31a025064a2ca3d7644250b8d9237b61e5..0000000000000000000000000000000000000000
--- a/HySoP/hysop/numerics/remeshing/m8prime.py
+++ /dev/null
@@ -1,286 +0,0 @@
-"""
-@file m8prime.py
-"""
-from parmepy.constants import np
-from parmepy.numerics.remeshing.remeshing import Remeshing
-
-
-class M8Prime(Remeshing):
-    """Remshing with M8prime function"""
-
-    def __init__(self, dim, dx, origin):
-        Remeshing.__init__(self, dim)
-        self.name = 'M8Prime'
-        self.dx = dx
-        self.origin = origin
-        self._alpha = lambda y, s: s * (
-            (y * (y * (y * (y * (y * (y * (-10. * y + 21.) + 28.) - 105.)
-                            + 70.) + 35.) - 56.) + 17.) / 3360.)
-        self._beta = lambda y, s: s * (
-            (y * (y * (y * (y * (y * (y * (70. * y - 175.) - 140.) + 770.)
-                            - 560.) - 350.) + 504.) - 102.) / 3360.)
-        self._gamma = lambda y, s: s * (
-            (y * (y * (y * (y * (y * (y * (-210. * y + 609.) + 224.) - 2135.)
-                            + 910.) + 2765.) - 2520.) + 255.) / 3360.)
-        self._delta = lambda y, s: s * (
-            (y * y * (y * y * (y * y * (70. * y - 231.) + 588.) - 980.) + 604.)
-            / 672.)
-        self._eta = lambda y, s: s * (
-            (y * (y * (y * (y * (y * (y * (-70. * y + 259.) - 84.) - 427.)
-                            - 182.) + 553.) + 504.) + 51.) / 672.)
-        self._zeta = lambda y, s: s * (
-            (y * (y * (y * (y * (y * (y * (210. * y - 861.) + 532.) + 770.)
-                            + 560.) - 350.) - 504.) - 102.) / 3360.)
-        self._theta = lambda y, s: s * (
-            (y * (y * (y * (y * (y * (y * (-70. * y + 315.) - 280.) - 105.)
-                            - 70.) + 35.) + 56.) + 17.) / 3360.)
-        self._iota = lambda y, s: s * (
-            (y * y * y * y * y * (y * (10. * y - 49.) + 56.)) / 3360.)
-
-    def __call__(self, ppos, origin, pscal, d, res=None,
-                 i_row=None, i_col=None, i_dep=None, i_y=None):
-
-        """
-        Remesh particles at position ppos with scalar
-        pscal along direction d.
-
-        @param ppos : particle position
-        @param pscal : particle scalar
-        @param d : splitting direction
-        @param i_row : allocated working array (rows indices array).
-        @param i_col : allocated working array (columns indices array).
-        @param i_dep : allocated working array (depth indices array).
-        @param i_y : allocated working array (distance to left grid point).
-        """
-        shape = ppos.shape
-        if len(shape) == 2:
-            index = [i_row, i_col]
-            if d == 0:
-                index[1][...] = np.indices((shape[1],))[0][np.newaxis, :]
-            else:
-                index[0][...] = np.indices((shape[0],))[0][:, np.newaxis]
-            floor = res
-            floor[...] = np.floor((ppos - origin) / self.dx[d])
-            i_y[...] = ((ppos - origin) / self.dx[d]) - floor
-
-            # alpha
-            index[d][...] = (floor.astype(np.int32) - 3) % shape[d]
-            res[...] = 0.
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._alpha(i_y, pscal)[sl]
-
-            # beta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._beta(i_y, pscal)[sl]
-
-            # gamma
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._gamma(i_y, pscal)[sl]
-
-            # delta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._delta(i_y, pscal)[sl]
-
-            # eta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._eta(i_y, pscal)[sl]
-
-            # zeta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._zeta(i_y, pscal)[sl]
-
-            # theta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._theta(i_y, pscal)[sl]
-
-            # iota
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl]] = \
-                    res[index[0][sl], index[1][sl]] +\
-                    self._iota(i_y, pscal)[sl]
-
-        elif len(ppos.shape) == 3:
-            index = [i_row, i_col, i_dep]
-            if d == 0:
-                index[1][...] = \
-                    np.indices((shape[1],))[0][np.newaxis, :, np.newaxis]
-                index[2][...] = \
-                    np.indices((shape[2],))[0][np.newaxis, np.newaxis, :]
-            elif d == 1:
-                index[0][...] = \
-                    np.indices((shape[0],))[0][:, np.newaxis, np.newaxis]
-                index[2][...] = \
-                    np.indices((shape[2],))[0][np.newaxis, np.newaxis, :]
-            else:
-                index[0][...] = \
-                    np.indices((shape[0],))[0][:, np.newaxis, np.newaxis]
-                index[1][...] = \
-                    np.indices((shape[1],))[0][np.newaxis, :, np.newaxis]
-            floor = res
-            floor[...] = np.floor((ppos - origin) / self.dx[d])
-            i_y[...] = ((ppos - origin) / self.dx[d]) - floor
-
-            # alpha
-            index[d][...] = (floor.astype(np.int32) - 3) % shape[d]
-            res[...] = 0.
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] + \
-                    self._alpha(i_y, pscal)[sl]
-
-            # beta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._beta(i_y, pscal)[sl]
-
-            # gamma
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._gamma(i_y, pscal)[sl]
-
-            # delta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] + \
-                    self._delta(i_y, pscal)[sl]
-
-            # eta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._eta(i_y, pscal)[sl]
-
-            # zeta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._zeta(i_y, pscal)[sl]
-
-            # theta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._theta(i_y, pscal)[sl]
-
-            # iota
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl], index[1][sl], index[2][sl]] = \
-                    res[index[0][sl], index[1][sl], index[2][sl]] +\
-                    self._iota(i_y, pscal)[sl]
-
-        else:
-            index = [i_row]
-            floor = res
-            floor[...] = np.floor((ppos - origin) / self.dx[d])
-            i_y[...] = ((ppos - origin) / self.dx[d]) - floor
-
-            # alpha
-            index[d][...] = (floor.astype(np.int32) - 3) % shape[d]
-            res[...] = 0.
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._alpha(i_y, pscal)[sl]
-
-            # beta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._beta(i_y, pscal)[sl]
-
-            # gamma
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._gamma(i_y, pscal)[sl]
-
-            # delta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._delta(i_y, pscal)[sl]
-
-            # eta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._eta(i_y, pscal)[sl]
-
-            # zeta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._zeta(i_y, pscal)[sl]
-
-            # theta
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._theta(i_y, pscal)[sl]
-
-            # iota
-            index[d][...] = (index[d] + 1) % shape[d]
-            for i in xrange(shape[d]):
-                sl = self.slice_i_along_d(i, d)
-                res[index[0][sl]] = \
-                    res[index[0][sl]] +\
-                    self._iota(i_y, pscal)[sl]
diff --git a/HySoP/hysop/numerics/remeshing/remeshing.py b/HySoP/hysop/numerics/remeshing/remeshing.py
index 8ef86e1c9adc5bbffdad65b90efc6ef65fc12ff8..ec05f98c21392ab048ae15b35163d275b0205458 100644
--- a/HySoP/hysop/numerics/remeshing/remeshing.py
+++ b/HySoP/hysop/numerics/remeshing/remeshing.py
@@ -1,30 +1,142 @@
 """
 @file remeshing.py
 """
-from abc import ABCMeta, abstractmethod
-from parmepy.constants import np, PARMES_REAL, ORDER
+from parmepy.constants import np
 from parmepy.numerics.method import NumMethod
 
 
 class Remeshing(NumMethod):
-    """Remshing with M6prime function"""
+    """Remshing"""
 
-    __metaclass__ = ABCMeta
-
-    @abstractmethod
-    def __init__(self, dim):
+    def __init__(self, dim, dx, origin, formula):
+        """
+        Create a remeshing numeric method based on given formula.
+        @param dim : problem dimension
+        @param dx : mesh space step
+        @param origin : mesh lower point
+        @param formula : Remeshing formula to use.
+        Availables formulas :
+          - M4prime
+          - M6prime
+          - M8prime
+          - L6star
+        """
         NumMethod.__init__(self)
-        self.name = 'M6Prime'
+        self.name = formula
+        self.dx = dx
+        self.origin = origin
         self._slice_all = [slice(None, None, None)
                            for d in xrange(dim)]
+        if self.name == 'm4prime':
+            self._shift = 1
+            self._weights = [
+                lambda y, s: s * ((y * (y * (-y + 2.) - 1.)) / 2.),
+                lambda y, s: s * ((y * y * (3. * y - 5.) + 2.) / 2.),
+                lambda y, s: s * ((y * (y * (-3. * y + 4.) + 1.)) / 2.),
+                lambda y, s: s * ((y * y * (y - 1.)) / 2.)
+                ]
+        elif self.name == 'l4star':
+            self._shift = 2
+            self._weights = [
+                lambda y, s: s * y * (y * (y * (y * (13. - 5. * y) - 9.) - 1.) + 2.) / 24.,
+                lambda y, s: s * y * (y * (y * (y * (25. * y - 64.) + 39.) + 16.) - 16.) / 24.,
+                lambda y, s: s * (y * y * (y * (y * (126. - 50. * y) - 70.) - 30.) / 24. + 1.),
+                lambda y, s: s * y * (y * (y * (y * (50. * y - 124.) + 66.) + 16.) + 16.) / 24.,
+                lambda y, s: s * y * (y * (y * (y * (61. - 25. * y) - 33.) - 1.) - 2.) / 24.,
+                lambda y, s: s * y * y * y * (y * (5. * y - 12.) + 7.) / 24.
+                ]
+        elif self.name == 'l4star_c3':
+            self._shift = 2
+            self._weights = [
+                lambda y, s: s * (2. + (-1. + (-2. + (-22. + (58. + (-49. + 14. * y) * y) * y) * y) * y) * y) * y / 24.,
+                lambda y, s: s * (-16. + (16. + (4. + (111. + (-290. + (245. - 70. * y) * y) * y) * y) * y) * y) * y / 24.,
+                lambda y, s: s * (1. + (-30. + (-224. + (580. + (-490. + 140. * y) * y) * y) * y * y) * y * y / 24.),
+                lambda y, s: s * (16. + (16. + (-4. + (226. + (-580. + (490. - 140. * y) * y) * y) * y) * y) * y) * y / 24.,
+                lambda y, s: s * (-2. + (-1. + (2. + (-114. + (290. + (-245. + 70. * y) * y) * y) * y) * y) * y) * y / 24.,
+                lambda y, s: s * (23. + (-58. + (49. - 14. * y) * y) * y) * y * y * y * y / 24.
+
+                ]
+        elif self.name == 'l4star_c4':
+            self._shift = 2
+            self._weights = [
+                lambda y, s: s * (2. + (-1. + (-2. + (1. + (-80. + (273. + (-354. + (207. - 46. * y) * y) * y) * y) * y) * y) * y) * y) * y / 24.,
+                lambda y, s: s * (-16. + (16. + (4. + (-4. + (400. + (-1365. + (1770. + (-1035. + 230. * y) * y) * y) * y) * y) * y) * y) * y) * y / 24.,
+                lambda y, s: s * (1. + (-30. + (6. + (-800. + (2730. + (-3540. + (2070. - 460. * y) * y) * y) * y) * y) * y * y) * y * y / 24.),
+                lambda y, s: s * (16. + (16. + (-4. + (-4. + (800. + (-2730. + (3540. + (-2070. + 460. * y) * y) * y) * y) * y) * y) * y) * y) * y / 24.,
+                lambda y, s: s * (-2. + (-1. + (2. + (1. + (-400. + (1365. + (-1770. + (1035. - 230. * y) * y) * y) * y) * y) * y) * y) * y) * y / 24.,
+                lambda y, s: s * (80. + (-273. + (354. + (-207. + 46. * y) * y) * y) * y) * y * y * y * y * y / 24.
+                ]
+        elif self.name == 'm8prime':
+            self._shift = 3
+            self._weights = [
+                lambda y, s: s * ((y * (y * (y * (y * (y * (y * (-10. * y + 21.) + 28.) - 105.)+ 70.) + 35.) - 56.) + 17.) / 3360.),
+                lambda y, s: s * ((y * (y * (y * (y * (y * (y * (70. * y - 175.) - 140.) + 770.)- 560.) - 350.) + 504.) - 102.) / 3360.),
+                lambda y, s: s * ((y * (y * (y * (y * (y * (y * (-210. * y + 609.) + 224.) - 2135.)+ 910.) + 2765.) - 2520.) + 255.) / 3360.),
+                lambda y, s: s * ((y * y * (y * y * (y * y * (70. * y - 231.) + 588.) - 980.) + 604.)/ 672.),
+                lambda y, s: s * ((y * (y * (y * (y * (y * (y * (-70. * y + 259.) - 84.) - 427.)- 182.) + 553.) + 504.) + 51.) / 672.),
+                lambda y, s: s * ((y * (y * (y * (y * (y * (y * (210. * y - 861.) + 532.) + 770.)+ 560.) - 350.) - 504.) - 102.) / 3360.),
+                lambda y, s: s * ((y * (y * (y * (y * (y * (y * (-70. * y + 315.) - 280.) - 105.)- 70.) + 35.) + 56.) + 17.) / 3360.),
+                lambda y, s: s * ((y * y * y * y * y * (y * (10. * y - 49.) + 56.)) / 3360.)
+                ]
+        elif self.name == 'l6star':
+            self._shift = 3
+            self._weights = [
+                lambda y, s: s * (((-12. + (4. + (15. + (140. + (-370.+ (312. - 89. * y) * y) * y) * y) * y) * y) * y) / 720.),
+                lambda y, s: s * (((108. + (-54. + (-120. + (-955. +(2581. + (-2183. + 623. * y) * y) * y) * y) * y) * y ) * y) / 720.),
+                lambda y, s: s * (((-180. + (180. + (65. + (950. +(-2574. + (2182. - 623. * y) * y) * y) * y) * y) * y) * y) / 240.),
+                lambda y, s: s * ( 1. + ((-196. + (-959. + (2569. +(-2181. + 623. * y) * y) * y) * y * y ) * y * y) / 144.),
+                lambda y, s: s * (((108. + (108. + (-39. + (976. + (-2566.+ (2180. - 623. * y) * y) * y) * y) * y) * y) * y) / 144.),
+                lambda y, s: s * (((-36. + (-18. + (40. + (-995. + (2565.+ (-2179. + 623. * y) * y) * y) * y) * y) * y) * y) / 240.),
+                lambda y, s: s * (((12. + (4. + (-15. + (1010. + (-2566.+ (2178. - 623. * y) * y) * y) * y) * y) * y) * y) / 720.),
+                lambda y, s: s * (((-145. + (367. + (-311. + 89. * y)* y) * y) * y * y * y * y) / 720.)
+                ]
+        elif self.name == 'l6star_c4':
+            self._shift = 3
+            self._weights = [
+                lambda y, s: s * (-12. + (4. + (15. + (-5. + (500. + (-1718. + (2231. + (-1305. + 290. * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (108. + (-54. + (-120. + (60. + (-3509. + (12027. + (-15617. + (9135. - 2030. * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (-540. + (540. + (195. + (-195. + (10548. + (-36084. + (46851. + (-27405. + 6090. * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (1. + (-980. + (280. + (-17605. + (60145. + (-78085. + (45675. - 10150. * y) * y) * y) * y) * y) * y * y) * y * y / 720.),
+                lambda y, s: s * (540. + (540. + (-195. + (-195. + (17620. + (-60150. + (78085. + (-45675. + 10150. * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (-108. + (-54. + (120. + (60. + (-10575. + (36093. + (-46851. + (27405. - 6090. * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (12. + (4. + (-15. + (-5. + (3524. + (-12032. + (15617. + (-9135. + 2030. * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (-503. + (1719. + (-2231. + (1305. - 290. * y) * y) * y) * y) * y * y * y * y * y / 720.
+                ]
+        elif self.name == 'l6star_c5':
+            self._shift = 3
+            self._weights = [
+                lambda y, s: s * (-12. + (4. + (15. + (-5. + (-3. + (1803. + (-7829. + (13785. + (-12285. + (5533. - 1006. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (108. + (-54. + (-120. + (60. + (12. + (-12620. + (54803. + (-96495. + (85995. + (-38731. + 7042. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (-540. + (540. + (195. + (-195. + (-15. + (37857. + (-164409. + (289485. + (-257985. + (116193. - 21126. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (1. + (-980. + (280. + (-63090. + (274015. + (-482475. + (429975. + (-193655. + 35210. * y) * y) * y) * y) * y) * y * y) * y * y) * y * y / 720.),
+                lambda y, s: s * (540. + (540. + (-195. + (-195. + (15. + (63085. + (-274015. + (482475. + (-429975. + (193655. - 35210. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (-108. + (-54. + (120. + (60. + (-12. + (-37848. + (164409. + (-289485. + (257985. + (-116193. + 21126. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (12. + (4. + (-15. + (-5. + (3. + (12615. + (-54803. + (96495. + (-85995. + (38731. - 7042. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (-1802. + (7829. + (-13785. + (12285. + (-5533. + 1006. * y) * y) * y) * y) * y) * y * y * y * y * y * y / 720.
+                ]
+        elif self.name == 'l6star_c6':
+            self._shift = 3
+            self._weights = [
+                lambda y, s: s * (-12. + (4. + (15. + (-5. + (-3. + (1. + (6587. + (-34869. + (77815. + (-93577. + (63866. + (-23426. + 3604. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (108. + (-54. + (-120. + (60. + (12. + (-6. + (-46109. + (244083. + (-544705. + (655039. + (-447062. + (163982. - 25228. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (-540. + (540. + (195. + (-195. + (-15. + (15. + (138327. + (-732249. + (1634115. + (-1965117. + (1341186. + (-491946. + 75684. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (1. + (-980. + (280. + (-20. + (-230545. + (1220415. + (-2723525. + (3275195. + (-2235310. + (819910. - 126140. * y) * y) * y) * y) * y) * y) * y) * y * y) * y * y) * y * y / 720.),
+                lambda y, s: s * (540. + (540. + (-195. + (-195. + (15. + (15. + (230545. + (-1220415. + (2723525. + (-3275195. + (2235310. + (-819910. + 126140. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (-108. + (-54. + (120. + (60. + (-12. + (-6. + (-138327. + (732249. + (-1634115. + (1965117. + (-1341186. + (491946. - 75684. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (12. + (4. + (-15. + (-5. + (3. + (1. + (46109. + (-244083. + (544705. + (-655039. + (447062. + (-163982. + 25228. * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y) * y / 720.,
+                lambda y, s: s * (-6587. + (34869. + (-77815. + (93577. + (-63866. + (23426. - 3604. * y) * y) * y) * y) * y) * y) * y * y * y * y * y * y * y / 720.
+                ]
+        else:
+            raise ValueError("Unknown formula : " + self.name)
 
     def slice_i_along_d(self, i, d):
         l = list(self._slice_all)
         l[d] = i
         return tuple(l)
 
-    @abstractmethod
-    def __call__(self, ppos, pscal, d):
+    def __call__(self, ppos, origin, pscal, d, res=None,
+                 i_row=None, i_col=None, i_dep=None, i_y=None, work=None):
+
         """
         Remesh particles at position ppos with scalar
         pscal along direction d.
@@ -32,5 +144,52 @@ class Remeshing(NumMethod):
         @param ppos : particle position
         @param pscal : particle scalar
         @param d : splitting direction
+        @param i_row : allocated working array (rows indices array).
+        @param i_col : allocated working array (columns indices array).
+        @param i_dep : allocated working array (depth indices array).
+        @param i_y : allocated working array (distance to left grid point).
         """
-        pass
+        shape = ppos.shape
+        if len(shape) == 2:
+            index = tuple([i_row, i_col])
+            if d == 0:
+                index[1][...] = np.indices((shape[1],))[0][np.newaxis, :]
+            else:
+                index[0][...] = np.indices((shape[0],))[0][:, np.newaxis]
+        elif len(shape) == 3:
+            index = tuple([i_row, i_col, i_dep])
+            if d == 0:
+                index[1][...] = \
+                    np.indices((shape[1],))[0][np.newaxis, :, np.newaxis]
+                index[2][...] = \
+                    np.indices((shape[2],))[0][np.newaxis, np.newaxis, :]
+            elif d == 1:
+                index[0][...] = \
+                    np.indices((shape[0],))[0][:, np.newaxis, np.newaxis]
+                index[2][...] = \
+                    np.indices((shape[2],))[0][np.newaxis, np.newaxis, :]
+            else:
+                index[0][...] = \
+                    np.indices((shape[0],))[0][:, np.newaxis, np.newaxis]
+                index[1][...] = \
+                    np.indices((shape[1],))[0][np.newaxis, :, np.newaxis]
+        else:
+            index = tuple([i_row, ])
+
+        floor = res
+        floor[...] = (ppos - origin) / self.dx[d]
+        i_y[...] = (floor)
+        floor[...] = np.floor(floor)
+        i_y[...] -= floor
+
+        index[d][...] = (floor.astype(np.int32) - self._shift) % shape[d]
+        res[...] = 0.
+
+        for w_id, w in enumerate(self._weights):
+            if w_id > 0:
+                index[d][...] = (index[d] + 1) % shape[d]
+            for i in xrange(shape[d]):
+                sl = self.slice_i_along_d(i, d)
+                work = w(i_y, pscal)
+                index_sl = tuple([ind[sl] for ind in index])
+                res[index_sl] = res[index_sl] + work[sl]
diff --git a/HySoP/hysop/operator/discrete/particle_advection.py b/HySoP/hysop/operator/discrete/particle_advection.py
index 44a7a9a57b8d49f08372ac9a653e33ec4c6ac2ee..dc4dc69c928c77f699da39766b0ef0e800b5260b 100644
--- a/HySoP/hysop/operator/discrete/particle_advection.py
+++ b/HySoP/hysop/operator/discrete/particle_advection.py
@@ -28,7 +28,9 @@ class ParticleAdvection(DiscreteOperator):
         @param method : Method used
           - 'rk2' : Runge Kutta 2nd order advection
           - 'm4prime' : M4prime formula
-          - 'm6prime' : M6prime formula
+          - 'l4star' : Labmda4star formula
+          - 'l4star_c3' : Labmda4star C3 formula
+          - 'l4star_c4' : Labmda4star C4 formula
           - 'm8prime' : M8prime formula
           - 'l6star' : Lambda6star formula
         """
@@ -51,6 +53,10 @@ class ParticleAdvection(DiscreteOperator):
         self.part_position = part_position
         self.part_advectedFields = part_advectedFields
         self.num_method = None
+        self.available_methods = [
+            'm4prime', 'm8prime',
+            'l4star_c4', 'l4star_c3', 'l4star',
+            'l6star_c6', 'l6star_c5', 'l6star_c4','l6star']
 
     @debug
     def setUp(self):
@@ -75,25 +81,19 @@ class ParticleAdvection(DiscreteOperator):
             self.name += '_rk2'
             from parmepy.numerics.integrators.runge_kutta2 import RK2_scalar
             self.num_advec = RK2_scalar()
-        if self.method.find('m4prime') >= 0:
-            self.name += '_m4prime'
-            from parmepy.numerics.remeshing.m4prime import M4Prime as Remesh
-        elif self.method.find('m6prime') >= 0:
-            self.name += '_m6prime'
-            from parmepy.numerics.remeshing.m6prime import M6Prime as Remesh
-        elif self.method.find('m8prime') >= 0:
-            self.name += '_m8prime'
-            from parmepy.numerics.remeshing.m8prime import M8Prime as Remesh
-        elif self.method.find('l6star') >= 0:
-            self.name += '_l6star'
-            from parmepy.numerics.remeshing.l6star import L6Star as Remesh
-        else:
-            self.name += '_m6prime'
-            from parmepy.numerics.remeshing.m6prime import M6Prime as Remesh
-        self.num_remesh = Remesh(
+        remesh = 'l4star'
+        for m in self.available_methods:
+            if self.method.find(m) >= 0:
+                remesh = m
+                break
+        self.name += '_' + remesh
+        from parmepy.numerics.remeshing.remeshing import Remeshing
+        self.num_remesh = Remeshing(
             self.velocity.dimension,
             self.advectedFields[0].topology.mesh.space_step,
-            self.advectedFields[0].topology.mesh.origin)
+            self.advectedFields[0].topology.mesh.origin,
+            remesh)
+
         self.interpolation = [
             Linear(self.velocity, d,
                    self.advectedFields[0].topology.mesh.space_step,
@@ -108,9 +108,12 @@ class ParticleAdvection(DiscreteOperator):
             self.i_row, self.i_col = \
                 np.indices(self.part_position.data.shape)
             self.i_dep = None
-        else:
+        elif len(self.part_position.data.shape) == 3:
             self.i_row, self.i_col, self.i_dep = \
                 np.indices(self.part_position.data.shape)
+        else:
+            self.i_row = np.indices(self.part_position.data.shape)[0]
+            self.i_col, self.i_dep = None, None
 
         self._isUpToDate = True
 
@@ -152,7 +155,7 @@ class ParticleAdvection(DiscreteOperator):
         self.num_advec(
             self.interpolation[self.dir],
             t, dt, self.part_position.data, res=self.part_position.data,
-            work=self.work,
+            work=self.work, yprime=self.velocity.data[self.dir],
             i_row=self.i_row, i_col=self.i_col, i_dep=self.i_dep,
             i_y=self.i_y)
 
@@ -166,14 +169,14 @@ class ParticleAdvection(DiscreteOperator):
                         adF.topology.mesh.origin[self.dir],
                         p_adF.data[dim], self.dir, res=adF[dim],
                         i_row=self.i_row, i_col=self.i_col, i_dep=self.i_dep,
-                        i_y=self.i_y)
+                        i_y=self.i_y, work=self.work)
             else:
                 self.num_remesh(
                     self.part_position.data,
                     adF.topology.mesh.origin[self.dir],
                     p_adF.data, self.dir, res=adF.data,
                     i_row=self.i_row, i_col=self.i_col, i_dep=self.i_dep,
-                    i_y=self.i_y)
+                    i_y=self.i_y, work=self.work)
 
     @debug
     def finalize(self):
diff --git a/HySoP/hysop/operator/monitors/printer.py b/HySoP/hysop/operator/monitors/printer.py
index feb952200bd48ba732035b252e7829a629fdcca9..78abbcd43db4056021e3ae98502ad6634458c0a7 100644
--- a/HySoP/hysop/operator/monitors/printer.py
+++ b/HySoP/hysop/operator/monitors/printer.py
@@ -42,7 +42,7 @@ class Printer(Monitoring):
         self.output = []
         ## Method to collect data in case of distributed data
         self.get_data_method = None
-        if self.freq != 0:
+        if self.freq > 0:
             ## Printer core method
             self.step = self._printStep
         else:
@@ -62,7 +62,14 @@ class Printer(Monitoring):
         if simulation is None:
             raise ValueError("Missing simulation value for monitoring.")
 
-        self.step(simulation.currentIteration)
+        self._call_number += 1
+        if self.freq > 0 and (simulation.currentIteration % self.freq) == 0:
+            self.step(simulation.currentIteration)
+
+    def finalize(self):
+        if self.freq == -1:
+            self._printStep(self._call_number)
+        Monitoring.finalize(self)
 
     def _build_vtk_dict(self):
         """Build a dictionary from fields to VTK image."""
@@ -105,77 +112,92 @@ class Printer(Monitoring):
         If fails, turn to classical ascii output.
         @param iter : current iteration number
         """
-        if (ite % self.freq) == 0:
-            self._call_number += 1
-            # Transfer from GPU to CPU if required
-            for f in self.variables:
-                for df in f.discreteFields.values():
-                    try:
-                        df.toHost()
-                    except AttributeError:
-                        pass
-            # Set output file name
-            filename = self.prefix + str(main_rank)
-            filename += '_' + "iter_{0:03d}".format(ite) + self.ext
-            print "Print to file " + filename
-            ## VTK output \todo: Need fix in 2D, getting an IOError.
-            if self.ext == '.vtk':
-                #orig = self.variables[0].discreteFields.values()[0].topology.mesh.global_start
-                topo = self.variables[0].discreteFields.keys()[0]
-                orig = tuple([topo.mesh.origin[i]
-                              for i in xrange(topo.mesh.dim)])
-                coords = topo.mesh.coords
-                ind = topo.mesh.local_start
-                orig = tuple([topo.mesh.coords[i].flatten()[ind[i]]
-                              for i in xrange(topo.mesh.dim)])
-                spacing = tuple(topo.mesh.space_step)
-                evtk.imageToVTK(filename, origin=orig, spacing=spacing,
-                                pointData=self._build_vtk_dict())
-            elif self.ext == '.dat':
-                if self.variables[0].domain.dimension == 2:
-                    ## Standard output
-                    f = open(filename, 'w')
-                    df = self.variables[0].discreteFields.values()[0]
-                    shape = df.topology.mesh.resolution
-                    coords = df.topology.mesh.coords
-                    if len(shape) == 2:
-                        for i in xrange(shape[0] - 1):
-                            for j in xrange(shape[1] - 1):
-                                f.write("{0:8.12} {1:8.12} ".format(
-                                        coords[0][i, 0], coords[1][0, j]))
-                                for field in self.variables:
-                                    df = field.discreteFields.values()[0]
-                                    if field.isVector:
-                                        f.write("{0:8.12} {1:8.12} ".format(
-                                                df[0][i, j],
-                                                df[1][i, j]))
-                                    else:
-                                        f.write("{0:8.12} ".format(
-                                                df[i, j]))
-                                f.write("\n")
-                    else:
-                        for i in xrange(shape[0] - 1):
-                            for j in xrange(shape[1] - 1):
-                                for k in xrange(shape[2] - 1):
+        # Transfer from GPU to CPU if required
+        for f in self.variables:
+            for df in f.discreteFields.values():
+                try:
+                    df.toHost()
+                except AttributeError:
+                    pass
+        # Set output file name
+        filename = self.prefix + str(main_rank)
+        filename += '_' + "iter_{0:03d}".format(ite) + self.ext
+        print "Print to file " + filename
+        ## VTK output \todo: Need fix in 2D, getting an IOError.
+        if self.ext == '.vtk':
+            #orig = self.variables[0].discreteFields.values()[0].topology.mesh.global_start
+            topo = self.variables[0].discreteFields.keys()[0]
+            orig = tuple([topo.mesh.origin[i]
+                          for i in xrange(topo.mesh.dim)])
+            coords = topo.mesh.coords
+            ind = topo.mesh.local_start
+            orig = tuple([topo.mesh.coords[i].flatten()[ind[i]]
+                          for i in xrange(topo.mesh.dim)])
+            spacing = tuple(topo.mesh.space_step)
+            evtk.imageToVTK(filename, origin=orig, spacing=spacing,
+                            pointData=self._build_vtk_dict())
+        elif self.ext == '.dat':
+            f = open(filename, 'w')
+            if self.variables[0].domain.dimension == 2:
+                ## Standard output
+                df = self.variables[0].discreteFields.values()[0]
+                shape = df.topology.mesh.resolution
+                coords = df.topology.mesh.coords
+                if len(shape) == 2:
+                    for i in xrange(shape[0] - 1):
+                        for j in xrange(shape[1] - 1):
+                            f.write("{0:8.12} {1:8.12} ".format(
+                                    coords[0][i, 0], coords[1][0, j]))
+                            for field in self.variables:
+                                df = field.discreteFields.values()[0]
+                                if field.isVector:
+                                    f.write("{0:8.12} {1:8.12} ".format(
+                                            df[0][i, j],
+                                            df[1][i, j]))
+                                else:
+                                    f.write("{0:8.12} ".format(
+                                            df[i, j]))
+                            f.write("\n")
+            elif self.variables[0].domain.dimension == 3:
+                df = self.variables[0].discreteFields.values()[0]
+                shape = df.topology.mesh.resolution
+                coords = df.topology.mesh.coords
+                for i in xrange(shape[0] - 1):
+                    for j in xrange(shape[1] - 1):
+                        for k in xrange(shape[2] - 1):
+                            f.write(
+                                "{0:8.12} {1:8.12} {2:8.12} ".format(
+                                    coords[0][i, 0, 0],
+                                    coords[1][0, j, 0],
+                                    coords[2][0, 0, k]))
+                            for field in self.variables:
+                                df = field.discreteFields.values()[0]
+                                if field.isVector:
                                     f.write(
-                                        "{0:8.12} {1:8.12} {2:8.12} ".format(
-                                            coords[0][i, 0, 0],
-                                            coords[1][0, j, 0],
-                                            coords[2][0, 0, k]))
-                                    for field in self.variables:
-                                        df = field.discreteFields.values()[0]
-                                        if field.isVector:
-                                            f.write(
-                                                "{0:8.12} {1:8.12} " +
-                                                "{2:8.12} ".format(
-                                                    df[0][i, j, k],
-                                                    df[1][i, j, k],
-                                                    df[2][i, j, k]))
-                                        else:
-                                            f.write("{0:8.12} ".format(
-                                                    df[i, j, k]))
-                                    f.write("\n")
-                    f.close()
+                                        "{0:8.12} {1:8.12} " +
+                                        "{2:8.12} ".format(
+                                            df[0][i, j, k],
+                                            df[1][i, j, k],
+                                            df[2][i, j, k]))
+                                else:
+                                    f.write("{0:8.12} ".format(
+                                            df[i, j, k]))
+                            f.write("\n")
+            else:
+                df = self.variables[0].discreteFields.values()[0]
+                shape = df.topology.mesh.resolution
+                coords = df.topology.mesh.coords
+                for i in xrange(shape[0] - 1):
+                    f.write("{0:8.12} ".format(coords[0][i]))
+                    for field in self.variables:
+                        df = field.discreteFields.values()[0]
+                        if field.isVector:
+                            f.write(
+                                "{0:8.12} ".format(df[0][i]))
+                        else:
+                            f.write("{0:8.12} ".format(df[i]))
+                            f.write("\n")
+            f.close()
 
 if __name__ == "__main__":
     print __doc__
diff --git a/HySoP/hysop/problem/simulation.py b/HySoP/hysop/problem/simulation.py
index 746180989d50ae7e075f537f4d78cec06ed2720c..b223b9d93b74b23148721f95afd54f2fdb93cb19 100644
--- a/HySoP/hysop/problem/simulation.py
+++ b/HySoP/hysop/problem/simulation.py
@@ -42,6 +42,9 @@ class Simulation(object):
         if self.currentIteration < self.iterMax:
             self.currentIteration += 1
             self.time += self.timeStep
+            # adjust last timestep to reach self.end
+            if self.end - self.time < self.timeStep and self.end > self.time:
+                self.timeStep = self.end - self.time
         else:
             self.isOver = True
         if self.time >= self.end:
@@ -52,8 +55,9 @@ class Simulation(object):
         print current state
         """
         if main_rank == 0:
-            print "=== Iteration : {0:3d}, start from t ={1:6.3f} ===".format(
-                self.currentIteration, self.time)
+            print "=== Iteration : {0:3d}, start from t ={1:6.3f} \
+to t ={2:6.3f} ===".format(
+                self.currentIteration, self.time, self.time + self.timeStep)
 
     def reset(self):
         """