diff --git a/CMakeLists.txt b/CMakeLists.txt
index 81488582070a7bcd45dc009b9e2cce835d9a4bde..a2a18ce081039e32df522b993c3a60e9e5e78514 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,14 @@ project(TurTLE)
 
 string(TIMESTAMP BUILD_DATE "%Y-%m-%d")
 
+#####################################################################################
+## CXX Standard
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+#####################################################################################
+
+
 #####################################################################################
 ## Python and version
 
@@ -49,33 +57,32 @@ execute_process(
 project(TurTLE
         VERSION ${TURTLE_VERSION}
         LANGUAGES C CXX)
-#####################################################################################
 
-#####################################################################################
-## CXX Standard
+add_library(TurTLE STATIC "")
 
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
+target_compile_options(TurTLE PRIVATE $<$<CONFIG:DEBUG>:-O1>)
 #####################################################################################
 
 #####################################################################################
 ## OpenMP
 
 find_package(OpenMP REQUIRED)
+target_link_libraries(TurTLE
+    PRIVATE
+    OpenMP::OpenMP_CXX)
 
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
 #####################################################################################
 
 #####################################################################################
 ## MPI
 
 find_package(MPI REQUIRED)
+target_link_libraries(TurTLE
+    PRIVATE
+    MPI::MPI_C)
 
-set(CMAKE_CXX_COMPILE_FLAGS "${CMAKE_CXX_COMPILE_FLAGS} ${MPI_CXX_COMPILE_OPTIONS}")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MPI_CXX_LINK_FLAGS}")
-include_directories(${MPI_CXX_INCLUDE_DIRS})
-add_definitions(${MPI_CXX_COMPILE_DEFINITIONS})
+#include_directories(${MPI_CXX_INCLUDE_DIRS})
+#add_definitions(${MPI_CXX_COMPILE_DEFINITIONS})
 # set(CMAKE_CXX_EXTENSIONS OFF)
 #####################################################################################
 
@@ -212,13 +219,19 @@ endif()
 
 set(HDF5_PREFER_PARALLEL TRUE)
 set(HDF5_NO_FIND_PACKAGE_CONFIG_FILE TRUE)
-find_package(HDF5 REQUIRED)
+find_package(HDF5 REQUIRED COMPONENTS C)
+target_link_libraries(TurTLE
+    PRIVATE
+    HDF5::HDF5)
+target_include_directories(TurTLE
+    PUBLIC
+    ${HDF5_C_INCLUDE_DIR})
 
-message(STATUS "HDF5_C_INCLUDE_DIRS ${HDF5_C_INCLUDE_DIRS}")
+#message(STATUS "HDF5_C_INCLUDE_DIRS ${HDF5_C_INCLUDE_DIRS}")
 
-include_directories(${HDF5_C_INCLUDE_DIRS})
-add_definitions(${HDF5_C_DEFINITIONS})
-list(APPEND TURTLE_LIBS "${HDF5_C_LIBRARIES}")
+#include_directories(${HDF5_C_INCLUDE_DIRS})
+#add_definitions(${HDF5_C_DEFINITIONS})
+#list(APPEND TURTLE_LIBS "${HDF5_C_LIBRARIES}")
 
 option(TURTLE_HDF5_USE_SZIP "Set to on to also link against SZIP" OFF)
 
@@ -227,7 +240,10 @@ if(TURTLE_HDF5_USE_SZIP)
     if(TURTLE_HDF5_SZIP_LIB_PATH)
         link_directories(${TURTLE_HDF5_SZIP_LIB_PATH})
     endif()
-    list(APPEND TURTLE_LIBS "z")
+    #list(APPEND TURTLE_LIBS "z")
+    target_link_libraries(TurTLE
+        PRIVATE
+        z)
 endif()
 #####################################################################################
 
@@ -237,8 +253,9 @@ endif()
 find_package(GSL)
 
 if (GSL_FOUND)
-    include_directories(${GSL_INCLUDE_DIRS})
-    list(APPEND TURTLE_LIBS "${GSL_LIBRARIES}")
+    target_link_libraries(TurTLE
+        PRIVATE
+        GSL::gsl)
 endif()
 #####################################################################################
 
@@ -252,9 +269,8 @@ if(DEFINED ENV{PINCHECK_ROOT})
         HINTS ${PINCHECK_INCLUDE})
     if(PINCHECK_HEADER)
         message("found pincheck header ${PINCHECK_HEADER}")
-        include_directories($ENV{PINCHECK_ROOT}/include)
-        #add_definitions(-DPINCHECK_FOUND)
-        set(CMAKE_CXX_COMPILE_FLAGS "${CMAKE_CXX_COMPILE_FLAGS} -DPINCHECK_FOUND")
+        target_include_directories(TurTLE PUBLIC $ENV{PINCHECK_ROOT}/include)
+        target_compile_definitions(TurTLE PRIVATE PINCHECK_FOUND)
     endif()
 endif()
 #####################################################################################
