diff --git a/bfps/cpp/full_code/NSVEparticlesP2P.cpp b/bfps/cpp/full_code/NSVEparticlesP2P.cpp
index 12d77149a1c36b0393b89b749c8fe515e15d697b..3a8312f189c4d4e84b38c89e694803eef13efbd5 100644
--- a/bfps/cpp/full_code/NSVEparticlesP2P.cpp
+++ b/bfps/cpp/full_code/NSVEparticlesP2P.cpp
@@ -12,7 +12,10 @@ int NSVEparticlesP2P<rnumber>::initialize(void)
     this->NSVE<rnumber>::initialize();
 
     p2p_computer<double, long long int> current_p2p_computer;
+    // TODO: particle interactions are switched off manually for testing purposes.
+    // this needs to be fixed once particle interactions can be properly resolved.
     current_p2p_computer.setEnable(enable_p2p);
+    //current_p2p_computer.setEnable(false);
 
     particles_inner_computer<double, long long int> current_particles_inner_computer(inner_v0);
     current_particles_inner_computer.setEnable(enable_inner);
@@ -59,7 +62,12 @@ int NSVEparticlesP2P<rnumber>::step(void)
     this->fs->compute_velocity(this->fs->cvorticity);
     this->fs->cvelocity->ift();
     if(enable_vorticity_omega){
-        this->ps->completeLoopWithVorticity(this->dt, *this->fs->cvorticity);
+        *this->tmp_vec_field = this->fs->cvorticity->get_cdata();
+        this->tmp_vec_field->ift();
+        std::unique_ptr<double[]> pdata;
+        pdata.reset(new double[ps->getLocalNbParticles()*3]);
+        this->ps->sample_compute_field(*this->tmp_vec_field, pdata.get());
+        this->ps->completeLoopWithVorticity(this->dt, pdata.get());
     }
     else{
         this->ps->completeLoop(this->dt);
diff --git a/bfps/cpp/particles/abstract_particles_system.hpp b/bfps/cpp/particles/abstract_particles_system.hpp
index 456a756381f341a1c59dc24b468f5afbc47562ab..859432c02a090390a2a304984fd64d39842fe532 100644
--- a/bfps/cpp/particles/abstract_particles_system.hpp
+++ b/bfps/cpp/particles/abstract_particles_system.hpp
@@ -18,6 +18,8 @@ public:
 
     virtual void compute_particles_inner() = 0;
 
+    virtual void enforce_unit_orientation() = 0;
+
     virtual void compute_particles_inner(const real_number particle_extra_rhs[]) = 0;
 
     virtual void move(const real_number dt) = 0;
diff --git a/bfps/cpp/particles/particles_inner_computer.hpp b/bfps/cpp/particles/particles_inner_computer.hpp
index b20abfdab437e008454de1102a1444cc8cbacc71..d58981e6204b64e5cff8b7f5e626ee08b590049d 100644
--- a/bfps/cpp/particles/particles_inner_computer.hpp
+++ b/bfps/cpp/particles/particles_inner_computer.hpp
@@ -14,7 +14,7 @@ public:
     }
 
     template <int size_particle_positions, int size_particle_rhs>
