diff --git a/TurTLE/test/test_turtle_NSVEparticles.py b/TurTLE/test/test_turtle_NSVEparticles.py
index 8329a0b5ceebdb0f8477fbb45dc05645891a774e..4ed1d9968ae0288fdcb05f26dd072575435770c4 100644
--- a/TurTLE/test/test_turtle_NSVEparticles.py
+++ b/TurTLE/test/test_turtle_NSVEparticles.py
@@ -89,6 +89,7 @@ def main():
         y0 = f0['tracers0/rhs/{0}'.format(iteration)][...]
         y1 = f1['tracers0/rhs/{0}'.format(iteration)][...]
         rhs_error = np.max(np.abs(y0 - y1))
+        print(field_error, traj_error, rhs_error)
         assert(field_error < 1e-5)
         assert(traj_error < 1e-5)
         assert(rhs_error < 1e-5)
diff --git a/cpp/field.cpp b/cpp/field.cpp
index 2fd79ce4fe7d25f2f7f8bdae0a500ee40e0a8330..a5779752ee4ca232f4883042c3171ec4c45ab18a 100644
--- a/cpp/field.cpp
+++ b/cpp/field.cpp
@@ -1278,16 +1278,20 @@ void field<rnumber, be, fc>::symmetrize()
     typename fftw_interface<rnumber>::complex *cdata = this->get_cdata();
     // symmetrize kx = 0 plane, line by line, for ky != 0
     MPI_Status *mpistatus = new MPI_Status;
-    typename fftw_interface<rnumber>::complex *buffer = new typename fftw_interface<rnumber>::complex[ncomp(fc)*this->clayout->sizes[1]];
-    //typename fftw_interface<rnumber>::complex *buffer;
-    //buffer = fftw_interface<rnumber>::alloc_complex(ncomp(fc)*this->clayout->sizes[1]);
+    // bufferp will hold data from "plus", i.e. iy
+    // bufferm will hold data from "minus", i.e. ny - iy
+    typename fftw_interface<rnumber>::complex *bufferp  = new typename fftw_interface<rnumber>::complex[ncomp(fc)*this->clayout->sizes[1]];
+    typename fftw_interface<rnumber>::complex *bufferm = new typename fftw_interface<rnumber>::complex[ncomp(fc)*this->clayout->sizes[1]];
     /*ptrdiff_t tindex;*/
-    int ranksrc, rankdst;
+    int rankp, rankm;
+    // for each ky slice except ky=0
     for (ptrdiff_t iy = 1; iy < ptrdiff_t(this->clayout->sizes[0]/2); iy++)
     {
-        ranksrc = this->clayout->rank[0][iy];
-        rankdst = this->clayout->rank[0][this->clayout->sizes[0] - iy];
-        if (this->clayout->myrank == ranksrc)
+        // read rank plus and rank minus
+        rankp = this->clayout->rank[0][iy];
+        rankm = this->clayout->rank[0][this->clayout->sizes[0] - iy];
+        // if my rank is rank plus, I should fill out the plus buffer
+        if (this->clayout->myrank == rankp)
         {
             ptrdiff_t iyy = iy - this->clayout->starts[0];
             for (ptrdiff_t iz = 0; iz < ptrdiff_t(this->clayout->sizes[1]); iz++)
@@ -1295,50 +1299,103 @@ void field<rnumber, be, fc>::symmetrize()
                 ptrdiff_t cindex = this->get_cindex(0, iyy, iz);
                 for (int cc = 0; cc < int(ncomp(fc)); cc++)
                     for (int imag_comp=0; imag_comp<2; imag_comp++)
-                        (*(buffer + ncomp(fc)*iz+cc))[imag_comp] =
+                        (*(bufferp + ncomp(fc)*iz+cc))[imag_comp] =
                             (*(cdata + ncomp(fc)*cindex + cc))[imag_comp];
             }
         }