@@ -311,9 +327,6 @@ find_library(
 set(TURTLE_LIBS ${FFTW_MPI} ${TURTLE_LIBS})
 #####################################################################################
 
-list(APPEND TURTLE_LIBS "${MPI_CXX_LIBRARIES}")
-list(APPEND TURTLE_LIBS "${OpenMP_CXX_LIB_NAMES}")
-
 #####################################################################################
 ## Get the links and include from deps
 
@@ -322,194 +335,11 @@ get_property(ALL_LINK_DIRS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY LINK_D
 #####################################################################################
 
 #####################################################################################
-## Build the lib
+## Add sources
 
 include_directories(${PROJECT_SOURCE_DIR}/cpp)
 
-#file(GLOB_RECURSE cpp_for_lib ${PROJECT_SOURCE_DIR}/*.cpp)
-set(cpp_for_lib
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/code_base.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/direct_numerical_simulation.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSE.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/static_field.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/kraichnan_field.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/joint_acc_vel_stats.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/pressure_stats.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/filter_test.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_test.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/write_filtered_test.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/dealias_test.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/Gauss_field_test.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/symmetrize_test.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_output_test.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/phase_shift_test.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_tracer_set.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/get_rfields.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/get_velocity.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/get_3D_correlations.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/write_rpressure.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/bandpass_stats.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_single_to_double.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/resize.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_field_stats.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/native_binary_to_hdf5.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/postprocess.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/base.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/field.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/kspace.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/field_layout.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/hdf5_tools.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/fftw_tools.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/vorticity_equation.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/field_binary_IO.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n0.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n1.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n2.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n3.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n4.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n5.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n6.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n7.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n8.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n9.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n10.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/Lagrange_polys.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/field_tinterpolator.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/particle_set.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/tracer_rhs.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/tracer_with_collision_counter_rhs.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particle_solver.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/scope_timer.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_interpolation.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEparticles.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEcomplex_particles.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_Stokes_particles.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEp_extra_sampling.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/inner/particles_inner_computer.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/ornstein_uhlenbeck_process.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/ou_vorticity_equation.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_interpolation_methods.cpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_particle_integration.cpp)
-
-set(hpp_for_lib
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/code_base.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/direct_numerical_simulation.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSE.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/static_field.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/kraichnan_field.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/joint_acc_vel_stats.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/pressure_stats.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/filter_test.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/dealias_test.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/Gauss_field_test.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_test.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/write_filtered_test.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/symmetrize_test.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_output_test.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/phase_shift_test.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_tracer_set.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/get_rfields.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/get_velocity.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/get_3D_correlations.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/write_rpressure.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/bandpass_stats.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/field_single_to_double.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/resize.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_field_stats.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/native_binary_to_hdf5.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/postprocess.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/field.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/kspace.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/field_layout.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/hdf5_tools.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/fftw_tools.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/vorticity_equation.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/field_binary_IO.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n0.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n1.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n2.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n3.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n4.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n5.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n6.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n7.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n8.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n9.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/spline_n10.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/Lagrange_polys.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/abstract_particle_set.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/particle_set.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/field_tinterpolator.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particle_rhs.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/tracer_rhs.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/deformation_tensor_rhs.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particle_solver.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/scope_timer.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_interpolation.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEparticles.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEcomplex_particles.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_Stokes_particles.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEp_extra_sampling.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/inner/particles_inner_computer.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/inner/particles_inner_computer_2nd_order.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/inner/particles_inner_computer_empty.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_input.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_output.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_system.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_system_with_p2p.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/alltoall_exchanger.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/lock_free_bool_array.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_computer_empty.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_computer.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_ghost_collisions.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_distr_mpi.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/p2p/p2p_tree.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_adams_bashforth.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_distr_mpi.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/particles_field_computer.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/interpolation/particles_generic_interp.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_input_hdf5.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_output_hdf5.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_output_mpiio.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_output_sampling_hdf5.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_sampling.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_system_builder.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_system.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/particles/particles_utils.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/main_code.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/codes_with_no_output.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVE_no_output.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/NSVEparticles_no_output.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/base.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/env_utils.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/fftw_interface.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/turtle_timer.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/omputils.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/shared_array.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/spectrum_function.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/ornstein_uhlenbeck_process.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/ou_vorticity_equation.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_interpolation_methods.hpp
-    ${PROJECT_SOURCE_DIR}/cpp/full_code/test_particle_integration.hpp)
-
-if(GSL_FOUND)
-    LIST(APPEND cpp_for_lib ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/deformation_tensor_rhs.cpp)
-    LIST(APPEND hpp_for_lib ${PROJECT_SOURCE_DIR}/cpp/particles/rhs/deformation_tensor_rhs.hpp)
-endif()
-
-#file(GLOB_RECURSE hpp_for_lib ${PROJECT_SOURCE_DIR}/*.hpp)
-LIST(APPEND source_files ${hpp_for_lib} ${cpp_for_lib})
-
-add_library(TurTLE ${source_files})
-
-target_link_libraries(TurTLE ${TURTLE_LIBS})
-target_compile_options(TurTLE PRIVATE $<$<CONFIG:DEBUG>:-O1>)
+add_subdirectory(cpp)
 
 install(TARGETS TurTLE EXPORT TURTLE_EXPORT DESTINATION lib/ )
 install(DIRECTORY ${PROJECT_SOURCE_DIR}/cpp/ DESTINATION include/TurTLE/ FILES_MATCHING PATTERN "*.h*")
diff --git a/TurTLE/_code.py b/TurTLE/_code.py
index 24481fbca5913a103f762b042e8076c744fe672c..fcd6ac5b4181fdf75b27ba920aa43caa28c5ec57 100644
--- a/TurTLE/_code.py
+++ b/TurTLE/_code.py
@@ -205,17 +205,20 @@ class _code(_base):
         with open('CMakeLists.txt', 'w') as outfile:
             outfile.write('cmake_minimum_required(VERSION 3.10)\n')
             outfile.write('cmake_policy(VERSION 3.12)\n')
-            outfile.write('project(project_{0} LANGUAGES C CXX)\n'.format(self.name))
             outfile.write('set(CMAKE_CXX_STANDARD 17)\n')
             outfile.write('set(CMAKE_CXX_STANDARD_REQUIRED ON)\n')
+            outfile.write('project(project_{0} LANGUAGES C CXX)\n'.format(self.name))
+            outfile.write('add_executable({0} {0}.cpp)\n'.format(self.name))
             outfile.write('find_package(OpenMP REQUIRED)\n')
-            outfile.write('set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")\n')
             outfile.write('find_package(MPI REQUIRED)\n')
-            outfile.write('set(CMAKE_CXX_COMPILE_FLAGS "${CMAKE_CXX_COMPILE_FLAGS} ${MPI_CXX_COMPILE_OPTIONS}")\n')
-            outfile.write('include_directories(${MPI_CXX_INCLUDE_DIRS})\n')
-            outfile.write('add_definitions(${MPI_CXX_COMPILE_DEFINITIONS})\n')
-            outfile.write('list(APPEND TURTLE_LIBS "${MPI_CXX_LIBRARIES}")\n')
-            outfile.write('list(APPEND TURTLE_LIBS "${OpenMP_CXX_LIB_NAMES}")\n')
+            outfile.write('target_link_libraries({0} PRIVATE OpenMP::OpenMP_CXX MPI::MPI_C)\n'.format(self.name))
+            outfile.write('set(HDF5_STATIC ON)\n')
+            outfile.write('set(HDF5_PREFER_PARALLEL TRUE)\n')
+            outfile.write('set(HDF5_NO_FIND_PACKAGE_CONFIG_FILE TRUE)\n')
+            outfile.write('find_package(HDF5 REQUIRED COMPONENTS C)\n')
+            outfile.write('message("found HDF5 include dir at ${HDF5_C_INCLUDE_DIR}")\n')
+            outfile.write('target_link_libraries({0} PRIVATE HDF5::HDF5)\n'.format(self.name))
+            outfile.write('target_include_directories({0} PRIVATE ${{HDF5_C_INCLUDE_DIR}})\n'.format(self.name))
             #ideally we should use something like the following 2 lines
             #outfile.write('set(CMAKE_CXX_COMPILER ${TURTLE_CXX_COMPILER})\n')
             #outfile.write('set(CMAKE_C_COMPILER ${TURTLE_C_COMPILER})\n')
@@ -223,8 +226,6 @@ class _code(_base):
             outfile.write('set(CMAKE_CXX_COMPILE_FLAGS "${CMAKE_CXX_COMPILE_FLAGS} ${TURTLE_CXX_COMPILE_FLAGS}")\n')
             outfile.write('set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_COMPILE_FLAGS}")\n')
             outfile.write('set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TURTLE_EXE_LINKER_FLAGS}")\n')
-            outfile.write('set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MPI_CXX_LINK_FLAGS}")\n')
-            outfile.write('set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")\n')
             outfile.write('if(NDEBUG)\n')
             outfile.write('    add_definitions(-DNDEBUG)\n')
             outfile.write('endif()\n')
@@ -234,9 +235,8 @@ class _code(_base):
             outfile.write('include_directories(${TURTLE_INCLUDE_DIRECTORIES} ${TURTLE_INCLUDE_DIR}/TurTLE)\n')
             outfile.write('link_directories(${TURTLE_LINK_DIRECTORIES} ${TURTLE_LIBRARIES_DIR})\n')
             outfile.write('find_library(TURTLE_STATIC_LIBRARY TurTLE HINTS ${TURTLE_LIBRARIES_DIR})\n')
-            outfile.write('add_executable({0} {0}.cpp)\n'.format(self.name))
-            outfile.write('target_link_libraries(' + self.name + ' ${TURTLE_STATIC_LIBRARY})\n')
-            outfile.write('target_link_libraries(' + self.name + ' ${TURTLE_LIBS})\n')
+            outfile.write('target_link_libraries(' + self.name + ' PRIVATE ${TURTLE_STATIC_LIBRARY})\n')
+            outfile.write('target_link_libraries(' + self.name + ' PRIVATE ${TURTLE_LIBS})\n')
             fname = self.dns_type + '_extra_cmake.txt'
             if os.path.exists(fname):
                 with open(fname, 'r') as ifile:
diff --git a/TurTLE/test/collisions/stokes_rhs.hpp b/TurTLE/test/collisions/stokes_rhs.hpp
index 582f7089f3ed0759329b172363ac14823e500fdd..41268149f23f590bc1e6bb9f9ce011aba5c34c8c 100644
--- a/TurTLE/test/collisions/stokes_rhs.hpp
+++ b/TurTLE/test/collisions/stokes_rhs.hpp
@@ -43,7 +43,7 @@ class stokes_rhs: public abstract_particle_rhs
     public:
         stokes_rhs(){}
         ~stokes_rhs(){}
-        const int getStateSize() const
+        int getStateSize() const
         {
              // 3 numbers for position
              // // 9 numbers for components of deformation tensor                                                                                                                                                        // 3 numbers to store logarithmic factors
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6421dd5c13ccd7b17a3c65f239d6e0eda1f50294
--- /dev/null
+++ b/cpp/CMakeLists.txt
@@ -0,0 +1,210 @@
+#######################################################################
+#                                                                     #
+#  Copyright 2019 Max Planck Institute                                #
+#                 for Dynamics and Self-Organization                  #
+#                                                                     #
+#  This file is part of TurTLE.                                       #
+#                                                                     #
+#  TurTLE 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.                             #
+#                                                                     #
+#  TurTLE 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 TurTLE.  If not, see <http://www.gnu.org/licenses/>     #
+#                                                                     #
+# Contact: Cristian.Lalescu@ds.mpg.de                                 #
+#                                                                     #
+#######################################################################
+
+
+
+set(cpp_for_lib
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/code_base.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/direct_numerical_simulation.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSE.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVE.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/static_field.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/kraichnan_field.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/joint_acc_vel_stats.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/pressure_stats.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/filter_test.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/field_test.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/write_filtered_test.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/dealias_test.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/Gauss_field_test.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/symmetrize_test.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/field_output_test.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/phase_shift_test.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test_tracer_set.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/get_rfields.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/get_velocity.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/get_3D_correlations.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/write_rpressure.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/bandpass_stats.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/field_single_to_double.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/resize.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVE_field_stats.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/native_binary_to_hdf5.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/postprocess.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/base.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/field.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/kspace.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/field_layout.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/hdf5_tools.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/fftw_tools.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/vorticity_equation.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/field_binary_IO.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n0.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n1.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n2.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n3.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n4.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n5.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n6.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n7.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n8.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n9.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n10.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/Lagrange_polys.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/field_tinterpolator.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/particle_set.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/rhs/tracer_rhs.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/rhs/tracer_with_collision_counter_rhs.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particle_solver.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/scope_timer.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test_interpolation.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVEparticles.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVEcomplex_particles.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVE_Stokes_particles.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVEp_extra_sampling.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/inner/particles_inner_computer.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/ornstein_uhlenbeck_process.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/ou_vorticity_equation.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test_interpolation_methods.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test_particle_integration.cpp)
+
+set(hpp_for_lib
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/code_base.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/direct_numerical_simulation.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSE.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVE.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/static_field.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/kraichnan_field.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/joint_acc_vel_stats.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/pressure_stats.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/filter_test.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/dealias_test.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/Gauss_field_test.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/field_test.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/write_filtered_test.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/symmetrize_test.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/field_output_test.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/phase_shift_test.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test_tracer_set.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/get_rfields.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/get_velocity.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/get_3D_correlations.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/write_rpressure.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/bandpass_stats.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/field_single_to_double.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/resize.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVE_field_stats.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/native_binary_to_hdf5.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/postprocess.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/field.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/kspace.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/field_layout.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/hdf5_tools.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/fftw_tools.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/vorticity_equation.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/field_binary_IO.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n0.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n1.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n2.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n3.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n4.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n5.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n6.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n7.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n8.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n9.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/spline_n10.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/Lagrange_polys.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/abstract_particle_set.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/particle_set.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/field_tinterpolator.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/abstract_particle_rhs.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/rhs/tracer_rhs.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/rhs/deformation_tensor_rhs.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/rhs/tracer_with_collision_counter_rhs.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particle_solver.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/scope_timer.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test_interpolation.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVEparticles.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVEcomplex_particles.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVE_Stokes_particles.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVEp_extra_sampling.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/inner/particles_inner_computer.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/inner/particles_inner_computer_2nd_order.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/inner/particles_inner_computer_empty.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/abstract_particles_input.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/abstract_particles_output.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/abstract_particles_system.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/abstract_particles_system_with_p2p.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/alltoall_exchanger.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/lock_free_bool_array.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/p2p/p2p_computer_empty.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/p2p/p2p_computer.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/p2p/p2p_ghost_collisions.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/p2p/p2p_distr_mpi.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/p2p/p2p_tree.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_adams_bashforth.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_distr_mpi.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/particles_field_computer.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/interpolation/particles_generic_interp.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_input_hdf5.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_output_hdf5.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_output_mpiio.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_output_sampling_hdf5.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_sampling.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_system_builder.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_system.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/particles/particles_utils.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/main_code.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/codes_with_no_output.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVE_no_output.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/NSVEparticles_no_output.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/base.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/env_utils.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/fftw_interface.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/turtle_timer.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/omputils.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/shared_array.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/spectrum_function.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/ornstein_uhlenbeck_process.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/ou_vorticity_equation.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test_interpolation_methods.hpp
+    ${CMAKE_CURRENT_LIST_DIR}/full_code/test_particle_integration.hpp)
+
+if(GSL_FOUND)
+    LIST(APPEND cpp_for_lib ${CMAKE_CURRENT_LIST_DIR}/particles/rhs/deformation_tensor_rhs.cpp)
+    LIST(APPEND hpp_for_lib ${CMAKE_CURRENT_LIST_DIR}/particles/rhs/deformation_tensor_rhs.hpp)
+endif()
+
+LIST(APPEND source_files ${hpp_for_lib} ${cpp_for_lib})
+
+target_sources(TurTLE
+    PRIVATE
+    ${source_files})
+
+#EOF
+
diff --git a/cpp/base.cpp b/cpp/base.cpp
index b80b08ec51b36cd7c83aa312aa667cb2334f5fc3..1ad16d3794e7632a3e107f04b65320bf8283c85b 100644
--- a/cpp/base.cpp
+++ b/cpp/base.cpp
@@ -14,7 +14,8 @@ int read_maximum_MPI_tag_value()
             &flag);
     if (flag){
         maximum_MPI_tag_value = *((int*)(max_tag));
-        std::cerr << "Maximum MPI tag value queried is " << maximum_MPI_tag_value << std::endl;
+        if (myrank == 0)
+            std::cerr << "Maximum MPI tag value queried from rank 0 is " << maximum_MPI_tag_value << std::endl;
     }
     else{
         std::cerr << "TurTLE error: couldn't get maximum MPI tag value." << std::endl;
diff --git a/cpp/field.cpp b/cpp/field.cpp
index 16091a6bdc3ae2dfb3627f467fdf2bff0f0206cf..078f59c6145c1d84eaf1c6e2619ba9723be8710f 100644
--- a/cpp/field.cpp
+++ b/cpp/field.cpp
@@ -993,11 +993,13 @@ void field<rnumber, be, fc>::compute_rspace_stats(
                 const hid_t group,
                 const std::string dset_name,
                 const hsize_t toffset,
-                const std::vector<double> max_estimate)
+                const std::vector<double> max_estimate,
+                const unsigned int maximum_moment)
 {
     TIMEZONE("field::compute_rspace_stats");
     assert(this->real_space_representation);
     const unsigned int nmoments = 10;
+    assert(maximum_moment < nmoments);
     int nvals, nbins;
     if (this->myrank == 0)
     {
@@ -1017,6 +1019,13 @@ void field<rnumber, be, fc>::compute_rspace_stats(
         //        dset_name.c_str());
         assert(ndims == int(ndim(fc))-1);
         assert(dims[1] == nmoments);
+        // gcc complains about the following code, when ndim(fc)-1 is too small
+        // since I already assert what the value of ndims is, I know the code
+        // is safe, so I just tell GCC to ignore the apparent problem with this
+        // pragma. See link below for more info:
+        // https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#pragma GCC diagnostic push
         switch(ndims)
         {
             case 2:
@@ -1029,6 +1038,7 @@ void field<rnumber, be, fc>::compute_rspace_stats(
                 nvals = dims[2]*dims[3];
                 break;
         }
+#pragma GCC diagnostic pop
         H5Sclose(wspace);
         H5Dclose(dset);
         dset = H5Dopen(group, ("histograms/" + dset_name).c_str(), H5P_DEFAULT);
@@ -1113,8 +1123,8 @@ void field<rnumber, be, fc>::compute_rspace_stats(
                 if (bin >= 0 && bin < nbins)
                     local_hist[bin*nvals+i]++;
             }
-            for (int n=1; n < int(nmoments)-1; n++){
-                for (int i=0; i<nvals; i++){
+            for (unsigned int n=1; n < maximum_moment; n++){
+                for (auto i=0; i<nvals; i++){
                     local_moments[n*nvals + i] += (pow_tmp[i] = val_tmp[i]*pow_tmp[i]);
                 }
             }
diff --git a/cpp/field.hpp b/cpp/field.hpp
index f6c69a7d1e10d6751e0be0055518b1fa4c2d2e6c..eb79f5b74237efa7d98f5f889b5a64af763849c8 100644
--- a/cpp/field.hpp
+++ b/cpp/field.hpp
@@ -139,7 +139,8 @@ class field
                 const hid_t group,
                 const std::string dset_name,
                 const hsize_t toffset,
-                const std::vector<double> max_estimate);
+                const std::vector<double> max_estimate,
+                const unsigned int maximum_moment = 9);
 
         void compute_rspace_zaverage(
                 const hid_t group,
diff --git a/cpp/full_code/NSVE.cpp b/cpp/full_code/NSVE.cpp
index 5c0d360c0cdced78c17b72b11b30d813239d75c8..20591057555de5989742d6d1d25066ed4be64c71 100644
--- a/cpp/full_code/NSVE.cpp
+++ b/cpp/full_code/NSVE.cpp
@@ -84,7 +84,7 @@ int NSVE<rnumber>::initialize(void)
     this->fs->fk0 = fk0;
     this->fs->fk1 = fk1;
     this->fs->dt = dt;
-    strncpy(this->fs->forcing_type, forcing_type, 128);
+    this->fs->forcing_type = forcing_type;
     this->fs->iteration = this->iteration;
     this->fs->checkpoint = this->checkpoint;
 
@@ -193,8 +193,7 @@ int NSVE<rnumber>::read_parameters(void)
     this->histogram_bins = hdf5_tools::read_value<int>(parameter_file, "parameters/histogram_bins");
     this->max_velocity_estimate = hdf5_tools::read_value<double>(parameter_file, "parameters/max_velocity_estimate");
     this->max_vorticity_estimate = hdf5_tools::read_value<double>(parameter_file, "parameters/max_vorticity_estimate");
-    std::string tmp = hdf5_tools::read_string(parameter_file, "parameters/forcing_type");
-    snprintf(this->forcing_type, 511, "%s", tmp.c_str());
+    this->forcing_type = hdf5_tools::read_string(parameter_file, "parameters/forcing_type");
     this->fftw_plan_rigor = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_rigor");
     H5Fclose(parameter_file);
     // the following ensures the file is free after exiting this method
diff --git a/cpp/full_code/NSVE.hpp b/cpp/full_code/NSVE.hpp
index 15a388dc4f8e7fdd1db8e11b3cff1806094e18d3..60809a88e6278643b37299490c2d5a8da2e6655f 100644
--- a/cpp/full_code/NSVE.hpp
+++ b/cpp/full_code/NSVE.hpp
@@ -28,12 +28,13 @@
 #define NSVE_HPP
 
 
-
-#include <cstdlib>
 #include "base.hpp"
 #include "vorticity_equation.hpp"
 #include "full_code/direct_numerical_simulation.hpp"
 
+#include <cstdlib>
+#include <string>
+
 /** \brief Navier-Stokes solver.
  *
  * Solves the vorticity equation for a Navier-Stokes fluid.
@@ -58,7 +59,7 @@ class NSVE: public direct_numerical_simulation
         double energy;
         double injection_rate;
         int fmode;
-        char forcing_type[512];
+        std::string forcing_type;
         int histogram_bins;
         double max_velocity_estimate;
         double max_vorticity_estimate;
diff --git a/cpp/full_code/postprocess.cpp b/cpp/full_code/postprocess.cpp
index 2fe20c34ef524419e6e591b6d381421f12944d3b..2c136a7baa01e8e0e4bdbaf063cff3a06fca7f3a 100644
--- a/cpp/full_code/postprocess.cpp
+++ b/cpp/full_code/postprocess.cpp
@@ -73,8 +73,7 @@ int postprocess::read_parameters()
     this->variation_time_scale = hdf5_tools::read_value<double>(parameter_file, "parameters/variation_time_scale");
     this->energy = hdf5_tools::read_value<double>(parameter_file, "parameters/energy");
     this->injection_rate = hdf5_tools::read_value<double>(parameter_file, "parameters/injection_rate");
-    std::string tmp = hdf5_tools::read_string(parameter_file, "parameters/forcing_type");
-    snprintf(this->forcing_type, 511, "%s", tmp.c_str());
+    this->forcing_type = hdf5_tools::read_string(parameter_file, "parameters/forcing_type");
     H5Fclose(parameter_file);
     MPI_Barrier(this->comm);
     return EXIT_SUCCESS;
@@ -96,7 +95,7 @@ int postprocess::copy_parameters_into(
     dst->friction_coefficient = this->friction_coefficient;
     dst->variation_strength = this->variation_strength;
     dst->variation_time_scale = this->variation_time_scale;
-    strncpy(dst->forcing_type, this->forcing_type, 128);
+    dst->forcing_type = this->forcing_type;
     return EXIT_SUCCESS;
 }
 
diff --git a/cpp/full_code/postprocess.hpp b/cpp/full_code/postprocess.hpp
index 4a8fab396149ccddc008d15dedbc15ce968b8a70..52826cf7acf436823ad200e28ca29534bcf5e355 100644
--- a/cpp/full_code/postprocess.hpp
+++ b/cpp/full_code/postprocess.hpp
@@ -27,13 +27,14 @@
 #ifndef POSTPROCESS_HPP
 #define POSTPROCESS_HPP
 
+#include "full_code/code_base.hpp"
+#include "vorticity_equation.hpp"
+#include "base.hpp"
+
 #include <cstdlib>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <vector>
-#include "base.hpp"
-#include "vorticity_equation.hpp"
-#include "full_code/code_base.hpp"
 
 class postprocess: public code_base
 {
@@ -56,7 +57,7 @@ class postprocess: public code_base
         double variation_strength;
         double variation_time_scale;
         int fmode;
-        char forcing_type[512];
+        std::string forcing_type;
         double nu;
 
         postprocess(
diff --git a/cpp/hdf5_tools.cpp b/cpp/hdf5_tools.cpp
index 9a92c459cf368de3a66b456bffef502fcc9478cb..e75070b40ac56f5e2d248194430cd8ff250a6cce 100644
--- a/cpp/hdf5_tools.cpp
+++ b/cpp/hdf5_tools.cpp
@@ -1,7 +1,7 @@
 #include "hdf5_tools.hpp"
 #include "scope_timer.hpp"
-#include <cfloat>
-#include <climits>
+
+#include <limits>
 
 template <> hid_t hdf5_tools::hdf5_type_id<char>()
 {
@@ -208,13 +208,7 @@ std::vector<number> hdf5_tools::read_vector(
     hsize_t vector_length;
     // first, read size of array
     hid_t dset, dspace;
-    hid_t mem_dtype;
-    if (typeid(number) == typeid(int))
-        mem_dtype = H5Tcopy(H5T_NATIVE_INT);
-    else if (typeid(number) == typeid(double))
-        mem_dtype = H5Tcopy(H5T_NATIVE_DOUBLE);
-    else
-        return result;
+    hid_t mem_dtype = H5Tcopy(hdf5_tools::hdf5_type_id<number>());
     dset = H5Dopen(group, dset_name.c_str(), H5P_DEFAULT);
     dspace = H5Dget_space(dset);
     assert(H5Sget_simple_extent_ndims(dspace) == 1);
@@ -235,15 +229,7 @@ number hdf5_tools::read_value(
     TIMEZONE("hdf5_tools::read_value");
     number result;
     hid_t dset;
-    hid_t mem_dtype;
-    if (typeid(number) == typeid(int))
-        mem_dtype = H5Tcopy(H5T_NATIVE_INT);
-    else if (typeid(number) == typeid(long long int))
-        mem_dtype = H5Tcopy(H5T_NATIVE_LLONG);
-    else if (typeid(number) == typeid(double))
-        mem_dtype = H5Tcopy(H5T_NATIVE_DOUBLE);
-    else
-        return result;
+    hid_t mem_dtype = H5Tcopy(hdf5_tools::hdf5_type_id<number>());
     if (H5Lexists(group, dset_name.c_str(), H5P_DEFAULT))
     {
         dset = H5Dopen(group, dset_name.c_str(), H5P_DEFAULT);
@@ -258,12 +244,7 @@ number hdf5_tools::read_value(
     {
         DEBUG_MSG("attempted to read dataset %s which does not exist.\n",
                 dset_name.c_str());
-        if (typeid(number) == typeid(int))
-            result = INT_MAX;
-        else if (typeid(number) == typeid(long long int))
-            result = -1;
-        else if (typeid(number) == typeid(double))
-            result = number(DBL_MAX);
+        result = std::numeric_limits<number>::max();
     }
     H5Tclose(mem_dtype);
     return result;
@@ -275,13 +256,10 @@ int hdf5_tools::write_value_with_single_rank(
         const std::string dset_name,
         const number value)
 {
+    assert(typeid(number) == typeid(int) ||
+           typeid(number) == typeid(double));
     hid_t dset, mem_dtype;
-    if (typeid(number) == typeid(int))
-        mem_dtype = H5Tcopy(H5T_NATIVE_INT);
-    else if (typeid(number) == typeid(double))
-        mem_dtype = H5Tcopy(H5T_NATIVE_DOUBLE);
-    else
-        return EXIT_FAILURE;
+    mem_dtype = H5Tcopy(hdf5_tools::hdf5_type_id<number>());
     if (H5Lexists(group, dset_name.c_str(), H5P_DEFAULT))
     {
         dset = H5Dopen(group, dset_name.c_str(), H5P_DEFAULT);
diff --git a/cpp/kspace.cpp b/cpp/kspace.cpp
index b1f40ae446e469888ae645d0dd751aae4635817d..3628893df9d19561260d09eba882e0944491108b 100644
--- a/cpp/kspace.cpp
+++ b/cpp/kspace.cpp
@@ -172,7 +172,9 @@ kspace<be, dt>::kspace(
     // I chose the last option because there's no reason to optimize this
     // loop. Furthermore, it seems like the solution that's most readable,
     // and with the least amount of side effects.
-    # pragma novector
+    #if defined(__INTEL_COMPILER)
+        #pragma novector
+    #endif
     for (int n=0; n<this->nshells; n++){
         if (this->nshell[n] > 0)
 	        this->kshell[n] /= this->nshell[n];
diff --git a/cpp/particles/abstract_particle_rhs.hpp b/cpp/particles/abstract_particle_rhs.hpp
index 947e152430cb14bc439021d83e48860411c2c175..a0c68816c4e8879d3a72fee5aff8a168a3142916 100644
--- a/cpp/particles/abstract_particle_rhs.hpp
+++ b/cpp/particles/abstract_particle_rhs.hpp
@@ -49,7 +49,7 @@ class abstract_particle_rhs
 
         /** Probe the dimension of the ODE
          */
-        virtual const int getStateSize() const = 0;
+        virtual int getStateSize() const = 0;
 
 
         /** Compute right-hand-side of the ODE
diff --git a/cpp/particles/rhs/deformation_tensor_rhs.hpp b/cpp/particles/rhs/deformation_tensor_rhs.hpp
index 0835f9869645d14eacedea5990562dffbd0203e4..43b75cb934003606d7f35889da7911769bdbab80 100644
--- a/cpp/particles/rhs/deformation_tensor_rhs.hpp
+++ b/cpp/particles/rhs/deformation_tensor_rhs.hpp
@@ -48,7 +48,7 @@ class deformation_tensor_rhs: public abstract_particle_rhs
         deformation_tensor_rhs(){}
         ~deformation_tensor_rhs() noexcept(false){}
 
-        const int getStateSize() const
+        int getStateSize() const
         {
             // 3 numbers for position
             // 9 numbers for components of deformation tensor
diff --git a/cpp/particles/rhs/tracer_rhs.hpp b/cpp/particles/rhs/tracer_rhs.hpp
index 680b46fdbc330d3bd892a1343094dd066c1f83a5..eca90024144f2a598bcad860c050173245175a13 100644
--- a/cpp/particles/rhs/tracer_rhs.hpp
+++ b/cpp/particles/rhs/tracer_rhs.hpp
@@ -43,7 +43,7 @@ class tracer_rhs: public abstract_particle_rhs
         tracer_rhs(){}
         ~tracer_rhs() noexcept(false){}
 
-        const int getStateSize() const
+        int getStateSize() const
         {
             return 3;
         }
diff --git a/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp b/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp
index 5aa15213d02702eb96c198fab0e333584efb1598..4fdc0686586003b913f3ef09dd70bba69365b5e4 100644
--- a/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp
+++ b/cpp/particles/rhs/tracer_with_collision_counter_rhs.hpp
@@ -44,7 +44,7 @@ class tracer_with_collision_counter_rhs: public tracer_rhs<rnumber, be, tt>
         tracer_with_collision_counter_rhs(){}
         ~tracer_with_collision_counter_rhs() noexcept(false){}
 
-        virtual const int getStateSize() const
+        virtual int getStateSize() const
         {
             return 3;
         }
diff --git a/cpp/vorticity_equation.cpp b/cpp/vorticity_equation.cpp
index c32c03319d1e35796a847a30d1b9590999d3678a..7ce50a766ff3ed0c50d47b0da0b99787159e8518 100644
--- a/cpp/vorticity_equation.cpp
+++ b/cpp/vorticity_equation.cpp
@@ -289,12 +289,12 @@ void vorticity_equation<rnumber, be>::add_forcing(
         double t)
 {
     TIMEZONE("vorticity_equation::add_forcing");
-    if (strcmp(this->forcing_type, "Kolmogorov") == 0)
+    if (this->forcing_type == std::string("Kolmogorov"))
     {
         this->add_Kolmogorov_forcing(dst, this->fmode, this->famplitude);
         return;
     }
-    if (strcmp(this->forcing_type, "2Kolmogorov") == 0)
+    if (this->forcing_type == std::string("2Kolmogorov"))
     {
         // 2 Kolmogorov forces
         // first one wavenumber fk0, amplitude 1 - A
@@ -307,7 +307,7 @@ void vorticity_equation<rnumber, be>::add_forcing(
         this->add_Kolmogorov_forcing(dst, fmode, amplitude);
         return;
     }
-    if (strcmp(this->forcing_type, "Kolmogorov_and_drag") == 0)
+    if (this->forcing_type == std::string("Kolmogorov_and_drag"))
     {
         this->add_Kolmogorov_forcing(dst, this->fmode, this->famplitude);
         this->add_field_band(
@@ -316,7 +316,7 @@ void vorticity_equation<rnumber, be>::add_forcing(
                 -this->friction_coefficient);
         return;
     }
-    if (strcmp(this->forcing_type, "Kolmogorov_and_compensated_drag") == 0)
+    if (this->forcing_type == std::string("Kolmogorov_and_compensated_drag"))
     {
         double amplitude = this->famplitude * (
                 1 + this->friction_coefficient / sqrt(this->fmode  * this->famplitude));
@@ -327,7 +327,7 @@ void vorticity_equation<rnumber, be>::add_forcing(
                 -this->friction_coefficient);
         return;
     }
-    if (strcmp(this->forcing_type, "linear") == 0)
+    if (this->forcing_type == std::string("linear"))
     {
         this->add_field_band(
                 dst, vort_field,
@@ -335,9 +335,9 @@ void vorticity_equation<rnumber, be>::add_forcing(
                 this->famplitude);
         return;
     }
-    if ((strcmp(this->forcing_type, "fixed_energy_injection_rate") == 0) ||
-        (strcmp(this->forcing_type, "fixed_energy_injection_rate_and_drag") == 0) ||
-        (strcmp(this->forcing_type, "sinusoidal_energy_injection_rate") == 0))
+    if (this->forcing_type == std::string("fixed_energy_injection_rate") ||
+        this->forcing_type == std::string("fixed_energy_injection_rate_and_drag") ||
+        this->forcing_type == std::string("sinusoidal_energy_injection_rate"))
     {
         // first, compute energy in shell
         shared_array<double> local_energy_in_shell(1);
@@ -377,7 +377,7 @@ void vorticity_equation<rnumber, be>::add_forcing(
         if (energy_in_shell < 10*std::numeric_limits<rnumber>::epsilon())
             energy_in_shell = 1;
         double temp_famplitude = 0;
-        if (strcmp(this->forcing_type, "sinusoidal_energy_injection_rate") == 0){
+        if (this->forcing_type == std::string("sinusoidal_energy_injection_rate")){
             temp_famplitude = (this->injection_rate + this->variation_strength
                                 *sin(t/this->variation_time_scale))
                                 / energy_in_shell;
@@ -389,18 +389,18 @@ void vorticity_equation<rnumber, be>::add_forcing(
                 this->fk0, this->fk1,
                 temp_famplitude);
         // and add drag if desired
-        if (strcmp(this->forcing_type, "fixed_energy_injection_rate_and_drag") == 0)
+        if (this->forcing_type == std::string("fixed_energy_injection_rate_and_drag"))
             this->add_field_band(
                     dst, vort_field,
                     this->fmode, this->fmode + (this->fk1 - this->fk0),
                     -this->friction_coefficient);
         return;
     }
-    if (strcmp(this->forcing_type, "fixed_energy") == 0)
+    if (this->forcing_type == std::string("fixed_energy"))
         return;
     else
     {
-        DEBUG_MSG("unknown forcing type printed on next line\n%s", this->forcing_type);
+        DEBUG_MSG("unknown forcing type printed on next line\n%s", this->forcing_type.c_str());
         throw std::invalid_argument("unknown forcing type");
     }
 }
@@ -412,7 +412,7 @@ void vorticity_equation<rnumber, be>::impose_forcing(
         field<rnumber, be, THREE> *oold)
 {
     TIMEZONE("vorticity_equation::impose_forcing");
-    if (strcmp(this->forcing_type, "fixed_energy") == 0)
+    if (this->forcing_type == std::string("fixed_energy"))
     {
         // first, compute energy in shell
         shared_array<double> local_energy_in_shell(1);
@@ -802,7 +802,7 @@ void vorticity_equation<rnumber, be>::compute_Eulerian_acceleration(
                 for (int i=0; i<2; i++)
                     acceleration->get_cdata()[tindex+cc][i] = \
                         - this->nu*k2*this->cvelocity->get_cdata()[tindex+cc][i];
-            if (strcmp(this->forcing_type, "linear") == 0)
+            if (this->forcing_type == std::string("linear"))
             {
                 double knorm = sqrt(k2);
                 if ((this->fk0 <= knorm) &&
diff --git a/cpp/vorticity_equation.hpp b/cpp/vorticity_equation.hpp
index 90803b4b29a65951cac5afe93bfdd49cccf722da..e48196f31505c75eda2f0d7b6d72e9fe46b2443c 100644
--- a/cpp/vorticity_equation.hpp
+++ b/cpp/vorticity_equation.hpp
@@ -27,12 +27,14 @@
 #ifndef VORTICITY_EQUATION
 #define VORTICITY_EQUATION
 
+#include "field.hpp"
+
 #include <sys/stat.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <iostream>
+#include <string>
 
-#include "field.hpp"
 
 extern int myrank, nprocs;
 
@@ -79,7 +81,7 @@ class vorticity_equation
         double friction_coefficient; // for Kolmogorov_and_drag
         double variation_strength;   // for time-varying forcing
         double variation_time_scale; // for time-varying forcing
-        char forcing_type[128];
+        std::string forcing_type;
 
         /* constructor, destructor */
         vorticity_equation(