-    void compute_interaction(const partsize_t nb_particles, real_number pos_part[], real_number rhs_part[]) const{
+    void compute_interaction(const partsize_t nb_particles, const real_number pos_part[], real_number rhs_part[]) const{
         static_assert(size_particle_positions == 6, "This kernel works only with 6 values for one particle's position");
         static_assert(size_particle_rhs == 6, "This kernel works only with 6 values per particle's rhs");
 
@@ -24,34 +24,85 @@ public:
             rhs_part[idx_part*size_particle_rhs + IDX_X] += pos_part[idx_part*size_particle_positions + 3+IDX_X]*v0;
             rhs_part[idx_part*size_particle_rhs + IDX_Y] += pos_part[idx_part*size_particle_positions + 3+IDX_Y]*v0;
             rhs_part[idx_part*size_particle_rhs + IDX_Z] += pos_part[idx_part*size_particle_positions + 3+IDX_Z]*v0;
+        }
+    }
+
+    template <int size_particle_positions, int size_particle_rhs>
+    void enforce_unit_orientation(const partsize_t nb_particles, const real_number pos_part[], real_number rhs_part[]) const{
+        static_assert(size_particle_positions == 6, "This kernel works only with 6 values for one particle's position");
+        static_assert(size_particle_rhs == 6, "This kernel works only with 6 values per particle's rhs");
 
-            real_number alpha[3] = {0, 0, 0};
+        #pragma omp parallel for
+        for(partsize_t idx_part = 0 ; idx_part < nb_particles ; ++idx_part){
+            const partsize_t idx0 = idx_part*size_particle_positions + 3;
+            const partsize_t idx1 = idx_part*size_particle_rhs + 3;
+            //real_number alpha[3] = {0, 0, 0};
+            // check that orientation is unit vector:
+            real_number orientation_size = sqrt(
+                    pos_part[idx0+IDX_X]*pos_part[idx1+IDX_X] +
+                    pos_part[idx0+IDX_Y]*pos_part[idx1+IDX_Y] +
+                    pos_part[idx0+IDX_Z]*pos_part[idx1+IDX_Z]);
+            assert(orientation_size > 0.99);
+            assert(orientation_size < 1.01);
             // I call "rotation" to be the right hand side of the orientation part of the ODE
             // project rotation on orientation:
             real_number projection = (
-                    pos_part[idx_part*size_particle_positions + 3+IDX_X]*rhs_part[idx_part*size_particle_rhs + 3+IDX_X] +
-                    pos_part[idx_part*size_particle_positions + 3+IDX_Y]*rhs_part[idx_part*size_particle_rhs + 3+IDX_Y] +
-                    pos_part[idx_part*size_particle_positions + 3+IDX_Z]*rhs_part[idx_part*size_particle_rhs + 3+IDX_Z]);
-            // alpha is the vector that makes rotation perpendicular to orientation.
-            // note that the following three lines assume the current orientation is a unit vector.
-            alpha[IDX_X] = -pos_part[idx_part*size_particle_positions + 3+IDX_X]*projection;
-            alpha[IDX_Y] = -pos_part[idx_part*size_particle_positions + 3+IDX_Z]*projection;
-            alpha[IDX_Z] = -pos_part[idx_part*size_particle_positions + 3+IDX_Y]*projection;
-
-            // now add alpha term to orientation ODE right-hand side.
-            rhs_part[idx_part*size_particle_rhs + 3+IDX_X] += alpha[IDX_X];
-            rhs_part[idx_part*size_particle_rhs + 3+IDX_Y] += alpha[IDX_Y];
-            rhs_part[idx_part*size_particle_rhs + 3+IDX_Z] += alpha[IDX_Z];
+                    pos_part[idx0+IDX_X]*rhs_part[idx1+IDX_X] +
+                    pos_part[idx0+IDX_Y]*rhs_part[idx1+IDX_Y] +
+                    pos_part[idx0+IDX_Z]*rhs_part[idx1+IDX_Z]);
+            //// alpha is the vector that makes rotation perpendicular to orientation.
+            //// note that the following three lines assume the current orientation is a unit vector.
+            //alpha[IDX_X] = -;
+            //alpha[IDX_Y] = -;
+            //alpha[IDX_Z] = -;
+            //    DEBUG_MSG("projection = %g\n"
+            //              "pos_part[%d] = %g, pos_part[%d] = %g, pos_part[%d] = %g\n"
+            //              "rhs_part[%d] = %g, rhs_part[%d] = %g, rhs_part[%d] = %g\n",
+            //            projection,
+            //            IDX_X, pos_part[idx0 + IDX_X],
+            //            IDX_Y, pos_part[idx0 + IDX_Y],
+            //            IDX_Z, pos_part[idx0 + IDX_Z],
+            //            IDX_X, rhs_part[idx1 + IDX_X],
+            //            IDX_Y, rhs_part[idx1 + IDX_Y],
+            //            IDX_Z, rhs_part[idx1 + IDX_Z]);
+
+            // now remove parallel bit.
+            rhs_part[idx1+IDX_X] -= pos_part[idx0+IDX_X]*projection;
+            rhs_part[idx1+IDX_Y] -= pos_part[idx0+IDX_Y]*projection;
+            rhs_part[idx1+IDX_Z] -= pos_part[idx0+IDX_Z]*projection;
+
+            // compute dot product between orientation and orientation change
+            real_number dotproduct = (
+                    rhs_part[idx1 + IDX_X]*pos_part[idx0 + IDX_X] +
+                    rhs_part[idx1 + IDX_Y]*pos_part[idx0 + IDX_Y] +
+                    rhs_part[idx1 + IDX_Z]*pos_part[idx0 + IDX_Z]);
+            if (dotproduct > 0.1)
+            {
+                DEBUG_MSG("dotproduct = %g, projection = %g\n"
+                          "pos_part[%d] = %g, pos_part[%d] = %g, pos_part[%d] = %g\n"
+                          "rhs_part[%d] = %g, rhs_part[%d] = %g, rhs_part[%d] = %g\n",
+                        dotproduct,
+                        projection,
+                        IDX_X, pos_part[idx0 + IDX_X],
+                        IDX_Y, pos_part[idx0 + IDX_Y],
+                        IDX_Z, pos_part[idx0 + IDX_Z],
+                        IDX_X, rhs_part[idx1 + IDX_X],
+                        IDX_Y, rhs_part[idx1 + IDX_Y],
+                        IDX_Z, rhs_part[idx1 + IDX_Z]);
+            }
+            assert(dotproduct <= 0.1);
         }
     }
 
     template <int size_particle_positions, int size_particle_rhs, int size_particle_rhs_extra>