-        if (ranksrc != rankdst)
+        // if my rank is rank minus, I should fill out the minus buffer
+        if (this->clayout->myrank == rankm)
         {
-            if (this->clayout->myrank == ranksrc)
-                MPI_Send((void*)buffer,
+            ptrdiff_t iyy = (this->clayout->sizes[0] - iy) - this->clayout->starts[0];
+            for (ptrdiff_t iz = 0; iz < ptrdiff_t(this->clayout->sizes[1]); iz++)
+            {
+                ptrdiff_t cindex = this->get_cindex(0, iyy, iz);
+                for (int cc = 0; cc < int(ncomp(fc)); cc++)
+                    for (int imag_comp=0; imag_comp<2; imag_comp++)
+                        (*(bufferm + ncomp(fc)*iz+cc))[imag_comp] =
+                            (*(cdata + ncomp(fc)*cindex + cc))[imag_comp];
+            }
+        }
+        // if ranks are different, send and receive
+        if (rankp != rankm)
+        {
+            // if my rank is rank plus, send buffer plus, receive buffer minus
+            if (this->clayout->myrank == rankp)
+            {
+                MPI_Send((void*)bufferp,
                          ncomp(fc)*this->clayout->sizes[1],
                          mpi_real_type<rnumber>::complex(),
-                         rankdst, iy,
+                         rankm, 2*iy+0,
                          this->clayout->comm);
-            if (this->clayout->myrank == rankdst)
-                MPI_Recv((void*)buffer,
+                MPI_Recv((void*)bufferm,
                          ncomp(fc)*this->clayout->sizes[1],
                          mpi_real_type<rnumber>::complex(),
-                         ranksrc, iy,
+                         rankm, 2*iy+1,
                          this->clayout->comm,
                          mpistatus);
+            }
+            // if my rank is rank minus, receive buffer plus, send buffer minus
+            if (this->clayout->myrank == rankm)
+            {
+                MPI_Recv((void*)bufferp,
+                         ncomp(fc)*this->clayout->sizes[1],
+                         mpi_real_type<rnumber>::complex(),
+                         rankp, 2*iy+0,
+                         this->clayout->comm,
+                         mpistatus);
+                MPI_Send((void*)bufferm,
+                         ncomp(fc)*this->clayout->sizes[1],
+                         mpi_real_type<rnumber>::complex(),
+                         rankp, 2*iy+1,
+                         this->clayout->comm);
+            }
+        }
+        // if I my rank is either plus or minus, I should update my slice
+        if (this->clayout->myrank == rankp)
+        {
+            ptrdiff_t iyy = iy - this->clayout->starts[0];
+            for (ptrdiff_t iz = 1; iz < ptrdiff_t(this->clayout->sizes[1]); iz++)
+            {
+                ptrdiff_t izz = (this->clayout->sizes[1] - iz);
+                ptrdiff_t cindex = this->get_cindex(0, iyy, izz);
+                for (int cc = 0; cc < int(ncomp(fc)); cc++)
+                {
+                    (*(cdata + ncomp(fc)*cindex + cc))[0] =  ((*(bufferp + ncomp(fc)*iz+cc))[0] + (*(bufferm + ncomp(fc)*iz+cc))[0])/2;
+                    (*(cdata + ncomp(fc)*cindex + cc))[1] =  ((*(bufferp + ncomp(fc)*iz+cc))[1] - (*(bufferp + ncomp(fc)*iz+cc))[1])/2;
+                }
+            }
+            ptrdiff_t cindex = this->get_cindex(0, iyy, 0);
+            for (int cc = 0; cc < int(ncomp(fc)); cc++)
+            {
+                (*(cdata + cc + ncomp(fc)*cindex))[0] =  ((*(bufferp + cc))[0] + (*(bufferm + cc))[0])/2;
+                (*(cdata + cc + ncomp(fc)*cindex))[1] =  ((*(bufferp + cc))[1] - (*(bufferm + cc))[1])/2;
+            }
         }
-        if (this->clayout->myrank == rankdst)
+        // if I my rank is either plus or minus, I should update my slice
+        if (this->clayout->myrank == rankm)
         {
             ptrdiff_t iyy = (this->clayout->sizes[0] - iy) - this->clayout->starts[0];
             for (ptrdiff_t iz = 1; iz < ptrdiff_t(this->clayout->sizes[1]); iz++)
             {
                 ptrdiff_t izz = (this->clayout->sizes[1] - iz);
                 ptrdiff_t cindex = this->get_cindex(0, iyy, izz);
-                //DEBUG_MSG("iy = %ld, iz = %ld\n", iy, iz);
                 for (int cc = 0; cc < int(ncomp(fc)); cc++)
                 {
-                    (*(cdata + ncomp(fc)*cindex + cc))[0] =  (*(buffer + ncomp(fc)*iz+cc))[0];
-                    (*(cdata + ncomp(fc)*cindex + cc))[1] = -(*(buffer + ncomp(fc)*iz+cc))[1];
+                    (*(cdata + ncomp(fc)*cindex + cc))[0] =  ((*(bufferp + ncomp(fc)*iz+cc))[0] + (*(bufferm + ncomp(fc)*iz+cc))[0])/2;
+                    (*(cdata + ncomp(fc)*cindex + cc))[1] = -((*(bufferp + ncomp(fc)*iz+cc))[1] - (*(bufferp + ncomp(fc)*iz+cc))[1])/2;
                 }
             }
             ptrdiff_t cindex = this->get_cindex(0, iyy, 0);
             for (int cc = 0; cc < int(ncomp(fc)); cc++)
             {
-                (*(cdata + cc + ncomp(fc)*cindex))[0] =  (*(buffer + cc))[0];
-                (*(cdata + cc + ncomp(fc)*cindex))[1] = -(*(buffer + cc))[1];
+                (*(cdata + cc + ncomp(fc)*cindex))[0] =  ((*(bufferp + cc))[0] + (*(bufferm + cc))[0])/2;
+                (*(cdata + cc + ncomp(fc)*cindex))[1] = -((*(bufferp + cc))[1] - (*(bufferm + cc))[1])/2;
             }
         }
     }
     //fftw_interface<rnumber>::free(buffer);
-    delete[] buffer;
+    delete[] bufferp;
+    delete[] bufferm;
     delete mpistatus;
     // symmetrize kx = 0, ky = 0 line
     if (this->clayout->myrank == this->clayout->rank[0][0])
@@ -1349,8 +1406,12 @@ void field<rnumber, be, fc>::symmetrize()
             ptrdiff_t cindex1 = this->get_cindex(0, 0, this->clayout->sizes[1] - iz);
             for (int cc = 0; cc < int(ncomp(fc)); cc++)
             {
-                (*(cdata + cc + ncomp(fc)*cindex1))[0] =  (*(cdata + cc + ncomp(fc)*cindex0))[0];
-                (*(cdata + cc + ncomp(fc)*cindex1))[1] = -(*(cdata + cc + ncomp(fc)*cindex0))[1];
+                double re = ((*(cdata + cc + ncomp(fc)*cindex0))[0] + (*(cdata + cc + ncomp(fc)*cindex1))[0])/2;
+                double im = ((*(cdata + cc + ncomp(fc)*cindex0))[1] - (*(cdata + cc + ncomp(fc)*cindex1))[1])/2;
+                (*(cdata + cc + ncomp(fc)*cindex0))[0] =  re;
+                (*(cdata + cc + ncomp(fc)*cindex0))[1] =  im;
+                (*(cdata + cc + ncomp(fc)*cindex1))[0] =  re;
+                (*(cdata + cc + ncomp(fc)*cindex1))[1] = -im;
             }
         }
     }