diff --git a/bfps/NSVorticityEquation.py b/bfps/NSVorticityEquation.py
new file mode 100644
index 0000000000000000000000000000000000000000..11ea51d5d072a6b28f288ade949c341f2b2ad47f
--- /dev/null
+++ b/bfps/NSVorticityEquation.py
@@ -0,0 +1,605 @@
+#######################################################################
+#                                                                     #
+#  Copyright 2015 Max Planck Institute                                #
+#                 for Dynamics and Self-Organization                  #
+#                                                                     #
+#  This file is part of bfps.                                         #
+#                                                                     #
+#  bfps is free software: you can redistribute it and/or modify       #
+#  it under the terms of the GNU General Public License as published  #
+#  by the Free Software Foundation, either version 3 of the License,  #
+#  or (at your option) any later version.                             #
+#                                                                     #
+#  bfps is distributed in the hope that it will be useful,            #
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of     #
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      #
+#  GNU General Public License for more details.                       #
+#                                                                     #
+#  You should have received a copy of the GNU General Public License  #
+#  along with bfps.  If not, see <http://www.gnu.org/licenses/>       #
+#                                                                     #
+# Contact: Cristian.Lalescu@ds.mpg.de                                 #
+#                                                                     #
+#######################################################################
+
+
+
+import sys
+import os
+import numpy as np
+import h5py
+import argparse
+
+import bfps
+import bfps.tools
+from bfps._code import _code
+from bfps._fluid_base import _fluid_particle_base
+
+class NSVorticityEquation(_fluid_particle_base):
+    def __init__(
+            self,
+            name = 'NSVE-v' + bfps.__version__,
+            work_dir = './',
+            simname = 'test',
+            fluid_precision = 'single',
+            fftw_plan_rigor = 'FFTW_MEASURE',
+            use_fftw_wisdom = True):
+        self.fftw_plan_rigor = fftw_plan_rigor
+        _fluid_particle_base.__init__(
+                self,
+                name = name + '-' + fluid_precision,
+                work_dir = work_dir,
+                simname = simname,
+                dtype = fluid_precision,
+                use_fftw_wisdom = use_fftw_wisdom)
+        self.parameters['nu'] = 0.1
+        self.parameters['fmode'] = 1
+        self.parameters['famplitude'] = 0.5
+        self.parameters['fk0'] = 2.0
+        self.parameters['fk1'] = 4.0
+        self.parameters['forcing_type'] = 'linear'
+        self.parameters['histogram_bins'] = 256
+        self.parameters['max_velocity_estimate'] = 1.0
+        self.parameters['max_vorticity_estimate'] = 1.0
+        self.file_datasets_grow = """
+                //begincpp
+                hid_t group;
+                group = H5Gopen(stat_file, "/statistics", H5P_DEFAULT);
+                H5Ovisit(group, H5_INDEX_NAME, H5_ITER_NATIVE, grow_statistics_dataset, NULL);
+                H5Gclose(group);
+                //endcpp
+                """
+        self.style = {}
+        self.statistics = {}
+        self.fluid_output = 'fs->write(\'v\', \'c\');\n'
+        # vorticity_equation specific things
+        self.includes += '#include "vorticity_equation.hpp"\n'
+        self.store_kspace = """
+                //begincpp
+                if (myrank == 0 && iteration == 0)
+                {
+                    DEBUG_MSG("about to store kspace\\n");
+                    TIMEZONE("fluid_base::store_kspace");
+                    hsize_t dims[4];
+                    hid_t space, dset;
+                    // store kspace information
+                    hid_t parameter_file = stat_file;
+                    //char fname[256];
+                    //sprintf(fname, "%s.h5", simname);
+                    //parameter_file = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT);
+                    dset = H5Dopen(parameter_file, "/kspace/kshell", H5P_DEFAULT);
+                    space = H5Dget_space(dset);
+                    H5Sget_simple_extent_dims(space, dims, NULL);
+                    H5Sclose(space);
+                    if (fs->kk->nshells != dims[0])
+                    {
+                        DEBUG_MSG(
+                            "ERROR: computed nshells %d not equal to data file nshells %d\\n",
+                            fs->kk->nshells, dims[0]);
+                    }
+                    H5Dwrite(dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &fs->kk->kshell.front());
+                    H5Dclose(dset);
+                    dset = H5Dopen(parameter_file, "/kspace/nshell", H5P_DEFAULT);
+                    H5Dwrite(dset, H5T_NATIVE_INT64, H5S_ALL, H5S_ALL, H5P_DEFAULT, &fs->kk->nshell.front());
+                    H5Dclose(dset);
+                    dset = H5Dopen(parameter_file, "/kspace/kM", H5P_DEFAULT);
+                    H5Dwrite(dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &fs->kk->kM);
+                    H5Dclose(dset);
+                    dset = H5Dopen(parameter_file, "/kspace/dk", H5P_DEFAULT);
+                    H5Dwrite(dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &fs->kk->dk);
+                    H5Dclose(dset);
+                    //H5Fclose(parameter_file);
+                    DEBUG_MSG("finished storing kspace\\n");
+                }
+                //endcpp
+                """
+        return None
+    def create_stat_output(
+            self,
+            dset_name,
+            data_buffer,
+            data_type = 'H5T_NATIVE_DOUBLE',
+            size_setup = None,
+            close_spaces = True):
+        new_stat_output_txt = 'Cdset = H5Dopen(stat_file, "{0}", H5P_DEFAULT);\n'.format(dset_name)
+        if not type(size_setup) == type(None):
+            new_stat_output_txt += (
+                    size_setup +
+                    'wspace = H5Dget_space(Cdset);\n' +
+                    'ndims = H5Sget_simple_extent_dims(wspace, dims, NULL);\n' +
+                    'mspace = H5Screate_simple(ndims, count, NULL);\n' +
+                    'H5Sselect_hyperslab(wspace, H5S_SELECT_SET, offset, NULL, count, NULL);\n')
+        new_stat_output_txt += ('H5Dwrite(Cdset, {0}, mspace, wspace, H5P_DEFAULT, {1});\n' +
+                                'H5Dclose(Cdset);\n').format(data_type, data_buffer)
+        if close_spaces:
+            new_stat_output_txt += ('H5Sclose(mspace);\n' +
+                                    'H5Sclose(wspace);\n')
+        return new_stat_output_txt
+    def write_fluid_stats(self):
+        self.fluid_includes += '#include <cmath>\n'
+        self.fluid_includes += '#include "fftw_tools.hpp"\n'
+        self.stat_src += """
+                //begincpp
+                DEBUG_MSG("inside stat src\\n");
+                hid_t stat_group;
+                if (myrank == 0)
+                    stat_group = H5Gopen(stat_file, "statistics", H5P_DEFAULT);
+                fs->compute_velocity(fs->cvorticity);
+                *tmp_vec_field = fs->cvelocity->get_cdata();
+                tmp_vec_field->compute_stats(
+                    fs->kk,
+                    stat_group,
+                    "velocity",
+                    fs->iteration / niter_stat,
+                    max_velocity_estimate/sqrt(3));
+                DEBUG_MSG("after stats for %d\\n", fs->iteration);
+                //endcpp
+                """
+        self.stat_src += """
+                //begincpp
+                *tmp_vec_field = fs->cvorticity->get_cdata();
+                tmp_vec_field->compute_stats(
+                    fs->kk,
+                    stat_group,
+                    "vorticity",
+                    fs->iteration / niter_stat,
+                    max_vorticity_estimate/sqrt(3));
+                DEBUG_MSG("after vort stats for %d\\n", fs->iteration);
+                //endcpp
+                """
+        self.stat_src += """
+                //begincpp
+                if (myrank == 0)
+                    H5Gclose(stat_group);
+                if (fs->cd->myrank == 0)
+                {{
+                    hid_t Cdset, wspace, mspace;
+                    int ndims;
+                    hsize_t count[4], offset[4], dims[4];
+                    offset[0] = fs->iteration/niter_stat;
+                    offset[1] = 0;
+                    offset[2] = 0;
+                    offset[3] = 0;
+                //endcpp
+                """.format(self.C_dtype)
+        if self.dtype == np.float32:
+            field_H5T = 'H5T_NATIVE_FLOAT'
+        elif self.dtype == np.float64:
+            field_H5T = 'H5T_NATIVE_DOUBLE'
+        self.stat_src += self.create_stat_output(
+                '/statistics/xlines/velocity',
+                'fs->rvelocity->get_rdata()',
+                data_type = field_H5T,
+                size_setup = """
+                    count[0] = 1;
+                    count[1] = nx;
+                    count[2] = 3;
+                    """,
+                close_spaces = False)
+        self.stat_src += self.create_stat_output(
+                '/statistics/xlines/vorticity',
+                'fs->rvorticity->get_rdata()',
+                data_type = field_H5T)
+        self.stat_src += '}\n'
+        return None
+    def fill_up_fluid_code(self):
+        self.fluid_includes += '#include <cstring>\n'
+        self.fluid_variables += (
+                'vorticity_equation<{0}, FFTW> *fs;\n'.format(self.C_dtype) +
+                'field<{0}, FFTW, THREE> *tmp_vec_field;\n'.format(self.C_dtype) +
+                'field<{0}, FFTW, ONE> *tmp_scal_field;\n'.format(self.C_dtype))
+        self.fluid_definitions += """
+                    typedef struct {{
+                        {0} re;
+                        {0} im;
+                    }} tmp_complex_type;
+                    """.format(self.C_dtype)
+        self.write_fluid_stats()
+        if self.dtype == np.float32:
+            field_H5T = 'H5T_NATIVE_FLOAT'
+        elif self.dtype == np.float64:
+            field_H5T = 'H5T_NATIVE_DOUBLE'
+        self.fluid_start += """
+                //begincpp
+                char fname[512];
+                DEBUG_MSG("about to allocate vorticity equation\\n");
+                fs = new vorticity_equation<{0}, FFTW>(
+                        simname,
+                        nx, ny, nz,
+                        dkx, dky, dkz,
+                        {1});
+                tmp_vec_field = new field<{0}, FFTW, THREE>(
+                        nx, ny, nz,
+                        MPI_COMM_WORLD,
+                        {1});
+                tmp_scal_field = new field<{0}, FFTW, ONE>(
+                        nx, ny, nz,
+                        MPI_COMM_WORLD,
+                        {1});
+                DEBUG_MSG("finished allocating stuff\\n");
+                fs->nu = nu;
+                fs->fmode = fmode;
+                fs->famplitude = famplitude;
+                fs->fk0 = fk0;
+                fs->fk1 = fk1;
+                strncpy(fs->forcing_type, forcing_type, 128);
+                fs->iteration = iteration;
+                DEBUG_MSG("before reading\\n");
+                fs->read('v', 'c');
+                DEBUG_MSG("after reading\\n");
+                //endcpp
+                """.format(self.C_dtype, self.fftw_plan_rigor, field_H5T)
+        self.fluid_start += self.store_kspace
+        self.fluid_loop = ('fs->step(dt);\n' +
+                           'DEBUG_MSG("this is step %d\\n", fs->iteration);\n')
+        self.fluid_loop += ('if (fs->iteration % niter_out == 0)\n{\n' +
+                            self.fluid_output + '\n}\n')
+        self.fluid_end = ('if (fs->iteration % niter_out != 0)\n{\n' +
+                          self.fluid_output + '\n}\n' +
+                          'delete fs;\n' +
+                          'delete tmp_vec_field;\n' +
+                          'delete tmp_scal_field;\n')
+        return None
+    def get_postprocess_file_name(self):
+        return os.path.join(self.work_dir, self.simname + '_postprocess.h5')
+    def get_postprocess_file(self):
+        return h5py.File(self.get_postprocess_file_name(), 'r')
+    def compute_statistics(self, iter0 = 0, iter1 = None):
+        """Run basic postprocessing on raw data.
+        The energy spectrum :math:`E(t, k)` and the enstrophy spectrum
+        :math:`\\frac{1}{2}\omega^2(t, k)` are computed from the
+
+        .. math::
+
+            \sum_{k \\leq \\|\\mathbf{k}\\| \\leq k+dk}\\hat{u_i} \\hat{u_j}^*, \\hskip .5cm
+            \sum_{k \\leq \\|\\mathbf{k}\\| \\leq k+dk}\\hat{\omega_i} \\hat{\\omega_j}^*
+
+        tensors, and the enstrophy spectrum is also used to
+        compute the dissipation :math:`\\varepsilon(t)`.
+        These basic quantities are stored in a newly created HDF5 file,
+        ``simname_postprocess.h5``.
+        """
+        if len(list(self.statistics.keys())) > 0:
+            return None
+        self.read_parameters()
+        with self.get_data_file() as data_file:
+            if 'moments' not in data_file['statistics'].keys():
+                return None
+            iter0 = min((data_file['statistics/moments/velocity'].shape[0] *
+                         self.parameters['niter_stat']-1),
+                        iter0)
+            if type(iter1) == type(None):
+                iter1 = data_file['iteration'].value
+            else:
+                iter1 = min(data_file['iteration'].value, iter1)
+            ii0 = iter0 // self.parameters['niter_stat']
+            ii1 = iter1 // self.parameters['niter_stat']
+            self.statistics['kshell'] = data_file['kspace/kshell'].value
+            self.statistics['kM'] = data_file['kspace/kM'].value
+            self.statistics['dk'] = data_file['kspace/dk'].value
+            computation_needed = True
+            pp_file = h5py.File(self.get_postprocess_file_name(), 'a')
+            if 'ii0' in pp_file.keys():
+                computation_needed =  not (ii0 == pp_file['ii0'].value and
+                                           ii1 == pp_file['ii1'].value)
+                if computation_needed:
+                    for k in pp_file.keys():
+                        del pp_file[k]
+            if computation_needed:
+                pp_file['iter0'] = iter0
+                pp_file['iter1'] = iter1
+                pp_file['ii0'] = ii0
+                pp_file['ii1'] = ii1
+                pp_file['t'] = (self.parameters['dt']*
+                                self.parameters['niter_stat']*
+                                (np.arange(ii0, ii1+1).astype(np.float)))
+                pp_file['energy(t, k)'] = (
+                    data_file['statistics/spectra/velocity_velocity'][ii0:ii1+1, :, 0, 0] +
+                    data_file['statistics/spectra/velocity_velocity'][ii0:ii1+1, :, 1, 1] +
+                    data_file['statistics/spectra/velocity_velocity'][ii0:ii1+1, :, 2, 2])/2
+                pp_file['enstrophy(t, k)'] = (
+                    data_file['statistics/spectra/vorticity_vorticity'][ii0:ii1+1, :, 0, 0] +
+                    data_file['statistics/spectra/vorticity_vorticity'][ii0:ii1+1, :, 1, 1] +
+                    data_file['statistics/spectra/vorticity_vorticity'][ii0:ii1+1, :, 2, 2])/2
+                pp_file['vel_max(t)'] = data_file['statistics/moments/velocity']  [ii0:ii1+1, 9, 3]
+                pp_file['renergy(t)'] = data_file['statistics/moments/velocity'][ii0:ii1+1, 2, 3]/2
+            for k in ['t',
+                      'energy(t, k)',
+                      'enstrophy(t, k)',
+                      'vel_max(t)',
+                      'renergy(t)']:
+                if k in pp_file.keys():
+                    self.statistics[k] = pp_file[k].value
+            self.compute_time_averages()
+        return None
+    def compute_time_averages(self):
+        """Compute easy stats.
+
+        Further computation of statistics based on the contents of
+        ``simname_postprocess.h5``.
+        Standard quantities are as follows
+        (consistent with [Ishihara]_):
+
+        .. math::
+
+            U_{\\textrm{int}}(t) = \\sqrt{\\frac{2E(t)}{3}}, \\hskip .5cm
+            L_{\\textrm{int}}(t) = \\frac{\pi}{2U_{int}^2(t)} \\int \\frac{dk}{k} E(t, k), \\hskip .5cm
+            T_{\\textrm{int}}(t) =
+            \\frac{L_{\\textrm{int}}(t)}{U_{\\textrm{int}}(t)}
+
+            \\eta_K = \\left(\\frac{\\nu^3}{\\varepsilon}\\right)^{1/4}, \\hskip .5cm
+            \\tau_K = \\left(\\frac{\\nu}{\\varepsilon}\\right)^{1/2}, \\hskip .5cm
+            \\lambda = \\sqrt{\\frac{15 \\nu U_{\\textrm{int}}^2}{\\varepsilon}}
+
+            Re = \\frac{U_{\\textrm{int}} L_{\\textrm{int}}}{\\nu}, \\hskip
+            .5cm
+            R_{\\lambda} = \\frac{U_{\\textrm{int}} \\lambda}{\\nu}
+
+        .. [Ishihara] T. Ishihara et al,
+                      *Small-scale statistics in high-resolution direct numerical
+                      simulation of turbulence: Reynolds number dependence of
+                      one-point velocity gradient statistics*.
+                      J. Fluid Mech.,
+                      **592**, 335-366, 2007
+        """
+        for key in ['energy', 'enstrophy']:
+            self.statistics[key + '(t)'] = (self.statistics['dk'] *
+                                            np.sum(self.statistics[key + '(t, k)'], axis = 1))
+        self.statistics['Uint(t)'] = np.sqrt(2*self.statistics['energy(t)'] / 3)
+        self.statistics['Lint(t)'] = ((self.statistics['dk']*np.pi /
+                                       (2*self.statistics['Uint(t)']**2)) *
+                                      np.nansum(self.statistics['energy(t, k)'] /
+                                                self.statistics['kshell'][None, :], axis = 1))
+        for key in ['energy',
+                    'enstrophy',
+                    'vel_max',
+                    'Uint',
+                    'Lint']:
+            if key + '(t)' in self.statistics.keys():
+                self.statistics[key] = np.average(self.statistics[key + '(t)'], axis = 0)
+        for suffix in ['', '(t)']:
+            self.statistics['diss'    + suffix] = (self.parameters['nu'] *
+                                                   self.statistics['enstrophy' + suffix]*2)
+            self.statistics['etaK'    + suffix] = (self.parameters['nu']**3 /
+                                                   self.statistics['diss' + suffix])**.25
+            self.statistics['tauK'    + suffix] =  (self.parameters['nu'] /
+                                                    self.statistics['diss' + suffix])**.5
+            self.statistics['Re' + suffix] = (self.statistics['Uint' + suffix] *
+                                              self.statistics['Lint' + suffix] /
+                                              self.parameters['nu'])
+            self.statistics['lambda' + suffix] = (15 * self.parameters['nu'] *
+                                                  self.statistics['Uint' + suffix]**2 /
+                                                  self.statistics['diss' + suffix])**.5
+            self.statistics['Rlambda' + suffix] = (self.statistics['Uint' + suffix] *
+                                                   self.statistics['lambda' + suffix] /
+                                                   self.parameters['nu'])
+            self.statistics['kMeta' + suffix] = (self.statistics['kM'] *
+                                                 self.statistics['etaK' + suffix])
+            if self.parameters['dealias_type'] == 1:
+                self.statistics['kMeta' + suffix] *= 0.8
+        self.statistics['Tint'] = self.statistics['Lint'] / self.statistics['Uint']
+        self.statistics['Taylor_microscale'] = self.statistics['lambda']
+        return None
+    def set_plt_style(
+            self,
+            style = {'dashes' : (None, None)}):
+        self.style.update(style)
+        return None
+    def read_cfield(
+            self,
+            field_name = 'vorticity',
+            iteration = 0):
+        """read the Fourier representation of a vector field.
+
+        Read the binary file containing iteration ``iteration`` of the
+        field ``field_name``, and return it as a properly shaped
+        ``numpy.memmap`` object.
+        """
+        return np.memmap(
+                os.path.join(self.work_dir,
+                             self.simname + '_{0}_i{1:0>5x}'.format('c' + field_name, iteration)),
+                dtype = self.ctype,
+                mode = 'r',
+                shape = (self.parameters['ny'],
+                         self.parameters['nz'],
+                         self.parameters['nx']//2+1,
+                         3))
+    def write_par(
+            self,
+            iter0 = 0):
+        _fluid_particle_base.write_par(self, iter0 = iter0)
+        with h5py.File(self.get_data_file_name(), 'r+') as ofile:
+            kspace = self.get_kspace()
+            nshells = kspace['nshell'].shape[0]
+            vec_stat_datasets = ['velocity', 'vorticity']
+            scal_stat_datasets = []
+            for k in vec_stat_datasets:
+                time_chunk = 2**20//(8*3*self.parameters['nx']) # FIXME: use proper size of self.dtype
+                time_chunk = max(time_chunk, 1)
+                ofile.create_dataset('statistics/xlines/' + k,
+                                     (1, self.parameters['nx'], 3),
+                                     chunks = (time_chunk, self.parameters['nx'], 3),
+                                     maxshape = (None, self.parameters['nx'], 3),
+                                     dtype = self.dtype)
+            for k in vec_stat_datasets:
+                time_chunk = 2**20//(8*3*3*nshells)
+                time_chunk = max(time_chunk, 1)
+                ofile.create_dataset('statistics/spectra/' + k + '_' + k,
+                                     (1, nshells, 3, 3),
+                                     chunks = (time_chunk, nshells, 3, 3),
+                                     maxshape = (None, nshells, 3, 3),
+                                     dtype = np.float64)
+                time_chunk = 2**20//(8*4*10)
+                time_chunk = max(time_chunk, 1)
+                a = ofile.create_dataset('statistics/moments/' + k,
+                                     (1, 10, 4),
+                                     chunks = (time_chunk, 10, 4),
+                                     maxshape = (None, 10, 4),
+                                     dtype = np.float64)
+                time_chunk = 2**20//(8*4*self.parameters['histogram_bins'])
+                time_chunk = max(time_chunk, 1)
+                ofile.create_dataset('statistics/histograms/' + k,
+                                     (1,
+                                      self.parameters['histogram_bins'],
+                                      4),
+                                     chunks = (time_chunk,
+                                               self.parameters['histogram_bins'],
+                                               4),
+                                     maxshape = (None,
+                                                 self.parameters['histogram_bins'],
+                                                 4),
+                                     dtype = np.int64)
+        return None
+    def specific_parser_arguments(
+            self,
+            parser):
+        _fluid_particle_base.specific_parser_arguments(self, parser)
+        parser.add_argument(
+                '--src-wd',
+                type = str,
+                dest = 'src_work_dir',
+                default = '')
+        parser.add_argument(
+                '--src-simname',
+                type = str,
+                dest = 'src_simname',
+                default = '')
+        parser.add_argument(
+                '--src-iteration',
+                type = int,
+                dest = 'src_iteration',
+                default = 0)
+        parser.add_argument(
+               '--njobs',
+               type = int, dest = 'njobs',
+               default = 1)
+        parser.add_argument(
+               '--kMeta',
+               type = float,
+               dest = 'kMeta',
+               default = 2.0)
+        parser.add_argument(
+               '--dtfactor',
+               type = float,
+               dest = 'dtfactor',
+               default = 0.5,
+               help = 'dt is computed as DTFACTOR / N')
+        return None
+    def prepare_launch(
+            self,
+            args = []):
+        """Set up reasonable parameters.
+
+        With the default Lundgren forcing applied in the band [2, 4],
+        we can estimate the dissipation, therefore we can estimate
+        :math:`k_M \\eta_K` and constrain the viscosity.
+
+        In brief, the command line parameter :math:`k_M \\eta_K` is
+        used in the following formula for :math:`\\nu` (:math:`N` is the
+        number of real space grid points per coordinate):
+
+        .. math::
+
+            \\nu = \\left(\\frac{2 k_M \\eta_K}{N} \\right)^{4/3}
+
+        With this choice, the average dissipation :math:`\\varepsilon`
+        will be close to 0.4, and the integral scale velocity will be
+        close to 0.77, yielding the approximate value for the Taylor
+        microscale and corresponding Reynolds number:
+
+        .. math::
+
+            \\lambda \\approx 4.75\\left(\\frac{2 k_M \\eta_K}{N} \\right)^{4/6}, \\hskip .5in
+            R_\\lambda \\approx 3.7 \\left(\\frac{N}{2 k_M \\eta_K} \\right)^{4/6}
+
+        """
+        opt = _code.prepare_launch(self, args = args)
+        self.parameters['nu'] = (opt.kMeta * 2 / opt.n)**(4./3)
+        self.parameters['dt'] = (opt.dtfactor / opt.n)
+        # custom famplitude for 288 and 576
+        if opt.n == 288:
+            self.parameters['famplitude'] = 0.45
+        elif opt.n == 576:
+            self.parameters['famplitude'] = 0.47
+        if ((self.parameters['niter_todo'] % self.parameters['niter_out']) != 0):
+            self.parameters['niter_out'] = self.parameters['niter_todo']
+        if len(opt.src_work_dir) == 0:
+            opt.src_work_dir = os.path.realpath(opt.work_dir)
+        self.pars_from_namespace(opt)
+        return opt
+    def launch(
+            self,
+            args = [],
+            noparticles = False,
+            **kwargs):
+        opt = self.prepare_launch(args = args)
+        self.fill_up_fluid_code()
+        if noparticles:
+            opt.nparticles = 0
+        elif type(opt.nparticles) == int:
+            if opt.nparticles > 0:
+                self.name += '-particles'
+                self.add_3D_rFFTW_field(
+                        name = 'rFFTW_acc')
+                self.add_interpolator(
+                        name = 'cubic_spline',
+                        neighbours = opt.neighbours,
+                        smoothness = opt.smoothness,
+                        class_name = 'rFFTW_interpolator')
+                self.add_particles(
+                        integration_steps = [4],
+                        interpolator = 'cubic_spline',
+                        acc_name = 'rFFTW_acc',
+                        class_name = 'rFFTW_distributed_particles')
+        self.finalize_code()
+        self.launch_jobs(opt = opt)
+        return None
+    def launch_jobs(
+            self,
+            opt = None):
+        if not os.path.exists(os.path.join(self.work_dir, self.simname + '.h5')):
+            self.write_par()
+            init_condition_file = os.path.join(
+                    self.work_dir,
+                    self.simname + '_cvorticity_i{0:0>5x}'.format(0))
+            if not os.path.exists(init_condition_file):
+                if len(opt.src_simname) > 0:
+                    src_file = os.path.join(
+                            os.path.realpath(opt.src_work_dir),
+                            opt.src_simname + '_cvorticity_i{0:0>5x}'.format(opt.src_iteration))
+                    os.symlink(src_file, init_condition_file)
+                else:
+                   self.generate_vector_field(
+                           write_to_file = True,
+                           spectra_slope = 2.0,
+                           amplitude = 0.05)
+        self.run(
+                ncpu = opt.ncpu,
+                njobs = opt.njobs,
+                hours = opt.minutes // 60,
+                minutes = opt.minutes % 60)
+        return None
+
+if __name__ == '__main__':
+    pass
+
diff --git a/bfps/__main__.py b/bfps/__main__.py
index a26d84d0e918cebe1a9351ca20b5249418d6a3c6..9db5e350340e67dfe99c5a40e3027b489399a42e 100644
--- a/bfps/__main__.py
+++ b/bfps/__main__.py
@@ -29,6 +29,7 @@ import argparse
 
 import bfps
 from .NavierStokes import NavierStokes
