diff --git a/bfps/cpp/field.cpp b/bfps/cpp/field.cpp
index 2af8bded1af436d93dfc7fb09e2727d2f30a0bdf..a456b8a99b0989d4456f13907f91be0750b0f824 100644
--- a/bfps/cpp/field.cpp
+++ b/bfps/cpp/field.cpp
@@ -30,83 +30,7 @@
 #include "field.hpp"
 #include "scope_timer.hpp"
 
-template <field_components fc>
-field_layout<fc>::field_layout(
-        const hsize_t *SIZES,
-        const hsize_t *SUBSIZES,
-        const hsize_t *STARTS,
-        const MPI_Comm COMM_TO_USE)
-{
-    TIMEZONE("field_layout::field_layout");
-    this->comm = COMM_TO_USE;
-    MPI_Comm_rank(this->comm, &this->myrank);
-    MPI_Comm_size(this->comm, &this->nprocs);
-
-    std::copy(SIZES, SIZES + 3, this->sizes);
-    std::copy(SUBSIZES, SUBSIZES + 3, this->subsizes);
-    std::copy(STARTS, STARTS + 3, this->starts);
-    if (fc == THREE || fc == THREExTHREE)
-    {
-        this->sizes[3] = 3;
-        this->subsizes[3] = 3;
-        this->starts[3] = 0;
-    }
-    if (fc == THREExTHREE)
-    {
-        this->sizes[4] = 3;
-        this->subsizes[4] = 3;
-        this->starts[4] = 0;
-    }
-    this->local_size = 1;
-    this->full_size = 1;
-    for (unsigned int i=0; i<ndim(fc); i++)
-    {
-        this->local_size *= this->subsizes[i];
-        this->full_size *= this->sizes[i];
-    }
 
-    /*field will at most be distributed in 2D*/
-    this->rank.resize(2);
-    this->all_start.resize(2);
-    this->all_size.resize(2);
-    for (int i=0; i<2; i++)
-    {
-        this->rank[i].resize(this->sizes[i]);
-        std::vector<int> local_rank;
-        local_rank.resize(this->sizes[i], 0);
-        for (unsigned int ii=this->starts[i]; ii<this->starts[i]+this->subsizes[i]; ii++)
-            local_rank[ii] = this->myrank;
-        MPI_Allreduce(
-                &local_rank.front(),
-                &this->rank[i].front(),
-                this->sizes[i],
-                MPI_INT,
-                MPI_SUM,
-                this->comm);
-        this->all_start[i].resize(this->nprocs);
-        std::vector<int> local_start;
-        local_start.resize(this->nprocs, 0);
-        local_start[this->myrank] = this->starts[i];
-        MPI_Allreduce(
-                &local_start.front(),
-                &this->all_start[i].front(),
-                this->nprocs,
-                MPI_INT,
-                MPI_SUM,
-                this->comm);
-        this->all_size[i].resize(this->nprocs);
-        std::vector<int> local_subsize;
-        local_subsize.resize(this->nprocs, 0);
-        local_subsize[this->myrank] = this->subsizes[i];
-        MPI_Allreduce(
-                &local_subsize.front(),
-                &this->all_size[i].front(),
-                this->nprocs,
-                MPI_INT,
-                MPI_SUM,
-                this->comm);
-    }
-}
 
 template <typename rnumber,
           field_backend be,
diff --git a/bfps/cpp/field.hpp b/bfps/cpp/field.hpp
index 871274ca7dc0afc5b819da7b906d1169f8844605..a1e38d03f766506ff3af980b3c8c0ec2f5781982 100644
--- a/bfps/cpp/field.hpp
+++ b/bfps/cpp/field.hpp
@@ -28,58 +28,16 @@
 #include <unordered_map>
 #include <vector>
 #include <string>
-#include "base.hpp"
 #include "fftw_interface.hpp"
+#include "field_layout.hpp"
 
 #ifndef FIELD_HPP
 
 #define FIELD_HPP
 
 enum field_backend {FFTW};
-enum field_components {ONE, THREE, THREExTHREE};
 enum kspace_dealias_type {TWO_THIRDS, SMOOTH};
 
-constexpr unsigned int ncomp(
-        field_components fc)
-    /* return actual number of field components for each enum value */
-{
-    return ((fc == THREE) ? 3 : (
-            (fc == THREExTHREE) ? 9 : 1));
-}
-
-constexpr unsigned int ndim(
-        field_components fc)
-    /* return actual number of field dimensions for each enum value */
-{
-    return ((fc == THREE) ? 4 : (
-            (fc == THREExTHREE) ? 5 : 3));
-}
-
-template <field_components fc>
-class field_layout
-{
-    public:
-        /* description */
-        hsize_t sizes[ndim(fc)];
-        hsize_t subsizes[ndim(fc)];
-        hsize_t starts[ndim(fc)];
-        hsize_t local_size, full_size;
-
-        int myrank, nprocs;
-        MPI_Comm comm;
-
-        std::vector<std::vector<int>> rank;
-        std::vector<std::vector<int>> all_start;
-        std::vector<std::vector<int>> all_size;
-
-        /* methods */
-        field_layout(
-                const hsize_t *SIZES,
-                const hsize_t *SUBSIZES,
-                const hsize_t *STARTS,
-                const MPI_Comm COMM_TO_USE);
-        ~field_layout(){}
-};
 
 template <field_backend be,
           kspace_dealias_type dt>