-    void compute_interaction_with_extra(const partsize_t nb_particles, real_number pos_part[], real_number rhs_part[],
+    void compute_interaction_with_extra(const partsize_t nb_particles, const real_number pos_part[], real_number rhs_part[],
                                         const real_number rhs_part_extra[]) const{
         static_assert(size_particle_rhs_extra == 3, "This kernel works only with 3 values for one particle's rhs extra");
 
+        // call plain compute_interaction first
         compute_interaction<size_particle_positions, size_particle_rhs>(nb_particles, pos_part, rhs_part);
 
+        // now add vorticity term
         #pragma omp parallel for
         for(partsize_t idx_part = 0 ; idx_part < nb_particles ; ++idx_part){
             // Cross product vorticity/orientation
diff --git a/bfps/cpp/particles/particles_inner_computer_empty.hpp b/bfps/cpp/particles/particles_inner_computer_empty.hpp
index 1bd3b1ecc1edbff73fa003de5bfd0932143c5b82..263d8b178ef64d034945442021700cfa702671d5 100644
--- a/bfps/cpp/particles/particles_inner_computer_empty.hpp
+++ b/bfps/cpp/particles/particles_inner_computer_empty.hpp
@@ -11,6 +11,10 @@ public:
     void compute_interaction(const partsize_t /*nb_particles*/, real_number /*pos_part*/[], real_number /*rhs_part*/[]) const{
     }
 
+    template <int size_particle_positions, int size_particle_rhs>
+    void enforce_unit_orientation(const partsize_t /*nb_particles*/, real_number /*pos_part*/[], real_number /*rhs_part*/[]) const{
+    }
+
     template <int size_particle_positions, int size_particle_rhs, int size_particle_rhs_extra>
     void compute_interaction_with_extra(const partsize_t /*nb_particles*/, real_number /*pos_part*/[], real_number /*rhs_part*/[],
                              const real_number /*rhs_part_extra*/[]) const{
diff --git a/bfps/cpp/particles/particles_system.hpp b/bfps/cpp/particles/particles_system.hpp
index 24bd228dc2a4b49fad492ec62335267b60cfbb02..a5d7878f49447f176d3766aed8c3d96f86dc38ec 100644
--- a/bfps/cpp/particles/particles_system.hpp
+++ b/bfps/cpp/particles/particles_system.hpp
@@ -162,6 +162,14 @@ public:
         }
     }
 
+    void enforce_unit_orientation() final {
+        if(computer_particules_inner.isEnable() == true){
+            TIMEZONE("particles_system::enforce_unit_orientation");
+            computer_particules_inner.template enforce_unit_orientation<size_particle_positions, size_particle_rhs>(
+                            my_nb_particles, my_particles_positions.get(), my_particles_rhs.front().get());
+        }
+    }
+
     void compute_particles_inner(const real_number particle_extra_rhs[]) final {
         if(computer_particules_inner.isEnable() == true){
             TIMEZONE("particles_system::compute_particles_inner");
@@ -252,6 +260,7 @@ public:
         compute();
         compute_p2p();
         compute_particles_inner();
+        enforce_unit_orientation();
         move(dt);
         redistribute();
         inc_step_idx();
@@ -264,6 +273,7 @@ public:
         compute();
         compute_p2p();
         compute_particles_inner(particle_extra_rhs);
+        enforce_unit_orientation();
         move(dt);
         redistribute();
         inc_step_idx();
diff --git a/bfps/test/test_particles.py b/bfps/test/test_particles.py
index 79595a23a89dd1ad22e0621f28ca69f0f87a242c..c3d4c41507da778005c52caca768f871581d7493 100644
--- a/bfps/test/test_particles.py
+++ b/bfps/test/test_particles.py
@@ -88,30 +88,23 @@ def main():
                                           np.maximum(np.abs(x),
                                                      np.abs(s[..., 3:])))))
             assert(distance < 1e-14)
-        # print movement
-        x0 = pf['tracers0/position/0'].value
-        x1 = pf['tracers0/position/32'].value
-        # compute distance travelled by first particle
-        deltax = x1[0] - x0[0]
-        print('distance travelled by first particle is ', np.sum(deltax**2)**.5)
-        ## code relevant when velocity field is 0 everywhere.
-        ## we check to see what happens to the orientation of the particles
-        ## show a histogram of the orientations
-        #f = plt.figure()
-        #a = f.add_subplot(111)
-        #for iteration in range(0, niterations*njobs+1, niterations//4):
-        #    x = pf['tracers0/orientation/{0}'.format(iteration)].value
-        #    print(x)
-        #    hist, bins = np.histogram(
-        #            x.flatten(),
-        #            bins = 100)
-        #    bb = (bins[:-1] + bins[1:])/2
-        #    pp = hist.astype(np.float) / (np.sum(hist) * (bb[1] - bb[0]))
-        #    a.plot(bb, pp, label = '{0}'.format(iteration))
-        #a.legend(loc = 'best')
-        #f.tight_layout()
-        #f.savefig('full_orientation_histogram.pdf')
-        #plt.close(f)
+        # code relevant when velocity field is 0 everywhere.
+        # we check to see what happens to the orientation of the particles
+        # show a histogram of the orientations
+        f = plt.figure()
+        a = f.add_subplot(111)
+        for iteration in range(0, niterations*njobs+1, niterations//4):
+            x = pf['tracers0/orientation/{0}'.format(iteration)].value
+            hist, bins = np.histogram(
+                    x.flatten(),
+                    bins = 100)
+            bb = (bins[:-1] + bins[1:])/2
+            pp = hist.astype(np.float) / (np.sum(hist) * (bb[1] - bb[0]))
+            a.plot(bb, pp, label = '{0}'.format(iteration))
+        a.legend(loc = 'best')
+        f.tight_layout()
+        f.savefig('full_orientation_histogram.pdf')
+        plt.close(f)
     return None
 
 if __name__ == '__main__':
diff --git a/setup.py b/setup.py
index 27a2993f65a36bfc3b9213fe57895ac27edb7864..34b9e16a1c7f5945513480d2b7d884c2d488ac91 100644
--- a/setup.py
+++ b/setup.py
@@ -88,7 +88,8 @@ print('This is bfps version ' + VERSION)
 
 
 ### lists of files and MANIFEST.in
-src_file_list = ['full_code/joint_acc_vel_stats',
+src_file_list = ['full_code/NSVEparticlesP2P',
+                 'full_code/joint_acc_vel_stats',
                  'full_code/test',
                  'full_code/filter_test',
                  'full_code/field_test',
@@ -128,8 +129,7 @@ src_file_list = ['full_code/joint_acc_vel_stats',
                  'spline_n10',
                  'Lagrange_polys',
                  'scope_timer',
-                 'full_code/NSVEparticles',
-                 'full_code/NSVEparticlesP2P']
+                 'full_code/NSVEparticles']
 
 particle_headers = [
         'cpp/particles/abstract_particles_input.hpp',