+from .NSVorticityEquation import NSVorticityEquation
 from .FluidResize import FluidResize
 from .FluidConvert import FluidConvert
 from .NSManyParticles import NSManyParticles
@@ -45,6 +46,12 @@ def main():
                  'NS',
                  'NS-single',
                  'NS-double']
+    NSVEoptions = ['NSVorticityEquation',
+                 'NSVorticityEquation-single',
+                 'NSVorticityEquation-double',
+                 'NSVE',
+                 'NSVE-single',
+                 'NSVE-double']
     FRoptions = ['FluidResize',
                  'FluidResize-single',
                  'FluidResize-double',
@@ -57,7 +64,7 @@ def main():
                'NSManyParticles-double']
     parser.add_argument(
             'base_class',
-            choices = NSoptions + FRoptions + FCoptions + NSMPopt,
+            choices = NSoptions + NSVEoptions + FRoptions + FCoptions + NSMPopt,
             type = str)
     # first option is the choice of base class or -h or -v
     # all other options are passed on to the base_class instance
@@ -70,6 +77,8 @@ def main():
         precision = 'single'
     if opt.base_class in NSoptions:
         base_class = NavierStokes
+    if opt.base_class in NSVEoptions:
+        base_class = NSVorticityEquation
     elif opt.base_class in FRoptions:
         base_class = FluidResize
     elif opt.base_class in FCoptions:
diff --git a/bfps/cpp/vorticity_equation.cpp b/bfps/cpp/vorticity_equation.cpp
index 9e65faa7716545e6bfaef3bab79a8163e70925d7..5ad266c47fb42fc4c134ca87322b8085f0a7440d 100644
--- a/bfps/cpp/vorticity_equation.cpp
+++ b/bfps/cpp/vorticity_equation.cpp
@@ -129,6 +129,7 @@ template <class rnumber,
 void vorticity_equation<rnumber, be>::compute_vorticity()
 {
     TIMEZONE("vorticity_equation::compute_vorticity");
+    this->cvorticity->real_space_representation = false;
     this->kk->CLOOP_K2(
                 [&](ptrdiff_t cindex,
                     ptrdiff_t xindex,