diff --git a/bfps/cpp/field_layout.cpp b/bfps/cpp/field_layout.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..908904991d5d95b0c89ba679b402d8d5727b8c85
--- /dev/null
+++ b/bfps/cpp/field_layout.cpp
@@ -0,0 +1,111 @@
+/**********************************************************************
+*                                                                     *
+*  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                                 *
+*                                                                     *
+**********************************************************************/
+
+
+#include <cassert>
+#include "field_layout.hpp"
+#include "scope_timer.hpp"
+
+template <field_components fc>
+field_layout<fc>::field_layout(
+        const hsize_t *SIZES,
+        const hsize_t *SUBSIZES,
+        const hsize_t *STARTS,
+        const MPI_Comm COMM_TO_USE)
+{
+    TIMEZONE("field_layout::field_layout");
+    this->comm = COMM_TO_USE;
+    MPI_Comm_rank(this->comm, &this->myrank);
+    MPI_Comm_size(this->comm, &this->nprocs);
+
+    std::copy(SIZES, SIZES + 3, this->sizes);
+    std::copy(SUBSIZES, SUBSIZES + 3, this->subsizes);
+    std::copy(STARTS, STARTS + 3, this->starts);
+    if (fc == THREE || fc == THREExTHREE)
+    {
+        this->sizes[3] = 3;
+        this->subsizes[3] = 3;
+        this->starts[3] = 0;
+    }
+    if (fc == THREExTHREE)
+    {
+        this->sizes[4] = 3;
+        this->subsizes[4] = 3;
+        this->starts[4] = 0;
+    }
+    this->local_size = 1;
+    this->full_size = 1;
+    for (unsigned int i=0; i<ndim(fc); i++)
+    {
+        this->local_size *= this->subsizes[i];
+        this->full_size *= this->sizes[i];
+    }
+
+    /*field will at most be distributed in 2D*/
+    this->rank.resize(2);
+    this->all_start.resize(2);
+    this->all_size.resize(2);
+    for (int i=0; i<2; i++)
+    {
+        this->rank[i].resize(this->sizes[i]);
+        std::vector<int> local_rank;
+        local_rank.resize(this->sizes[i], 0);
+        for (unsigned int ii=this->starts[i]; ii<this->starts[i]+this->subsizes[i]; ii++)
+            local_rank[ii] = this->myrank;
+        MPI_Allreduce(
+                &local_rank.front(),
+                &this->rank[i].front(),
+                this->sizes[i],
+                MPI_INT,
+                MPI_SUM,
+                this->comm);
+        this->all_start[i].resize(this->nprocs);
+        std::vector<int> local_start;
+        local_start.resize(this->nprocs, 0);
+        local_start[this->myrank] = this->starts[i];
+        MPI_Allreduce(
+                &local_start.front(),
+                &this->all_start[i].front(),
+                this->nprocs,
+                MPI_INT,
+                MPI_SUM,
+                this->comm);
+        this->all_size[i].resize(this->nprocs);
+        std::vector<int> local_subsize;
+        local_subsize.resize(this->nprocs, 0);
+        local_subsize[this->myrank] = this->subsizes[i];
+        MPI_Allreduce(
+                &local_subsize.front(),
+                &this->all_size[i].front(),
+                this->nprocs,
+                MPI_INT,
+                MPI_SUM,
+                this->comm);
+    }
+}
+
+template class field_layout<ONE>;
+template class field_layout<THREE>;
+template class field_layout<THREExTHREE>;
+
diff --git a/bfps/cpp/field_layout.hpp b/bfps/cpp/field_layout.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..770119c2dcb05017d495b62559f050646872dc84
--- /dev/null
+++ b/bfps/cpp/field_layout.hpp
@@ -0,0 +1,79 @@
+/**********************************************************************
+*                                                                     *
+*  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                                 *
+*                                                                     *
+**********************************************************************/
+
+
+
+#include <vector>
+#include "base.hpp"
+
+#ifndef FIELD_LAYOUT_HPP
+
+#define FIELD_LAYOUT_HPP
+
+enum field_components {ONE, THREE, THREExTHREE};
+
+constexpr unsigned int ncomp(
+        field_components fc)
+    /* return actual number of field components for each enum value */
+{
+    return ((fc == THREE) ? 3 : (
+            (fc == THREExTHREE) ? 9 : 1));
+}
+
+constexpr unsigned int ndim(
+        field_components fc)
+    /* return actual number of field dimensions for each enum value */
+{
+    return ((fc == THREE) ? 4 : (
+            (fc == THREExTHREE) ? 5 : 3));
+}
+
+template <field_components fc>
+class field_layout
+{
+    public:
+        /* description */
+        hsize_t sizes[ndim(fc)];
+        hsize_t subsizes[ndim(fc)];
+        hsize_t starts[ndim(fc)];
+        hsize_t local_size, full_size;
+
+        int myrank, nprocs;
+        MPI_Comm comm;
+
+        std::vector<std::vector<int>> rank;
+        std::vector<std::vector<int>> all_start;
+        std::vector<std::vector<int>> all_size;
+
+        /* methods */
+        field_layout(
+                const hsize_t *SIZES,
+                const hsize_t *SUBSIZES,
+                const hsize_t *STARTS,
+                const MPI_Comm COMM_TO_USE);
+        ~field_layout(){}
+};
+
+#endif//FIELD_LAYOUT_HPP
+
diff --git a/setup.py b/setup.py
index ed5c9fe479cfbcd3aa2ae5ad99da81e7ab845e79..10ec94ee8f8762773db28e2d35723a6250ec7e64 100644
--- a/setup.py
+++ b/setup.py
@@ -90,6 +90,7 @@ print('This is bfps version ' + VERSION)
 ### lists of files and MANIFEST.in
 src_file_list = ['vorticity_equation',
                  'field',
+                 'field_layout',
                  'field_descriptor',
                  'rFFTW_distributed_particles',
                  'distributed_particles',