diff --git a/CMake/FindFFTW.cmake b/CMake/FindFFTW.cmake
index eb00a98025d4657b63b4b7041118fdcfb5717a0f..7a48c8e21b1b6752fada4cdd4914ef02ede952cc 100644
--- a/CMake/FindFFTW.cmake
+++ b/CMake/FindFFTW.cmake
@@ -80,11 +80,11 @@ find_library(FFTWFloat_MPI_LIBRARY
 
 
 #other types for the CXX library
-find_library (FFTWD_LIB "fftw3")
-find_library (FFTWL_LIB "fftw3l")
-find_library (FFTWQ_LIB "fftw3q")
-set(FFTW_OTHER_LIBRARIES ${FFTW_LIB} ${FFTWF_LIB} ${FFTWL_LIB} ${FFTWQ_LIB})
+#find_library (FFTWD_LIB "fftw3")
+#find_library (FFTWL_LIB "fftw3l")
+#find_library (FFTWQ_LIB "fftw3q")
+set(FFTW_OTHER_LIBRARIES) # ${FFTW_LIB} ${FFTWF_LIB} ${FFTWL_LIB} ${FFTWQ_LIB})
 
 set(FFTW_PROCESS_INCLUDES FFTW_INCLUDE_DIR)
-set(FFTW_PROCESS_LIBS FFTW_LIBRARY FFTWFloat_LIBRARY FFTW_MPI_LIBRARY FFTWFloat_MPI_LIBRARY FFTW_OTHER_LIBRARIES)
+set(FFTW_PROCESS_LIBS FFTW_LIBRARY FFTWFloat_LIBRARY FFTW_MPI_LIBRARY FFTWFloat_MPI_LIBRARY)# FFTW_OTHER_LIBRARIES)
 libfind_process(FFTW)
diff --git a/CMake/FindPythonFull.cmake b/CMake/FindPythonFull.cmake
index 6447a4af8fc9fbe0be05d74b08e49f33afe9b477..646611606ac36dbb90f17eab561856ce8a195189 100644
--- a/CMake/FindPythonFull.cmake
+++ b/CMake/FindPythonFull.cmake
@@ -16,7 +16,7 @@
 #   PYTHON_EXECUTABLE          - python interpreter (full path)
 #   PYTHON_VERSION_STRING      - Python version found e.g. 2.5.2
 #   PYTHON_LIBRARIES           - full path to the python library
-#   PYTHON_INCLUDE_DIR         - full path to Python.h
+#   PYTHON_INCLUDE_DIRS        - full path to Python.h
 #   PYTHONLIBS_VERSION_STRING  - version of the Python libs found
 #
 # By default, we search for the current active python version first.
@@ -27,7 +27,7 @@
 set(PYTHON_FOUND FALSE)
 
 # Does nothing if vars are already in cache
-if(EXISTS "${PYTHON_INCLUDE_DIR}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS "${PYTHON_SITE_PACKAGES_DIR}")
+if(EXISTS "${PYTHON_INCLUDE_DIRS}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS "${PYTHON_SITE_PACKAGES_DIR}")
   set(PYTHON_FOUND TRUE)
 else()
   set(PYTHON_FOUND FALSE)
@@ -47,11 +47,12 @@ else()
   if(python_config)
     string(REGEX REPLACE ".*exec_prefix:([^\n]+).*$" "\\1" PYTHON_PREFIX ${python_config})
     string(REGEX REPLACE ".*\nversion:([^\n]+).*$" "\\1" PYTHON_VERSION ${python_config})
-    string(REGEX REPLACE ".*\npy_inc_dir:([^\n]+).*$" "\\1" PYTHON_INCLUDE_DIR ${python_config})
+    string(REGEX REPLACE ".*\npy_inc_dir:([^\n]+).*$" "\\1" PYTHON_INCLUDE_DIRS ${python_config})
     string(REGEX REPLACE ".*\nsite_packages_dir:([^\n]+).*$" "\\1" PYTHON_SITE_PACKAGES_DIR ${python_config})
     string(REGEX REPLACE "([0-9]+).([0-9]+)" "\\1\\2" PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
     if(WIN32)
       string(REPLACE "\\" "/" PYTHON_SITE_PACKAGES_DIR ${PYTHON_SITE_PACKAGES_DIR})
+      string(REPLACE "\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX})
     endif(WIN32)
 
     # --- Search python library corresponding to python exec.
@@ -59,25 +60,17 @@ else()
       NAMES
       python${PYTHON_VERSION_NO_DOTS} python${PYTHON_VERSION}
       NO_DEFAULT_PATH
-      HINTS 
-      ${PYTHON_PREFIX} 
-      ${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config
-      ${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config-x86_64-linux-gnu
-      PATH_SUFFIXES lib
+      HINTS ${PYTHON_PREFIX} ${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config ${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config-${CMAKE_LIBRARY_ARCHITECTURE}
+      PATH_SUFFIXES lib libs
       )
-    # find_library(PYTHON_LIBRARY
-    #   NAMES
-    #   python${PYTHON_VERSION_NO_DOTS} python${PYTHON_VERSION}
-    #   NO_DEFAULT_PATH
-    #   HINTS ${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/config
-    #   )
+
     set(PYTHON_LIBRARIES ${PYTHON_LIBRARY} CACHE FILEPATH "Python libraries" FORCE)
 
-    set(PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIR} CACHE FILEPATH "Path to Python.h" FORCE)
+    set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} CACHE FILEPATH "Path to Python.h" FORCE)
 
     # --- Extract python library version for further checks.
-    if(PYTHON_INCLUDE_DIR AND EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h")
-      file(STRINGS "${PYTHON_INCLUDE_DIR}/patchlevel.h" python_version_str
+    if(PYTHON_INCLUDE_DIRS AND EXISTS "${PYTHON_INCLUDE_DIRS}/patchlevel.h")
+      file(STRINGS "${PYTHON_INCLUDE_DIRS}/patchlevel.h" python_version_str
         REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"")
       string(REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1"
         PYTHONLIBS_VERSION_STRING "${python_version_str}")
@@ -89,15 +82,15 @@ else()
   unset(PYTHON_FOUND)
   include(FindPackageHandleStandardArgs)
   find_package_handle_standard_args(Python
-    REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIR PYTHON_EXECUTABLE
+    REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS PYTHON_EXECUTABLE
     VERSION_VAR PYTHONLIBS_VERSION_STRING)
-
   if(PYTHON_FOUND)
+    set(PYTHONFULL_FOUND TRUE)
     if(NOT PythonFull_FIND_QUIETLY)
       message("-- Found Python executable: ${PYTHON_EXECUTABLE}")
       message("-- Found Python library: ${PYTHON_LIBRARIES}")
       message("-- Python version is : ${PYTHON_VERSION_STRING}")
-      message("-- Python include dir is : ${PYTHON_INCLUDE_DIR}")
+      message("-- Python include dir is : ${PYTHON_INCLUDE_DIRS}")
       message("-- Python Site package dir is : ${PYTHON_SITE_PACKAGES_DIR}\n")
     endif()
   else()
@@ -111,5 +104,5 @@ endif()
 if(NOT PYTHONLIBS_VERSION_STRING VERSION_EQUAL PYTHON_VERSION_STRING)
   display(PYTHONLIBS_VERSION_STRING)
   display(PYTHON_VERSION_STRING)
-  message(FATAL_ERROR "Python library and executable versions do not match.")
+  message(FATAL_ERROR "Python library and executable versions do not match. Please check your python installation.")
 endif()
diff --git a/CMake/FindPythonModule.cmake b/CMake/FindPythonModule.cmake
index 660533df8669e4671e4562f767588263a3525fd5..dd356effbb06122a682e11bc977c8bf4f7ca7990 100644
--- a/CMake/FindPythonModule.cmake
+++ b/CMake/FindPythonModule.cmake
@@ -11,16 +11,24 @@ function(find_python_module module)
 	# A module's location is usually a directory, but for binary modules
 	# it's a .so file.
 	execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
-	  "import re, ${module}; print re.compile('/__init__.py.*').sub('',${module}.__file__)"
+	  "import re, ${module}; print(re.compile('/__init__.py.*').sub('',${module}.__file__))"
 	  RESULT_VARIABLE _${module}_status
 	  OUTPUT_VARIABLE _${module}_location
 	  ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
-
+	if(_${module}_location)
+	  # Sometimes the output of the command above is multi-lines.
+	  # We need to keep only the last one.
+	  string(FIND ${_${module}_location} "\n" matches REVERSE)
+	  if(${matches} GREATER 0)
+	    MATH(EXPR matches "${matches}+1")
+	    string(SUBSTRING ${_${module}_location} ${matches} -1 _${module}_location)
+  	  endif()
+	endif()
     	if(NOT _${module}_status)
 	  set(python_${module_upper} ${_${module}_location} CACHE STRING
 	    "Location of Python module ${module}")
 	endif(NOT _${module}_status)
-
+	display(_${module}_location)
 	find_package_handle_standard_args(${module} DEFAULT_MSG _${module}_location)
 	set(${module}_FOUND ${${module_upper}_FOUND} PARENT_SCOPE)
 endfunction(find_python_module)
diff --git a/CMake/MyTools.cmake b/CMake/MyTools.cmake
index f0c4ad54c40a01dba44c761e2fc6eca3f928638a..018c8d5ba2315f44bd8a4d25bffeb746501acbfa 100644
--- a/CMake/MyTools.cmake
+++ b/CMake/MyTools.cmake
@@ -1,10 +1,12 @@
 include(LibFindMacros)
 
-# Basic list manipulation
+# -- Basic list manipulation --
+# Get first element of list var
 macro(CAR var)
   set(${var} ${ARGV1})
 endmacro(CAR)
 
+# get elements in list var minus the first one.
 macro(CDR var junk)
   set(${var} ${ARGN})
 endmacro(CDR)
@@ -16,48 +18,6 @@ macro(APPEND_FLAGS)
   set(${_V} "${${_V}} ${_F}")
 endmacro(APPEND_FLAGS)
 
-
-# Add all dirs in _DIRS into the searched directories for include files
-# Set, for dir in _DIRS:
-# - ${PROJECT_NAME}_INCLUDE_DIRECTORIES 
-# - ${PROJECT_NAME}_REMEMBER_INC_${dir} (to avoid multiple sets)
-macro(REMEMBER_INCLUDE_DIRECTORIES _DIRS)
-  foreach(_D ${_DIRS})
-    if(NOT ${PROJECT_NAME}_REMEMBER_INC_${_D})
-      set(${PROJECT_NAME}_REMEMBER_INC_${_D} TRUE)
-      list(APPEND ${PROJECT_NAME}_INCLUDE_DIRECTORIES ${_D})
-      include_directories(${_DIRS})
-    endif(NOT ${PROJECT_NAME}_REMEMBER_INC_${_D})
-  endforeach(_D ${_DIRS})
-endmacro(REMEMBER_INCLUDE_DIRECTORIES _DIRS)
-
-# Add all dirs in _DIRS into the searched directories for linked libraries
-# Set, for dir in _DIRS:
-# - ${PROJECT_NAME}_LINK_DIRECTORIES 
-# - ${PROJECT_NAME}_REMEMBER_LINK_${dir} (to avoid multiple sets)
-macro(REMEMBER_LINK_DIRECTORIES _DIRS)
-  foreach(_D ${_DIRS})
-    if(NOT ${PROJECT_NAME}_REMEMBER_LINK_${_D})
-      set(${PROJECT_NAME}_REMEMBER_LINK_${_D} TRUE)
-      list(APPEND ${PROJECT_NAME}_LINK_DIRECTORIES ${_D})
-      link_directories(${_D})
-    endif(NOT ${PROJECT_NAME}_REMEMBER_LINK_${_D})
-  endforeach(_D ${_DIRS})
-endmacro(REMEMBER_LINK_DIRECTORIES _DIRS)
-
-# Add all libraries in _LIBS into the searched directories for linked libraries
-# Set, for lib in _LIBS:
-# - ${PROJECT_NAME}_LINK_LIBRARIES 
-# - ${PROJECT_NAME}_REMEMBER_LINK_LIBRARIES_${lib} (to avoid multiple sets)
-macro(REMEMBER_LINK_LIBRARIES _LIBS)
-  foreach(_LIB ${_LIBS})
-    if(NOT ${PROJECT_NAME}_REMEMBER_LINK_LIBRARIES_${_LIB})
-      set(${PROJECT_NAME}_REMEMBER_LINK_LIBRARIES_${_LIB} TRUE)
-      list(APPEND ${PROJECT_NAME}_LINK_LIBRARIES ${_LIB})
-    endif(NOT ${PROJECT_NAME}_REMEMBER_LINK_LIBRARIES_${_LIB})
-  endforeach(_LIB ${_LIBS})
-endmacro(REMEMBER_LINK_LIBRARIES _LIBS)
-
 # The use of ADD_DEFINITION results in a warning with Fortran compiler
 macro(APPEND_C_FLAGS)
   APPEND_FLAGS(CMAKE_C_FLAGS ${ARGV})
@@ -71,48 +31,201 @@ macro(APPEND_Fortran_FLAGS)
   APPEND_FLAGS(CMAKE_Fortran_FLAGS ${ARGV})
 endmacro(APPEND_Fortran_FLAGS)
 
+# Scans DIRS (list of directories) and returns a list of all files in those dirs
+# matching extensions defined in SRC_EXTS list.
+# Results are saved in SOURCES_FILES
+#
+# Usage:
+# set(src_dirs dir1 dir2)
+# get_sources(src_dirs)
+macro(get_sources)
+  set(SOURCES_FILES)
+  foreach(DIR ${ARGV})
+    foreach(_EXT ${SRC_EXTS})
+      file(GLOB FILES_LIST ${DIR}/*.${_EXT})
+      if(FILES_LIST)
+	list(APPEND SOURCES_FILES ${FILES_LIST})
+      endif()
+    endforeach()
+  endforeach()
+  if(SOURCES_FILES)
+    list(REMOVE_DUPLICATES SOURCES_FILES)
+  endif()
+endmacro()
+
+# Scans DIRS (list of directories) and returns a list of all files in those dirs
+# matching extensions defined in HDR_EXTS list.
+# Results are saved in HDRS_FILES
+#
+# Usage:
+# set(src_dirs dir1 dir2)
+# get_headers(src_dirs)
+macro(get_headers DIRS)
+  set(HDRS_FILES)
+  foreach(DIR ${ARGV})
+    foreach(_EXT ${HDR_EXTS})
+      file(GLOB FILES_LIST ${DIR}/*.${_EXT})
+      if(FILES_LIST)
+	list(APPEND HDRS_FILES ${FILES_LIST})
+      endif()
+    endforeach()
+  endforeach()
+  if(HDRS_FILES)
+    list(REMOVE_DUPLICATES HDRS_FILES)
+  endif()
+endmacro()
+
+
+# Return all files matching ext in directories of list dirs
+function(get_files ext dirs)
+  set(files_list)
+  foreach(_dir IN LISTS ${dirs})
+    file(GLOB files ${_DIR}/*.${ext})
+  endforeach()
+  list(APPEND files_list ${files})
+  if(files_list)
+    list(REMOVE_DUPLICATES files_list)
+  endif()
+  set(files_list ${files_list} PARENT_SCOPE)
+endfunction()
+
+# -- returns a list of source files extension --
+# Results in var ALL_EXTS
+macro(get_standard_ext)
+  set(ALL_EXTS)
+  foreach(_EXT
+      ${CMAKE_CXX_SOURCE_FILE_EXTENSIONS}
+      ${CMAKE_C_SOURCE_FILE_EXTENSIONS}
+      ${CMAKE_Fortran_SOURCE_FILE_EXTENSIONS}
+      ${CMAKE_Java_SOURCE_FILE_EXTENSIONS}
+      ${CMAKE_RC_SOURCE_FILE_EXTENSIONS})
+    list(APPEND ALL_EXTS ${_EXT})
+  endforeach()
+  list(REMOVE_DUPLICATES ALL_EXTS)
+endmacro()
+
 # debug
 macro(display V)
   message(STATUS "${V} = ${${V}}")
 endmacro(display V)
 
-# Tests
-macro(begin_test _D)
-  set(_CURRENT_TEST_DIRECTORY ${_D})
-  file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_D})
+# =======================================
+# For a given package name, try to find
+# corresponding headers and libraries and
+# add them to the include directories
+# and list of linked libraries.
+#
+# It sets (if found):
+# - HYSOP_INCLUDE_DIRECTORIES with the list
+# of directories of headers required for hysop to work with
+# - HYSOP_LINK_LIBRARIES with the list of external libraries
+# (full path!) needed by hysop project.
+#
+# Usage :
+#  compile_with(Packagename options)
+#
+# with the same 'options' as find_package
+# (see http://www.cmake.org/cmake/help/v3.0/command/find_package.html?highlight=find_package)
+macro(COMPILE_WITH)
+  # Get package name and extra args ...
+  CAR(_NAME ${ARGV})
+  CDR(_REST ${ARGV})
+  CAR(_REQ ${_REST})
+  if(_REST)
+    CDR(_RREST ${_REST})
+    CAR(_COMP ${_RREST})
+  endif(_REST)
+  string(TOUPPER ${_NAME} _UNAME)
+  list(APPEND _NAMES ${_NAME})
+  list(APPEND _NAMES ${_UNAME})
+  set(_FOUND)
+  find_package(${ARGV})
   
-  # create a CMakeLists.txt for the current test in build_dir/test-name
-  # Source = file CMakeListsForTests.cmake. 
-  configure_file(${CMAKE_SOURCE_DIR}/CMake/CMakeListsForTests.cmake 
-    ${CMAKE_CURRENT_BINARY_DIR}/${_CURRENT_TEST_DIRECTORY}/CMakeLists.txt @ONLY)
- 
-  # init the list of test executables
-  set(_EXE_LIST_${_CURRENT_TEST_DIRECTORY})
-endmacro(begin_test _D)
-
-macro(end_test)
-  # add the subdir corresponding to the current test (i.e. take the new CMakeLists.txt into account)
-  add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/${_CURRENT_TEST_DIRECTORY} ${CMAKE_CURRENT_BINARY_DIR}/${_CURRENT_TEST_DIRECTORY})
-endmacro(end_test)
-
-
-# Declare a new test
-macro(new_test)
-  car(_EXE ${ARGV})
-  cdr(_SOURCES ${ARGV})
-  # Add the current test to the list of all executables
-  list(APPEND _EXE_LIST_${_CURRENT_TEST_DIRECTORY} ${_EXE})
-  # Get the list of sources for the current executable
-  set(${_EXE}_FSOURCES)
-  foreach(_F ${_SOURCES})
-    list(APPEND ${_EXE}_FSOURCES ${CMAKE_CURRENT_SOURCE_DIR}/${_CURRENT_TEST_DIRECTORY}/${_F})
-  endforeach(_F ${_SOURCES})
-endmacro(new_test)  
+  foreach(_N ${_NAMES})
+    if(${_N}_FOUND)
+      set(_FOUND TRUE)
+      # add headers dirs into 'include' path
+      # INCLUDE_DIR var name depends on FindNAME
+      # We try to check the standard var names.
+      if(DEFINED ${_N}_INCLUDE_DIRS)
+	remember_include_directories("${${_N}_INCLUDE_DIRS}")
+      endif()
+      if(DEFINED ${_N}_INCLUDE_DIR)
+	remember_include_directories("${${_N}_INCLUDE_DIR}")
+      endif()
+      if(DEFINED ${_N}_INCLUDE_PATH)
+	remember_include_directories("${${_N}_INCLUDE_DIR}")
+      endif()
+      # Now we set list of libs that must be linked with.
+      if(DEFINED ${_N}_LIBRARIES)
+	set(HYSOP_LINK_LIBRARIES ${HYSOP_LINK_LIBRARIES}
+	  ${${_N}_LIBRARIES})
+      endif()
+      # And the compiler flags
+      if(DEFINED ${_N}_DEFINITIONS)
+       foreach(_DEF ${${_N}_DEFINITIONS})
+        append_c_flags(${_DEF})
+        append_cxx_flags(${_DEF})
+       endforeach()
+      endif()
+    endif()
+  endforeach()
+  list(REMOVE_DUPLICATES HYSOP_LINK_LIBRARIES)
+  set(HYSOP_LINK_LIBRARIES ${HYSOP_LINK_LIBRARIES}
+    ${${_N}_LIBRARIES} CACHE INTERNAL "List of external libraries.")
+  set(_N)
+  set(_NAME) 
+  set(_UNAME)
+  set(_NAMES)
+endmacro(COMPILE_WITH)
+
+# ==== Save directories required for include_directory ===
+# 
+# Set variable HYSOP_INCLUDE_DIRECTORIES with the list
+# of directories of headers required for hysop to work with
+# its dependencies.
+# Usage :
+# set(dirs d1 d2 d3)
+# remember_include_directories(${dirs})
+#  --> save d1, d2, d3 into HYSOP_INCLUDE_DIRECTORIES
+# 
+macro(REMEMBER_INCLUDE_DIRECTORIES _DIRS)
+  foreach(_D ${_DIRS})
+    list(APPEND HYSOP_INCLUDE_DIRECTORIES ${_D})
+  endforeach()
+  list(REMOVE_DUPLICATES HYSOP_INCLUDE_DIRECTORIES)
+  set(HYSOP_INCLUDE_DIRECTORIES ${HYSOP_INCLUDE_DIRECTORIES}
+    CACHE INTERNAL "Include directories for external dependencies.")
+
+endmacro()
+
+# ==== Save directories required for include_directory ===
+# 
+# Set variable ${PROJECT_NAME}_LOCAL_INCLUDE_DIRECTORIES with the list
+# of directories of headers for hysop
+#
+# Usage :
+# set(dirs d1 d2 d3)
+# remember_local_include(${dirs})
+#  --> save d1, d2, d3 into ${PROJECT_NAME}_LOCAL_INCLUDE_DIRECTORIES
+#
+# mind the ${CMAKE_CURRENT_SOURCE_DIR} below!
+macro(remember_local_include_directories _DIRS)
+  foreach(_D ${_DIRS})
+    list(APPEND ${PROJECT_NAME}_LOCAL_INCLUDE_DIRECTORIES
+      ${CMAKE_CURRENT_SOURCE_DIR}/${_D})
+  endforeach()
+  list(REMOVE_DUPLICATES ${PROJECT_NAME}_LOCAL_INCLUDE_DIRECTORIES)
+  set(${PROJECT_NAME}_LOCAL_INCLUDE_DIRECTORIES
+    ${${PROJECT_NAME}_LOCAL_INCLUDE_DIRECTORIES}
+    CACHE INTERNAL "Include directories for external dependencies.")
+endmacro()
+
 
 # Usage: list_subdirectories(the_list_is_returned_here dir 1)
 # 1 if you want relative directories as output.
 macro(list_subdirectories retval curdir return_relative)
-  file(GLOB_RECURSE subdir RELATIVE ${curdir} *)
+  file(GLOB subdir RELATIVE ${curdir} *)
   display(subdir)
   set(list_of_dirs "")
   foreach(dir ${subdir})
@@ -155,4 +268,20 @@ macro(get_python_builddir where result)
   get_filename_component(builddir ${hysopfile} PATH)
   get_filename_component(builddir ${builddir} PATH)
   set(${result} ${builddir})
-endmacro()
\ No newline at end of file
+endmacro()
+
+
+# ------------------------------------
+# Get the list of subdirectories
+# of a given dir
+# ------------------------------------
+macro(get_subdirectories result current_dir)
+  file(GLOB subdirs RELATIVE ${current_dir} ${current_dir}/*)
+  set(dirs "")
+  foreach(_dir ${subdirs})
+    if(IS_DIRECTORY ${current_dir}/${_dir})
+      list(APPEND dirs ${_dir})
+    endif()
+  endforeach()
+  set(${result} ${dirs})
+endmacro()
diff --git a/HySoP/CMakeLists.txt b/HySoP/CMakeLists.txt
index 0491bc9e14ff56558989704ad09f3f78e624a357..9e414eaad7706c9fcaaa589f0dd02ebe8cc41fe0 100644
--- a/HySoP/CMakeLists.txt
+++ b/HySoP/CMakeLists.txt
@@ -43,9 +43,17 @@ option(FULL_TEST "Enable all test options (pep8, mpi ...) - Default = OFF" OFF)
 option(PROFILE "Enable profiling mode for HySoP. 0:disabled, 1: enabled. Default = 0" 0)
 option(OPTIM "To allow python -OO run, some packages must be deactivated. Set this option to 'ON' to do so. Default = OFF" OFF)
 option(WITH_MPI_TESTS "Enable mpi tests. Default = ON if USE_MPI is ON." ON)
+option(FORTRAN_LAYOUT "Choose default data layout ('fortran', column-major or 'C' order, row-major) for arrays. Default = column-major." ON)
+option(WITH_DOCUMENTATION "Build Documentation. Default = OFF" ON)
+
+# Set python install mode:
+# - user --> behave as 'python setup.py install --user'
+# - standard --> install in python site-package (ie behave as python setup.py install)
+# - prefix --> install in python CMAKE_INSTALL_PREFIX (ie behave as python setup.py install --prefix=CMAKE_INSTALL_PREFIX)
+set(hysop_python_install "user" CACHE STRING "Install mode for hysop python package")
 
 if(NOT WITH_LIB_FORTRAN)
-  message(WARNING "You deactivate libhysop (fortran) generation. This will disable fftw and scales fonctionnalities.")
+  message(WARNING "You deactivate libhysop (fortran) generation. This will disable the fortran interface, including fftw and scales fonctionnalities.")
   set(WITH_FFTW "OFF")
   set(WITH_SCALES "OFF")
   set(WITH_MAIN_FORTRAN "OFF")
@@ -56,6 +64,20 @@ if(NOT WITH_LIB_CXX)
     set(WITH_MAIN_CXX "OFF")
 endif()
 
+# Force a default build type if not provided by user
+# CMAKE_BUILD_TYPE = empty, Debug, Release, RelWithDebInfo or MinSizeRel.
+if(NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE RELEASE CACHE STRING
+    "Choose the type of build, options are: None Debug Release."
+    FORCE)
+endif()
+
+
+# true if hysop used Fortran and/or c++ sources
+if(${WITH_LIB_FORTRAN} OR ${WITH_LIB_CXX})
+  set(WITH_COMPILED_LIB)
+endif()
+
 # We can not run scales or fftw without mpi ...
 if(WITH_FFTW OR WITH_SCALES OR WITH_HYSOP_PLUS_PLUS)
   set(USE_MPI "ON")
@@ -77,27 +99,24 @@ set(PROJECT_LIBRARY_NAME ${PROJECT_NAME})
 #   - ${PROJECT_NAME}_BINARY_DIR : where you have run cmake, i.e. the place for compilation
 #   - ${PROJECT_NAME}_SOURCE_DIR : where sources (.f and .h and this CMakeLists.txt) are located
 # Note that because of OutOfSourceBuild, binary_dir and source_dir must be different.
-project(${PROJECT_NAME})
 
-# ============= Search for libraries  =============
-# We search for libraries HySoP depends on and
-# set the compile/link conf (-I and -L opt)
+set(LANGLIST)
+if(WITH_LIB_CXX)
+  set(LANGLIST ${LANGLIST} CXX)
+endif()
+if(WITH_LIB_FORTRAN)
+  set(LANGLIST ${LANGLIST} Fortran)
+endif()
+
+project(${PROJECT_NAME} ${LANGLIST})
 
 set(HYSOP_LIBRARY_NAME hysop)
 set(PACKAGE_NAME HySoP)
 
-# --- Python ---
+# ============= Python and its packages =============
 # - Global setup (interp and lib) -
 find_package(PythonFull REQUIRED)
 include(FindPythonModule)
-find_package(SWIG 2.0.7 REQUIRED)
-# WARNING FP : for cmake < 3.0 UseSWIG.cmake
-# does not work properly (bug for swig outdir)
-if(CMAKE_VERSION VERSION_LESS 3.0.0)
-  set(SWIG_USE_FILE ${CMAKE_SOURCE_DIR}/cmake/UseSWIG.cmake)
-endif()
-include(${SWIG_USE_FILE})
-
 # - python packages -
 find_python_module(numpy REQUIRED)
 find_python_module(scipy)
@@ -115,6 +134,47 @@ if(USE_MPI)
   find_python_module(mpi4py REQUIRED)
 endif()
 
+if(WITH_LIB_CXX)
+  find_package(SWIG 2.0.7 REQUIRED)
+  # WARNING FP : for cmake < 3.0 UseSWIG.cmake
+  # does not work properly (bug for swig outdir)
+  if(CMAKE_VERSION VERSION_LESS 3.0.0)
+    set(SWIG_USE_FILE ${CMAKE_SOURCE_DIR}/cmake/UseSWIG.cmake)
+  endif()
+  include(${SWIG_USE_FILE})
+endif()
+
+# Find python build dir name --> needed for tests and doc
+if(WITH_COMPILED_LIB)
+  execute_process(
+    COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.util as ut ; import distutils.sysconfig as sy; print 'lib.'+ut.get_platform()+'-'+sy.get_python_version()"
+    OUTPUT_VARIABLE ${PROJECT_NAME}_PYTHON_BUILD_DIR)
+  string(STRIP ${${PROJECT_NAME}_PYTHON_BUILD_DIR} ${PROJECT_NAME}_PYTHON_BUILD_DIR)
+  set(HYSOP_BUILD_PYTHONPATH ${CMAKE_BINARY_DIR}/build/${${PROJECT_NAME}_PYTHON_BUILD_DIR} CACHE INTERNAL "Python package build path")
+else()
+  set(HYSOP_BUILD_PYTHONPATH ${CMAKE_BINARY_DIR}/build/lib CACHE INTERNAL "Python package build path")
+endif()
+
+# ============= Other dependencies =============
+
+# --- FFTW ---
+if(WITH_FFTW)
+  compile_with(FFTW REQUIRED)
+  set(dirlist)
+  foreach(_file ${FFTW_LIBRARIES})
+    if(CMAKE_PATCH_VERSION LESS 12)
+      get_filename_component(_name ${_file} PATH)
+    else()
+      get_filename_component(_name ${_file} DIRECTORY)
+    endif()
+    list(FIND dirlist ${_name} isin)
+    if(isin EQUAL -1)
+      list(APPEND dirlist ${_name})
+    endif()
+  endforeach()
+  set(FFTWLIB ${dirlist} CACHE PATH "fftw libraries dir")
+endif()
+
 # ========= Check which opencl devices are available on the system =========
 if(WITH_GPU)
   execute_process(
@@ -141,13 +201,44 @@ display(OPENCL_DEFAULT_OPENCL_DEVICE_ID)
 # --> set installation dir
 # --> set options for python install
 # --> create install/uninstall targets
-
 include(HySoPInstallSetup)
 # Remark : this must be done before add_subdir below, since install process in src needs CMAKE_INSTALL_PREFIX
 # to be properly set.
 
-# ====== Create non-python (fortran, cxx) libraries (fftw and scales interfaces), if required =====
-if(WITH_LIB_FORTRAN OR WITH_LIB_CXX)
+if(EXISTS ${CMAKE_SOURCE_DIR}/${PACKAGE_NAME}/.f2py_f2cmap)
+  message(STATUS "Generate f2py map file ...")
+  configure_file(${CMAKE_SOURCE_DIR}/${PACKAGE_NAME}/.f2py_f2cmap
+    ${CMAKE_BINARY_DIR}/.f2py_f2cmap)
+endif()
+if(EXISTS ${CMAKE_SOURCE_DIR}/${PACKAGE_NAME}/f2hysop.pyf.in)
+  message(STATUS "Generate f2hysop.pyf (f2py main signature file) ...")
+  configure_file(${CMAKE_SOURCE_DIR}/${PACKAGE_NAME}/f2hysop.pyf.in
+    ${CMAKE_SOURCE_DIR}/${PACKAGE_NAME}/f2hysop.pyf)
+endif()
+
+# ====== Create non-python (fortran) libraries (fftw and scales interfaces), if required =====
+if(WITH_LIB_FORTRAN)
+  # Set module files directory (i.e. where .mod will be created)
+  set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/Modules)
+  #  Add compilation flags:
+  #append_Fortran_FLAGS("-Wall -fPIC -ffree-line-length-none -DBLOCKING_SEND_PLUS -DBLOCKING_SEND")
+  append_Fortran_FLAGS("-Wall -fPIC -ffree-line-length-none -cpp")
+  
+  if(USE_MPI)
+    # Find MPI for fortran.
+    find_package(MPI REQUIRED)
+    # -I
+    include_directories(${MPI_Fortran_INCLUDE_PATH})
+    # Add compilation/link flags
+    set(${HYSOP_LIBRARY_NAME}_LINK_FLAGS ${${HYSOP_LIBRARY_NAME}_LINK_FLAGS} ${MPI_Fortran_LINK_FLAGS})
+    append_Fortran_flags(${MPI_Fortran_COMPILE_FLAGS})
+    # Append mpi libraries to the list of libraries linked with libhysop.
+    set(LIBS ${LIBS} ${MPI_Fortran_LIBRARIES} )
+  endif(USE_MPI)
+
+  set(Fortran_FLAGS ${CMAKE_Fortran_FLAGS})
+  append_flags(Fortran_FLAGS ${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}})
+
   add_subdirectory(src)
 endif()
 
@@ -207,6 +298,7 @@ endif()
 
 # ============= Tests =============
 if(WITH_TESTS)
+  include(CTest)
   # Number of mpi processes used to run tests.
   set(NBPROCS_FOR_TESTS 8)
   if(NOT USE_MPI)
@@ -219,16 +311,19 @@ endif(WITH_TESTS)
 # ============= Summary =============
 if(VERBOSE_MODE)
   message(STATUS "====================== Summary ======================")
-  message(STATUS " Python libs found : ${PYTHONLIBS_FOUND}")
   message(STATUS " Python libraries : ${PYTHON_LIBRARIES}")
   message(STATUS " Python include : ${PYTHON_INCLUDE_DIRS}")
   message(STATUS " Python version : ${PYTHON_VERSION_STRING}")
   message(STATUS " Python executable : ${PYTHON_EXECUTABLE}")
   message(STATUS " Python user lib : ${PYTHON_LIBRARY}")
-  message(STATUS " Python user include : ${PYTHON_INCLUDE_DIR}")
-  message(STATUS " Install directory : ${CMAKE_INSTALL_PREFIX}")
-  message(STATUS " Fortran compiler : ${CMAKE_Fortran_COMPILER}")
-  message(STATUS " C++ compiler : ${CMAKE_CXX_COMPILER}")
+  message(STATUS " ${PACKAGE_NAME} will be installed in : ${HYSOP_PYTHON_INSTALL_DIR}")
+  message(STATUS " ${PACKAGE_NAME} will be built in ${HYSOP_BUILD_PYTHONPATH}")
+  if(WITH_LIB_FORTRAN)
+    message(STATUS " Fortran compiler : ${CMAKE_Fortran_COMPILER}")
+  endif()
+  if(WITH_LIB_CXX)
+    message(STATUS " CXX compiler : ${CMAKE_CXX_COMPILER}")
+  endif()
   message(STATUS " Sources are in : ${CMAKE_SOURCE_DIR}")
   message(STATUS " Project uses MPI : ${USE_MPI}")
   message(STATUS " Project uses Scales : ${WITH_SCALES}")
@@ -246,7 +341,7 @@ if(VERBOSE_MODE)
   message(STATUS " 'make clean' to clean build directory.")
   message(STATUS " 'make uninstall' to clean install directory. Dry-run (make -n uninstall) is advisable to check what will really be deleted.")
   message(STATUS "\n\n/!\\ Warning /!\\ : depending on your python environment configuration, you may need to set PYTHONPATH.")
-  message("Try to run python -c 'import hysop'. If it fails, add ${${PROJECT_NAME}_PYTHONPATH} to PYTHONPATH environment variable.")
-  message("Example : \n export PYTHONPATH=${${PROJECT_NAME}_PYTHONPATH}:\${PYTHONPATH}\n")
+  message("Try to run python -c 'import hysop'. If it fails, add ${HYSOP_PYTHON_INSTALL_DIR} to PYTHONPATH environment variable.")
+  message("Example : \n export PYTHONPATH=${HYSOP_PYTHON_INSTALL_DIR}:\${PYTHONPATH}\n")
 endif()
 
diff --git a/HySoP/hysop/.f2py_f2cmap b/HySoP/hysop/.f2py_f2cmap
new file mode 100644
index 0000000000000000000000000000000000000000..99f5f3517caf6260a22a9851a15f66443a1045d4
--- /dev/null
+++ b/HySoP/hysop/.f2py_f2cmap
@@ -0,0 +1,3 @@
+{'integer':{'c_int':'int'}, 'real':{'real64':'double', 'wp':'double'}}
+
+
diff --git a/HySoP/hysop/domain/tests/test_box.py b/HySoP/hysop/domain/tests/test_box.py
index ca231e8ceec97c9634942eda24e8d32ad2fed1e3..f23e357d3558f4ffb5e6abce6164fe5ef25b3dde 100644
--- a/HySoP/hysop/domain/tests/test_box.py
+++ b/HySoP/hysop/domain/tests/test_box.py
@@ -124,7 +124,7 @@ def test_topo_plane():
 def test_topo_from_mesh():
     # e.g. for fftw
     dom = Box(proc_tasks=proc_tasks)
-    from hysop.f2py import fftw2py
+    from hysop.f2hysop import fftw2py
     if dom.is_on_task(CPU):
         localres, global_start = fftw2py.init_fftw_solver(
             r3D.resolution, dom.length, comm=comm_s.py2f())
diff --git a/HySoP/hysop/f2hysop.pyf.in b/HySoP/hysop/f2hysop.pyf.in
new file mode 100644
index 0000000000000000000000000000000000000000..16fc16b58562b4e0ad0c89503c837ca78e130baf
--- /dev/null
+++ b/HySoP/hysop/f2hysop.pyf.in
@@ -0,0 +1,16 @@
+  !    -*- f90 -*-
+  ! Note: the context of this file is case sensitive.
+  
+  python module f2hysop ! in 
+  interface
+     ! Example
+     include '@CMAKE_SOURCE_DIR@/hysop/fortran/template.pyf'
+     ! precision 
+     include '@CMAKE_SOURCE_DIR@/hysop/f2py/parameters.pyf'
+     ! fftw
+     include '@CMAKE_SOURCE_DIR@/hysop/f2py/fftw2py.pyf'
+     ! scales
+     include '@CMAKE_SOURCE_DIR@/hysop/f2py/scales2py.pyf'
+
+  end interface
+end python module f2hysop
diff --git a/HySoP/hysop/f2py/fftw2py.pyf b/HySoP/hysop/f2py/fftw2py.pyf
new file mode 100644
index 0000000000000000000000000000000000000000..3153e51b9c80f7ba98960bebb9378050867e2e50
--- /dev/null
+++ b/HySoP/hysop/f2py/fftw2py.pyf
@@ -0,0 +1,130 @@
+!    -*- f90 -*-
+! Note: the context of this file is case sensitive.
+
+module fftw2py ! in fftw2py.f90
+    use fft3d
+    use mpi
+    use client_data
+    use hysopparam
+    use fft2d
+    subroutine init_fftw_solver(resolution,lengths,comm,datashape,offset,dim,fftw_type_real) ! in fftw2py.f90:fftw2py
+        integer dimension(dim),intent(in) :: resolution
+        real(kind=pk) dimension(dim),intent(in),depend(dim) :: lengths
+        integer intent(in) :: comm
+        integer(kind=ik) dimension(dim),intent(out),depend(dim) :: datashape
+        integer(kind=ik) dimension(dim),intent(out),depend(dim) :: offset
+        integer, optional,intent(hide),check(len(resolution)>=dim),depend(resolution) :: dim=len(resolution)
+        logical, optional,intent(in) :: fftw_type_real=1
+    end subroutine init_fftw_solver
+    subroutine init_fftw_solver_scalar(resolution,lengths,comm,datashape,offset,dim,fftw_type_real) ! in fftw2py.f90:fftw2py
+        integer dimension(dim),intent(in) :: resolution
+        real(kind=pk) dimension(dim),intent(in),depend(dim) :: lengths
+        integer intent(in) :: comm
+        integer(kind=ik) dimension(dim),intent(out),depend(dim) :: datashape
+        integer(kind=ik) dimension(dim),intent(out),depend(dim) :: offset
+        integer, optional,intent(hide),check(len(resolution)>=dim),depend(resolution) :: dim=len(resolution)
+        logical, optional,intent(in) :: fftw_type_real=1
+    end subroutine init_fftw_solver_scalar
+    subroutine clean_fftw_solver(dim) ! in fftw2py.f90:fftw2py
+        integer intent(in) :: dim
+    end subroutine clean_fftw_solver
+    subroutine solve_poisson_2d(omega,velocity_x,velocity_y,ghosts_vort,ghosts_velo) ! in fftw2py.f90:fftw2py
+        real(kind=pk) dimension(:,:),intent(in) :: omega
+        real(kind=pk) dimension(size(omega,1),size(omega,2)),intent(in,out),depend(omega,omega) :: velocity_x
+        real(kind=pk) dimension(size(omega,1),size(omega,2)),intent(in,out),depend(omega,omega) :: velocity_y
+        integer dimension(2),intent(in) :: ghosts_vort
+        integer dimension(2),intent(in) :: ghosts_velo
+    end subroutine solve_poisson_2d
+    subroutine solve_diffusion_2d(nudt,omega,ghosts_vort) ! in fftw2py.f90:fftw2py
+        real(kind=pk) intent(in) :: nudt
+        real(kind=pk) dimension(:,:),intent(in,out) :: omega
+        integer dimension(2),intent(in) :: ghosts_vort
+    end subroutine solve_diffusion_2d
+    subroutine solve_poisson_3d(omega_x,omega_y,omega_z,velocity_x,velocity_y,velocity_z,ghosts_vort,ghosts_velo) ! in fftw2py.f90:fftw2py
+        real(kind=pk) dimension(:,:,:),intent(in) :: omega_x
+        real(kind=pk) dimension(:,:,:),intent(in) :: omega_y
+        real(kind=pk) dimension(:,:,:),intent(in) :: omega_z
+        real(kind=pk) dimension(size(omega_x,1),size(omega_y,2),size(omega_z,3)),intent(in,out),depend(omega_x,omega_y,omega_z) :: velocity_x
+        real(kind=pk) dimension(size(omega_x,1),size(omega_y,2),size(omega_z,3)),intent(in,out),depend(omega_x,omega_y,omega_z) :: velocity_y
+        real(kind=pk) dimension(size(omega_x,1),size(omega_y,2),size(omega_z,3)),intent(in,out),depend(omega_x,omega_y,omega_z) :: velocity_z
+        integer dimension(3),intent(in) :: ghosts_vort
+        integer dimension(3),intent(in) :: ghosts_velo
+    end subroutine solve_poisson_3d
+    subroutine solve_poisson_2d_c(omega,velocity_x,velocity_y) ! in fftw2py.f90:fftw2py
+        complex(kind=pk) dimension(:,:),intent(in) :: omega
+        complex(kind=pk) dimension(size(omega,1),size(omega,2)),intent(in,out),depend(omega,omega) :: velocity_x
+        complex(kind=pk) dimension(size(omega,1),size(omega,2)),intent(in,out),depend(omega,omega) :: velocity_y
+    end subroutine solve_poisson_2d_c
+    subroutine solve_poisson_3d_c(omega_x,omega_y,omega_z,velocity_x,velocity_y,velocity_z) ! in fftw2py.f90:fftw2py
+        complex(kind=pk) dimension(:,:,:),intent(in) :: omega_x
+        complex(kind=pk) dimension(:,:,:),intent(in) :: omega_y
+        complex(kind=pk) dimension(:,:,:),intent(in) :: omega_z
+        complex(kind=pk) dimension(size(omega_x,1),size(omega_y,2),size(omega_z,3)),intent(in,out),depend(omega_x,omega_y,omega_z) :: velocity_x
+        complex(kind=pk) dimension(size(omega_x,1),size(omega_y,2),size(omega_z,3)),intent(in,out),depend(omega_x,omega_y,omega_z) :: velocity_y
+        complex(kind=pk) dimension(size(omega_x,1),size(omega_y,2),size(omega_z,3)),intent(in,out),depend(omega_x,omega_y,omega_z) :: velocity_z
+    end subroutine solve_poisson_3d_c
+    subroutine solve_curl_diffusion_3d(nudt,velocity_x,velocity_y,velocity_z,omega_x,omega_y,omega_z,ghosts_velo,ghosts_vort) ! in fftw2py.f90:fftw2py
+        real(kind=pk) intent(in) :: nudt
+        real(kind=pk) dimension(:,:,:),intent(in) :: velocity_x
+        real(kind=pk) dimension(:,:,:),intent(in) :: velocity_y
+        real(kind=pk) dimension(:,:,:),intent(in) :: velocity_z
+        real(kind=pk) dimension(size(velocity_x,1),size(velocity_y,2),size(velocity_z,3)),intent(in,out),depend(velocity_x,velocity_y,velocity_z) :: omega_x
+        real(kind=pk) dimension(size(velocity_x,1),size(velocity_y,2),size(velocity_z,3)),intent(in,out),depend(velocity_x,velocity_y,velocity_z) :: omega_y
+        real(kind=pk) dimension(size(velocity_x,1),size(velocity_y,2),size(velocity_z,3)),intent(in,out),depend(velocity_x,velocity_y,velocity_z) :: omega_z
+        integer dimension(3),intent(in) :: ghosts_velo
+        integer dimension(3),intent(in) :: ghosts_vort
+    end subroutine solve_curl_diffusion_3d
+    subroutine solve_diffusion_3d(nudt,omega_x,omega_y,omega_z,ghosts) ! in fftw2py.f90:fftw2py
+        real(kind=pk) intent(in) :: nudt
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: omega_x
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: omega_y
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: omega_z
+        integer dimension(3),intent(in) :: ghosts
+    end subroutine solve_diffusion_3d
+    subroutine projection_om_3d(omega_x,omega_y,omega_z,ghosts) ! in fftw2py.f90:fftw2py
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: omega_x
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: omega_y
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: omega_z
+        integer dimension(3),intent(in) :: ghosts
+    end subroutine projection_om_3d
+    subroutine multires_om_3d(dxf,dyf,dzf,omega_x,omega_y,omega_z,ghosts) ! in fftw2py.f90:fftw2py
+        real(kind=pk) intent(in) :: dxf
+        real(kind=pk) intent(in) :: dyf
+        real(kind=pk) intent(in) :: dzf
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: omega_x
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: omega_y
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: omega_z
+        integer dimension(3),intent(in) :: ghosts
+    end subroutine multires_om_3d
+    subroutine pressure_3d(pressure,ghosts) ! in fftw2py.f90:fftw2py
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: pressure
+        integer dimension(3),intent(in) :: ghosts
+    end subroutine pressure_3d
+    subroutine solve_curl_3d(velocity_x,velocity_y,velocity_z,omega_x,omega_y,omega_z,ghosts_velo,ghosts_vort) ! in fftw2py.f90:fftw2py
+        real(kind=pk) dimension(:,:,:),intent(in) :: velocity_x
+        real(kind=pk) dimension(:,:,:),intent(in) :: velocity_y
+        real(kind=pk) dimension(:,:,:),intent(in) :: velocity_z
+        real(kind=pk) dimension(size(velocity_x,1),size(velocity_y,2),size(velocity_z,3)),intent(in,out),depend(velocity_x,velocity_y,velocity_z) :: omega_x
+        real(kind=pk) dimension(size(velocity_x,1),size(velocity_y,2),size(velocity_z,3)),intent(in,out),depend(velocity_x,velocity_y,velocity_z) :: omega_y
+        real(kind=pk) dimension(size(velocity_x,1),size(velocity_y,2),size(velocity_z,3)),intent(in,out),depend(velocity_x,velocity_y,velocity_z) :: omega_z
+        integer dimension(3),intent(in) :: ghosts_velo
+        integer dimension(3),intent(in) :: ghosts_vort
+    end subroutine solve_curl_3d
+    subroutine solve_curl_2d(velocity_x,velocity_y,omega_z,ghosts_velo,ghosts_vort) ! in fftw2py.f90:fftw2py
+        real(kind=pk) dimension(:,:),intent(in) :: velocity_x
+        real(kind=pk) dimension(:,:),intent(in) :: velocity_y
+        real(kind=pk) dimension(size(velocity_x,1),size(velocity_x,2)),intent(in,out),depend(velocity_x,velocity_x) :: omega_z
+        integer dimension(2),intent(in) :: ghosts_velo
+        integer dimension(2),intent(in) :: ghosts_vort
+    end subroutine solve_curl_2d
+    subroutine spectrum_3d(field,spectrum,wavelengths,ghosts,length) ! in fftw2py.f90:fftw2py
+        real(kind=pk) dimension(:,:,:),intent(in) :: field
+        real(kind=pk) dimension(:),intent(inout) :: spectrum
+        real(kind=pk) dimension(:),intent(inout) :: wavelengths
+        integer dimension(3),intent(in) :: ghosts
+        real(kind=pk) intent(in) :: length
+    end subroutine spectrum_3d
+end module fftw2py
+
+! This file was auto-generated with f2py (version:2).
+! See http://cens.ioc.ee/projects/f2py2e/
diff --git a/HySoP/hysop/f2py/parameters.pyf b/HySoP/hysop/f2py/parameters.pyf
new file mode 100644
index 0000000000000000000000000000000000000000..caefb2e4fd8de7978f125e0bd76d227072b60866
--- /dev/null
+++ b/HySoP/hysop/f2py/parameters.pyf
@@ -0,0 +1,14 @@
+!    -*- f90 -*-
+! Note: the context of this file is case sensitive.
+
+module hysopparam ! in parameters.f90
+    integer, parameter,optional :: pk=8
+    integer, parameter,optional :: ik=8
+end module hysopparam
+module hysopparam_sp ! in parameters.f90
+    integer, parameter,optional :: pk=4
+    integer, parameter,optional :: ik=8
+end module hysopparam_sp
+
+! This file was auto-generated with f2py (version:2).
+! See http://cens.ioc.ee/projects/f2py2e/
diff --git a/HySoP/hysop/f2py/scales2py.pyf b/HySoP/hysop/f2py/scales2py.pyf
new file mode 100644
index 0000000000000000000000000000000000000000..584336cfac437a80667dccfa9dcc3cf15bcf2e87
--- /dev/null
+++ b/HySoP/hysop/f2py/scales2py.pyf
@@ -0,0 +1,63 @@
+!    -*- f90 -*-
+! Note: the context of this file is case sensitive.
+
+module scales2py ! in scales2py.f90
+    use advec, only: advec_step_inter_two,advec_step_inter_basic,advec_step,advec_init
+    use interpolation_velo, only: interpol_init
+    use cart_topology, only: cart_rank,coord,n_proc,discretisation_set_mesh_velo,cart_create,set_group_size,discretisation_create
+    use advec_vect, only: advec_step_vect,advec_step_inter_basic_vect
+    use mpi
+    use hysopparam
+    subroutine init_advection_solver(ncells,lengths,topodims,main_comm,datashape,offset,dim,order,dim_split) ! in scales2py.f90:scales2py
+        integer dimension(dim),intent(in) :: ncells
+        real(kind=pk) dimension(dim),intent(in),depend(dim) :: lengths
+        integer dimension(dim),intent(in),depend(dim) :: topodims
+        integer intent(in) :: main_comm
+        integer(kind=ik) dimension(dim),intent(out),depend(dim) :: datashape
+        integer(kind=ik) dimension(dim),intent(out),depend(dim) :: offset
+        integer, optional,intent(hide),depend(ncells) :: dim=len(ncells)
+        character*(*), optional,intent(in) :: order='p_o2'
+        character*(*), optional,intent(in) :: dim_split
+    end subroutine init_advection_solver
+    subroutine init_multiscale(nx,ny,nz,formula) ! in scales2py.f90:scales2py
+        integer intent(in) :: nx
+        integer intent(in) :: ny
+        integer intent(in) :: nz
+        character*(*), optional,intent(in) :: formula
+    end subroutine init_multiscale
+    subroutine solve_advection(dt,vx,vy,vz,scal) ! in scales2py.f90:scales2py
+        real(kind=pk) intent(in) :: dt
+        real(kind=pk) dimension(:,:,:),intent(in) :: vx
+        real(kind=pk) dimension(:,:,:),intent(in) :: vy
+        real(kind=pk) dimension(:,:,:),intent(in) :: vz
+        real(kind=pk) dimension(size(vx,1),size(vx,2),size(vx,3)),intent(in,out),depend(size(vx,1)) :: scal
+    end subroutine solve_advection
+    subroutine solve_advection_vect(dt,vx,vy,vz,cx,cy,cz) ! in scales2py.f90:scales2py
+        real(kind=pk) intent(in) :: dt
+        real(kind=pk) dimension(:,:,:),intent(in) :: vx
+        real(kind=pk) dimension(:,:,:),intent(in) :: vy
+        real(kind=pk) dimension(:,:,:),intent(in) :: vz
+        real(kind=pk) dimension(size(vx,1),size(vx,2),size(vx,3)),intent(in,out),depend(size(vx,1)) :: cx
+        real(kind=pk) dimension(size(vx,1),size(vx,2),size(vx,3)),intent(in,out),depend(size(vx,1)) :: cy
+        real(kind=pk) dimension(size(vx,1),size(vx,2),size(vx,3)),intent(in,out),depend(size(vx,1)) :: cz
+    end subroutine solve_advection_vect
+    subroutine solve_advection_inter_basic(dt,vx,vy,vz,scal) ! in scales2py.f90:scales2py
+        real(kind=pk) intent(in) :: dt
+        real(kind=pk) dimension(:,:,:),intent(in) :: vx
+        real(kind=pk) dimension(:,:,:),intent(in) :: vy
+        real(kind=pk) dimension(:,:,:),intent(in) :: vz
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: scal
+    end subroutine solve_advection_inter_basic
+    subroutine solve_advection_inter_basic_vec(dt,vx,vy,vz,cx,cy,cz) ! in scales2py.f90:scales2py
+        real(kind=pk) intent(in) :: dt
+        real(kind=pk) dimension(:,:,:),intent(in) :: vx
+        real(kind=pk) dimension(:,:,:),intent(in) :: vy
+        real(kind=pk) dimension(:,:,:),intent(in) :: vz
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: cx
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: cy
+        real(kind=pk) dimension(:,:,:),intent(in,out) :: cz
+    end subroutine solve_advection_inter_basic_vec
+end module scales2py
+
+! This file was auto-generated with f2py (version:2).
+! See http://cens.ioc.ee/projects/f2py2e/
diff --git a/HySoP/hysop/fakef2py/__init__.py b/HySoP/hysop/fakef2py/__init__.py
index 58da6ae35dd3554bf354e34a5f0878ee4a7c427c..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/HySoP/hysop/fakef2py/__init__.py
+++ b/HySoP/hysop/fakef2py/__init__.py
@@ -1,24 +0,0 @@
-## @package hysop.f2py
-# f2py interfaces to fortran files.
-#
-# Driver routines to generate python functions
-# from fortran routines using f2py.
-#
-# Available interfaces :
-# - fftw : driver for fftw-mpi (fortran) routines.
-#   Poisson and Diffusion solvers.
-# - scales : advection solver (only 3D).
-#
-# Usage :
-# \code
-# import hysop.f2py
-# ppfft = hysop.f2py.fftw2py
-# scales = hysop.f2py.scales2py
-# ...
-# ppfft.init_fftw_solver(...)
-# scales.init_advection_solver(...)
-# # List of functionnalities and help :
-# dir(scales)
-# dir(ppfft)
-# print ppfft.init_fftw_solver.__doc__
-# \endcode
diff --git a/HySoP/hysop/fortran/template.f95 b/HySoP/hysop/fortran/template.f95
new file mode 100644
index 0000000000000000000000000000000000000000..77685fb293e3c9d23968b5f00494b6a35bde7c2b
--- /dev/null
+++ b/HySoP/hysop/fortran/template.f95
@@ -0,0 +1,27 @@
+  !! Template file - Provide an example
+  !! to write f2py interface between fortran and python
+
+
+module template_f2py
+
+  implicit none
+
+  !> a global var
+  integer, parameter :: var1 = 12
+ 
+contains
+
+  !> do something ...
+  subroutine check_f2py(input, output)
+    
+    !> input array
+    real(kind=8), dimension(:,:), intent(in) :: input
+    !> output array
+    real(kind=8), dimension(:,:), intent(inout) :: output
+
+    print *, 'template f2py for tab'
+    output(:,:) = 2 * input(:,:)
+    print *, 'aha hah', output(1,1)
+  end subroutine check_f2py
+  
+end module template_f2py
diff --git a/HySoP/hysop/fortran/template.pyf b/HySoP/hysop/fortran/template.pyf
new file mode 100644
index 0000000000000000000000000000000000000000..1564dabe01205ce1ca54ef2de8c54484b2eb47fc
--- /dev/null
+++ b/HySoP/hysop/fortran/template.pyf
@@ -0,0 +1,13 @@
+!    -*- f90 -*-
+! Note: the context of this file is case sensitive.
+
+module template_f2py ! in template.f95
+    integer, parameter,optional :: var1=12
+    subroutine check_f2py(input,output) ! in template.f95:template_f2py
+        real(kind=8), dimension(:, :), intent(in) :: input
+        real(kind=8), dimension(size(input,1), size(input,2)), intent(in,out), depend(input,input) :: output
+    end subroutine check_f2py
+end module template_f2py
+
+! This file was auto-generated with f2py (version:2).
+! See http://cens.ioc.ee/projects/f2py2e/
diff --git a/HySoP/hysop/operator/advection.py b/HySoP/hysop/operator/advection.py
index 130785a895cdd956f1bdb8fa9dc182de2f89a1f0..fd5abc420271d1b99a0bfd825aea36bb23196683 100644
--- a/HySoP/hysop/operator/advection.py
+++ b/HySoP/hysop/operator/advection.py
@@ -215,7 +215,7 @@ class Advection(Computational):
 
         # Check if topos need to be created
         build_topos = self._check_variables()
-        from hysop.f2py import scales2py as scales
+        from hysop.f2hysop import scales2py as scales
 
         # Scales, single resolution
         if self._single_topo:
@@ -281,7 +281,7 @@ class Advection(Computational):
         self._discretize_vars()
 
     def _create_scales_topo(self, d3d, order, splitting):
-        from hysop.f2py import scales2py as scales
+        from hysop.f2hysop import scales2py as scales
         comm = self._mpis.comm
         topodims = [1, 1, comm.Get_size()]
         msg = 'Wrong type for parameter discretization (at init).' + str(self._discretization)
@@ -300,7 +300,7 @@ class Advection(Computational):
             discretization=d3d, cdir=ZDIR)
 
     def _check_scales_topo(self, toporef, order, splitting):
-        from hysop.f2py import scales2py as scales
+        from hysop.f2hysop import scales2py as scales
         # In that case, self._discretization must be
         # a Cartesian object, used for all fields.
         # We use it to initialize scales solver
diff --git a/HySoP/hysop/operator/computational.py b/HySoP/hysop/operator/computational.py
index d5992a9add91cced0f67c2765411c6d263dfa6fd..31ecca3eb47ea209d05235adb12966703427b9c9 100644
--- a/HySoP/hysop/operator/computational.py
+++ b/HySoP/hysop/operator/computational.py
@@ -246,7 +246,7 @@ class Computational(Operator):
         assert self._single_topo, 'All fields must use the same topology.'
         # Get local mesh parameters from fftw
         comm = self._mpis.comm
-        from hysop.f2py import fftw2py
+        from hysop.f2hysop import fftw2py
         if build_topos:
             # In that case, self._discretization must be
             # a Discretization object, used for all fields.
diff --git a/HySoP/hysop/operator/curlAndDiffusion.py b/HySoP/hysop/operator/curlAndDiffusion.py
index e8958501cad35ec1cbcf02ddee1b48ba54c83712..b171bd647382fd83b57f56e79cbc81d69e9b9c69 100644
--- a/HySoP/hysop/operator/curlAndDiffusion.py
+++ b/HySoP/hysop/operator/curlAndDiffusion.py
@@ -7,7 +7,7 @@ Operator for diffusion problem.
 """
 from hysop.operator.continuous import Operator
 try:
-    from hysop.f2py import fftw2py
+    from hysop.f2hysop import fftw2py
 except ImportError:
     from hysop.fakef2py import fftw2py
 from hysop.operator.discrete.diffusion_fft import DiffusionFFT
diff --git a/HySoP/hysop/operator/discrete/curlAndDiffusion_fft.py b/HySoP/hysop/operator/discrete/curlAndDiffusion_fft.py
index 73c6500618f4b9506f1db2121fa8435fbbd4f453..d8828c7fd1e5c6769737938358f7c09c5a3352f4 100644
--- a/HySoP/hysop/operator/discrete/curlAndDiffusion_fft.py
+++ b/HySoP/hysop/operator/discrete/curlAndDiffusion_fft.py
@@ -4,7 +4,7 @@
 Discrete Diffusion operator using FFTW (fortran)
 """
 try:
-    from hysop.f2py import fftw2py
+    from hysop.f2hysop import fftw2py
 except ImportError:
     from hysop.fakef2py import fftw2py
 from hysop.operator.discrete.discrete import DiscreteOperator
diff --git a/HySoP/hysop/operator/discrete/differential.py b/HySoP/hysop/operator/discrete/differential.py
index abd6e7ded1e3cbbc574e600002e632d6ebbe8cf2..6c9360a518c7a5b9ec798d7bc782259d535a6baa 100644
--- a/HySoP/hysop/operator/discrete/differential.py
+++ b/HySoP/hysop/operator/discrete/differential.py
@@ -18,7 +18,7 @@ from abc import ABCMeta, abstractmethod
 from hysop.numerics.update_ghosts import UpdateGhosts
 from hysop.methods_keys import SpaceDiscretisation
 try:
-    from hysop.f2py import fftw2py
+    from hysop.f2hysop import fftw2py
 except ImportError:
     from hysop.fakef2py import fftw2py
 import hysop.default_methods as default
diff --git a/HySoP/hysop/operator/discrete/diffusion_fft.py b/HySoP/hysop/operator/discrete/diffusion_fft.py
index fe7a3822b86b986deebf6684fe2019bef2cc6004..21401ea3aca6de152d10d11fde0d72a2f5816af5 100644
--- a/HySoP/hysop/operator/discrete/diffusion_fft.py
+++ b/HySoP/hysop/operator/discrete/diffusion_fft.py
@@ -4,7 +4,7 @@
 Discrete Diffusion operator using FFTW (fortran)
 """
 try:
-    from hysop.f2py import fftw2py
+    from hysop.f2hysop import fftw2py
 except ImportError:
     from hysop.fakef2py import fftw2py
 from hysop.operator.discrete.discrete import DiscreteOperator
diff --git a/HySoP/hysop/operator/discrete/poisson_fft.py b/HySoP/hysop/operator/discrete/poisson_fft.py
index 379b63244976337c3c76b4452cca134101e0e048..7aeb18b223097e80bdf64c13f300a5b023a3e553 100644
--- a/HySoP/hysop/operator/discrete/poisson_fft.py
+++ b/HySoP/hysop/operator/discrete/poisson_fft.py
@@ -5,7 +5,7 @@ Discrete operator for Poisson problem (fftw based)
 """
 import hysop.tools.numpywrappers as npw
 try:
-    from hysop.f2py import fftw2py
+    from hysop.f2hysop import fftw2py
 except ImportError:
     from hysop.fakef2py import fftw2py
 
diff --git a/HySoP/hysop/operator/discrete/reprojection.py b/HySoP/hysop/operator/discrete/reprojection.py
index 57ce89f6afde6c0034a800e05dd784562402c945..76a1ba3e4796e00adc926606b8f8aaa9a1073e21 100644
--- a/HySoP/hysop/operator/discrete/reprojection.py
+++ b/HySoP/hysop/operator/discrete/reprojection.py
@@ -104,7 +104,7 @@ class Reprojection(DiscreteOperator):
         # computation of the reprojection criterion and mpi-reduction
         criterion = d1 / d2
         criterion = self.vorticity.topology.comm.allreduce(
-            criterion, HYSOP_MPI_REAL, op=MPI.MAX)
+            criterion, op=MPI.MAX)
         # is reprojection of vorticity needed for the next time step ?
         if criterion > self.threshold:
             self.frequency = 1
diff --git a/HySoP/hysop/operator/discrete/scales_advection.py b/HySoP/hysop/operator/discrete/scales_advection.py
index 8c035f677fa68d7c083be4930a18a1996449cd32..04b47c09de4ac93930d3778ded4f74a2397822e8 100644
--- a/HySoP/hysop/operator/discrete/scales_advection.py
+++ b/HySoP/hysop/operator/discrete/scales_advection.py
@@ -5,7 +5,7 @@ Discrete Advection operator based on scales library (Jean-Baptiste)
 
 """
 try:
-    from hysop.f2py import scales2py
+    from hysop.f2hysop import scales2py
 except ImportError:
     from hysop.fakef2py import scales2py
 from hysop.operator.discrete.discrete import DiscreteOperator
diff --git a/HySoP/hysop/operator/discrete/spectrum.py b/HySoP/hysop/operator/discrete/spectrum.py
index 72502d24b0947355138e15a1df68004a1046a45d..9b1bdb0560fd808a3db431f61a9db97b28124118 100644
--- a/HySoP/hysop/operator/discrete/spectrum.py
+++ b/HySoP/hysop/operator/discrete/spectrum.py
@@ -4,7 +4,7 @@
 Discrete Spectrum operator using FFTW (fortran)
 """
 try:
-    from hysop.f2py import fftw2py
+    from hysop.f2hysop import fftw2py
 except ImportError:
     from hysop.fakef2py import fftw2py
 from hysop.operator.discrete.discrete import DiscreteOperator
diff --git a/HySoP/setup.py.in b/HySoP/setup.py.in
index 6c8cd130ba9342a2d1802ddbe59140e6adafa6fc..6a08d5f70a8d4bcecd0843ab07abacadadcfb94f 100644
--- a/HySoP/setup.py.in
+++ b/HySoP/setup.py.in
@@ -9,6 +9,52 @@ from numpy.distutils.misc_util import Configuration
 import os
 import glob
 
+# tools to deal with fortran dependencies.
+import sys
+sys.path.append('@CMAKE_SOURCE_DIR@/')
+import sort_f90
+
+
+def create_fortran_extension(name, pyf_file=None, src_dirs=None, sources=None,
+                             libdir=None, libs=None, debug_mode=0):
+    """Create a new f2py module from fortran files
+    """
+    if sources is None:
+        sources = []
+        assert src_dirs is not None
+
+    for sdir in src_dirs:
+        sources += glob.glob(os.path.join(sdir, '*.f95'))
+        sources += glob.glob(os.path.join(sdir, '*.f90'))
+    f2py_options = ['--no-lower', '--no-wrap-functions']
+    options = []
+    # Reorder source list with fortran modules
+    # dependencies. It seems that this is not taken into
+    # account in f2py or distutils.
+    if pyf_file is not None:
+        sources.append(pyf_file)
+    sources = sort_f90.sort(sources)
+    if debug_mode == 0:
+        options.append(('F2PY_REPORT_ON_ARRAY_COPY', '1'))
+        if os.uname()[0] == 'Linux':
+            options.append(('F2PY_REPORT_ATEXIT', '1'))
+    inc_dir = '@MPI_Fortran_INCLUDE_PATH@'.split(';')
+    #  To avoid -I -I in compiler call, which results in a bug:
+    while inc_dir.count('') > 0:
+        inc_dir.remove('')
+    inc_dir.append('@CMAKE_BINARY_DIR@/Modules')
+    fortran_flags = ['@Fortran_FLAGS@']
+    ext_fort = Extension(name=name,
+                         sources=sources,
+                         f2py_options=f2py_options,
+                         include_dirs=inc_dir,
+                         define_macros=options,
+                         library_dirs=libdir,
+                         libraries=libs,
+                         extra_f90_compile_args=fortran_flags
+                         )
+    return ext_fort
+
 
 def create_swig_extension(name, src_dirs=None, sources=None):
     """Create a python module from C++ files, using swig
@@ -44,6 +90,7 @@ def create_swig_extension(name, src_dirs=None, sources=None):
     return swig_ext
 
 
+# ------------ Set list of packages required to build the module -------------
 # Full package name
 name = '@PYPACKAGE_NAME@'
 # List of modules (directories) to be included
@@ -81,30 +128,26 @@ if "@WITH_TESTS@" is "ON":
 # Enable this to get debug info
 DISTUTILS_DEBUG = 1
 
+# ------------ Extensions (f2py, cython, ...) setup ------------
+
 ext_modules = []
 
-# Check if libhysop was created
+# Check if fortran interface is enabled
 enable_fortran = "@WITH_LIB_FORTRAN@"
-
+ext = {}
 
 if enable_fortran is "ON":
-    inc_dir = '@MPI_Fortran_INCLUDE_PATH@'.split(';')
-    #  To avoid -I -I in compiler call. Result in a bug:
-    while inc_dir.count('') > 0:
-        inc_dir.remove('')
-
-    hysop_dir = '@CMAKE_BINARY_DIR@/Modules'
-    inc_dir.append(hysop_dir)
-    fortran_dir = \
-        '@CMAKE_SOURCE_DIR@/hysop/f2py/'
+    fortran_root = \
+        '@CMAKE_SOURCE_DIR@/hysop'
     hysop_libdir = ['@CMAKE_BINARY_DIR@/src']
     hysoplib = ['@HYSOP_LIBRARY_NAME@']
     f2py_options = ['--no-lower']
-    fortran_src = []
+    fortran_src = set([])
+    # -- fftw fortran sources --
     withfftw = "@WITH_FFTW@"
     if withfftw is "ON":
-        fortran_src.append(fortran_dir + 'parameters.f90')
-        fortran_src.append(fortran_dir + 'fftw2py.f90')
+        fortran_src.add('f2py/parameters.f90')
+        fortran_src.add('f2py/fftw2py.f90')
         fftwdir = '@FFTWLIB@'
         hysoplib.append('fftw3')
         hysoplib.append('fftw3_mpi')
@@ -112,28 +155,45 @@ if enable_fortran is "ON":
     else:
         packages.append('hysop.fakef2py')
         packages.append('hysop.fakef2py.fftw2py')
+    # -- scales sources --
     withscales = '@WITH_SCALES@'
     if withscales is "ON":
-        if withfftw is "OFF":
-            fortran_src.append(fortran_dir + 'parameters.f90')
-        fortran_src.append(fortran_dir + 'scales2py.f90')
+        fortran_src.add('f2py/parameters.f90')
+        fortran_src.add('f2py/scales2py.f90')
     else:
         packages.append('hysop.fakef2py')
         packages.append('hysop.fakef2py.scales2py')
+    # -- set full path to fortran sources --
+    fortran_src = list(fortran_src)
+    for i in xrange(len(fortran_src)):
+        fortran_src[i] = os.path.join(fortran_root, fortran_src[i])
+
+    # === Draft for future implementation of fortran interface ===
+    # -- f2py signature file --
+    pyf_file = os.path.join(fortran_root, 'f2hysop.pyf')
+    # -- list of directories which contains fortran sources --
+    # those dirs must be in hysop package directory
+    subdirs = ['fortran',
+               ]
+    num_dirs = []
+    for sd in subdirs:
+        num_dirs.append(os.path.join(fortran_root, sd))
+
+    # create python interface to fortran sources
+    # For the moment, it includes the 'old' interface
+    # to scales and fftw (in sources) and the new
+    # interface, in src_dirs
+    ext['f2hysop'] = create_fortran_extension(
+        name='hysop.f2hysop',
+        sources=fortran_src,
+        libdir=hysop_libdir,
+        libs=hysoplib,
+        pyf_file=pyf_file,
+        src_dirs=num_dirs)
+
+    for ex in ext:
+        ext_modules.append(ext[ex])
 
-    options = [('F2PY_REPORT_ON_ARRAY_COPY', '1')]
-    if os.uname()[0] == 'Linux':
-        options.append(('F2PY_REPORT_ATEXIT', '1'))
-
-    parpyModule = Extension(name='hysop.f2py',
-                            f2py_options=f2py_options,
-                            sources=fortran_src,
-                            include_dirs=inc_dir,
-                            library_dirs=hysop_libdir,
-                            libraries=hysoplib,
-                            define_macros=options
-                            )
-    ext_modules.append(parpyModule)
 else:
     packages.append('hysop.fakef2py')
     packages.append('hysop.fakef2py.scales2py')
@@ -142,18 +202,21 @@ else:
 data_files = []
 
 # --- C++ files and swig interface --
-# path to .i files
-swig_dirs = [os.path.join('@CMAKE_SOURCE_DIR@','swig')]
-
-# C++ files and swig interface
-cpp_src_dirs = ['src/fftw','src/hysop++']
-for sd in cpp_src_dirs:
-    swig_dirs.append(os.path.join('@CMAKE_SOURCE_DIR@', sd))
-ext = {}
-ext['cpp2hysop'] = create_swig_extension(
-    name='cpp2hysop', src_dirs=swig_dirs)
-for ex in ext:
-    ext_modules.append(ext[ex])
+enable_cpp = "@WITH_LIB_CPP@"
+
+if enable_cpp:
+    # path to .i files
+    swig_dirs = [os.path.join('@CMAKE_SOURCE_DIR@','swig')]
+
+    # C++ files and swig interface
+    cpp_src_dirs = ['src/fftw','src/hysop++']
+    for sd in cpp_src_dirs:
+        swig_dirs.append(os.path.join('@CMAKE_SOURCE_DIR@', sd))
+    ext = {}
+    ext['cpp2hysop'] = create_swig_extension(
+        name='cpp2hysop', src_dirs=swig_dirs)
+    for ex in ext:
+        ext_modules.append(ext[ex])
 
 
 if "@WITH_GPU@" is "ON":
diff --git a/HySoP/sort_f90.py b/HySoP/sort_f90.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb1f6a93cdb947c1fc9361561c05f842ab9bcc21
--- /dev/null
+++ b/HySoP/sort_f90.py
@@ -0,0 +1,326 @@
+"""
+Dependency scanner for F90/95 modules. 
+
+The sort function provided below sorts fortran source files in order of 
+increasing dependency. That is, the sorting order makes sure that modules are 
+compiled before they are USE'd. 
+
+See:
+  http://scipy.org/scipy/numpy/ticket/752
+
+The regular expressions are modified versions from the SCons.Scanner.Fortran 
+module. The copyright notice for Scons is included below.
+
+:Author: David Huard, Pearu Peterson
+:Date: May, 2008
+"""
+
+""" 
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation 
+
+Permission is hereby granted, free of charge, to any person obtaining 
+a copy of this software and associated documentation files (the 
+"Software"), to deal in the Software without restriction, including 
+without limitation the rights to use, copy, modify, merge, publish, 
+distribute, sublicense, and/or sell copies of the Software, and to 
+permit persons to whom the Software is furnished to do so, subject to 
+the following conditions: 
+
+The above copyright notice and this permission notice shall be included 
+in all copies or substantial portions of the Software. 
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 
+KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+"""
+
+import re, copy, os
+import warnings
+
+__all__ = ['FortranFileSorter', 'sort'] 
+
+"""
+Regular expression for a module name
+------------------------------------
+
+An alphanumeric word not beginning with a numeric character.
+  
+   [a-z_]         : a letter or an underscore
+   \w*            : any number of alphanumeric characters
+"""
+modulename = """[a-z_]\w*"""
+
+
+
+"""
+Regular expression for a USE statement
+--------------------------------------
+
+Matches the following statements:
+
+USE module_name
+USE :: module_name
+USE, INTRINSIC :: module_name
+USE, NON_INTRINSIC :: module_name
+USE module_name, only :: [list of procedures]
+
+
+Here is a breakdown of the regex:
+
+   (?i)               : regex is case insensitive
+   (?:                : group a collection of regex symbols without saving the match as a "group"
+      ^|;             : matches either the start of the line or a semicolon - semicolon
+   )                  : end the unsaved grouping
+   \s*                : any amount of white space
+   USE                : match the string USE, case insensitive
+   (?:                : group a collection of regex symbols without saving the match as a "group"
+      \s+|            : match one or more whitespace OR ....  (the next entire grouped set of regex symbols)
+      (?:             : group a collection of regex symbols without saving the match as a "group"
+         (?:          : establish another unsaved grouping of regex symbols
+            \s*          : any amount of white space
+            ,         : match a comma
+            \s*       : any amount of white space
+            (?:NON_)? : optionally match the prefix NON_, case insensitive
+            INTRINSIC : match the string INTRINSIC, case insensitive
+         )?           : optionally match the ", INTRINSIC/NON_INTRINSIC" grouped expression
+         \s*          : any amount of white space
+         ::           : match a double colon that must appear after the INTRINSIC/NON_INTRINSIC attribute
+      )               : end the unsaved grouping
+   )                  : end the unsaved grouping
+   \s*                : match any amount of white space
+   (modulename_regex) : match the module name that is being USE'd, see above.
+"""
+use_regex = \
+"(?i)(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(%s)"%\
+modulename
+
+
+"""
+Regular expression for a MODULE statement
+-----------------------------------------
+
+This regex finds module definitions by matching the following: 
+
+MODULE module_name 
+
+but *not* the following: 
+ 
+MODULE PROCEDURE procedure_name 
+ 
+Here is a breakdown of the regex: 
+   (?i)               : regex is case insensitive
+   ^\s*               : any amount of white space 
+   MODULE             : match the string MODULE, case insensitive 
+   \s+                : match one or more white space characters 
+   (?!PROCEDURE)      : but *don't* match if the next word matches 
+                        PROCEDURE (negative lookahead assertion), 
+                        case insensitive 
+   ([a-z_]\w*)        : match one or more alphanumeric characters 
+                        that make up the defined module name and 
+                        save it in a group 
+"""
+def_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(%s)"""%modulename 
+
+
+"""
+Regular expression for an INCLUDE statement
+-------------------------------------------
+The INCLUDE statement regex matches the following:
+
+   INCLUDE 'some_Text'
+   INCLUDE "some_Text"
+   INCLUDE "some_Text" ; INCLUDE "some_Text"
+   INCLUDE kind_"some_Text"
+   INCLUDE kind_'some_Text"
+
+where some_Text can include any alphanumeric and/or special character
+as defined by the Fortran 2003 standard.
+
+Here is a breakdown of the regex:
+
+   (?i)               : regex is case insensitive
+   (?:                : begin a non-saving group that matches the following:
+      ^               :    either the start of the line
+      |               :                or
+      ['">]\s*;       :    a semicolon that follows a single quote,
+                           double quote or greater than symbol (with any
+                           amount of whitespace in between).  This will
+                           allow the regex to match multiple INCLUDE
+                           statements per line (although it also requires
+                           the positive lookahead assertion that is
+                           used below).  It will even properly deal with
+                           (i.e. ignore) cases in which the additional
+                           INCLUDES are part of an in-line comment, ala
+                                           "  INCLUDE 'someFile' ! ; INCLUDE 'someFile2' "
+   )                  : end of non-saving group
+   \s*                : any amount of white space
+   INCLUDE            : match the string INCLUDE, case insensitive
+   \s+                : match one or more white space characters
+   (?\w+_)?           : match the optional "kind-param _" prefix allowed by the standard
+   [<"']              : match the include delimiter - an apostrophe, double quote, or less than symbol
+   (.+?)              : match one or more characters that make up
+                        the included path and file name and save it
+                        in a group.  The Fortran standard allows for
+                        any non-control character to be used.  The dot
+                        operator will pick up any character, including
+                        control codes, but I can't conceive of anyone
+                        putting control codes in their file names.
+                        The question mark indicates it is non-greedy so
+                        that regex will match only up to the next quote,
+                        double quote, or greater than symbol
+  (?=["'>])          : positive lookahead assertion to match the include
+                        delimiter - an apostrophe, double quote, or
+                       greater than symbol.  This level of complexity
+                        is required so that the include delimiter is
+                        not consumed by the match, thus allowing the
+                        sub-regex discussed above to uniquely match a
+                        set of semicolon-separated INCLUDE statements
+                        (as allowed by the F2003 standard)
+"""
+include_regex = \
+    """(?i)(?:^|['">]\s*;)\s*INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
+
+
+"""
+Regular expression for a comment
+--------------------------------
+
+One limitation of the original Scons scanner is that it cannot properly USE 
+statements if they are commented out. In either of the following cases:
+
+   !  USE mod_a ; USE mod_b         [entire line is commented out]
+   USE mod_a ! ; USE mod_b       [in-line comment of second USE statement]
+
+the second module name (mod_b) will be picked up as a dependency even though 
+it should be ignored. The proposed solution is to first parse the file to 
+remove all the comments.
+
+(^.*)!?             : match everything on a line before an optional comment
+.*$                 : ignore the rest of the line
+"""
+comment_regex = r'(^.*)!?.*$'
+    
+class FortranFileSorter:
+    """Given a list of fortran 90/95 files, return a file list sorted by module
+    dependency. If a file depends on a parent through a USE MODULE statement, 
+    this parent file will occur earlier in the list. 
+    
+    Parameters
+    ----------
+    files : sequence
+      The sequence of file names to be sorted.
+    
+    """
+    def __init__(self, files):
+        self.files = files
+        self.use_regex = re.compile(use_regex, re.MULTILINE)
+        self.def_regex = re.compile(def_regex, re.MULTILINE)
+        self.comment_regex = re.compile(comment_regex, re.MULTILINE)
+        self.include_regex = re.compile(include_regex, re.MULTILINE)
+
+    def read_code(self, file):
+        """Open the file and return the code as one string."""
+        if not hasattr(file, 'readlines'):
+            file = open(file, 'r')
+        return file.read()
+
+    def uncomment(self, code):
+        """Return an uncommented version of a code string."""
+        return '\n'.join(self.comment_regex.findall(code))
+
+    def match_used(self, code):
+        """Return the set of used module in a code string."""
+        return set(map(str.lower, self.use_regex.findall(code)))
+
+    def match_defined(self, code):
+        """Return the set of defined module in a code string."""
+        return set(map(str.lower, self.def_regex.findall(code)))
+        
+    def match_included(self, code):
+        """Return the set of included files in a code string."""
+        return set(self.include_regex.findall(code))
+        
+    def externals(self):
+        """Return the modules that are used but not defined in the list of 
+        files."""
+        if not hasattr(self, 'mod_defined'):
+            self.scan()
+        all_used = reduce(set.union, self.mod_used.values())
+        all_defined = reduce(set.union, self.mod_defined.values())
+        return all_used.difference(all_defined)
+        
+    def scan(self):
+        """For each file, identify the set of modules that are
+         defined, used but not defined in the same file, and the set of 
+         included files.
+        """
+        self.mod_defined = {}
+        self.mod_used = {}
+        self.included = {}
+        for f in self.files:
+            code = self.read_code(f)
+            code = self.uncomment(code)         
+            self.mod_defined[f] = self.match_defined(code)
+            self.mod_used[f] = self.match_used(code)
+            self.included[f] = self.match_included(code)
+            
+            # Remove from used the modules defined internally. 
+            # That is, keep elements in used but not in defined. 
+            self.mod_used[f].difference_update(self.mod_defined[f]) 
+                    
+    # TODO : Deal with include (do we have too?)                        
+    def sort(self):
+        """Sort the files in order of dependency. 
+        """      
+        ordered_list = []
+        
+        # Take care of modules not defined anywhere in the files. eg.
+        # an intrinsic module by assuming them known from the 
+        # start.
+        defined = self.externals()
+            
+        # This cycles through the files, and appends those whose dependencies 
+        # are already satisfied by the files in the ordered list. 
+        remaining = set(self.files)
+        goon = True
+        while goon:
+            goon = False
+            for f in remaining:
+                dependencies_satisfied = self.mod_used[f].issubset(defined)
+                if dependencies_satisfied:
+                    ordered_list.append(f)            
+                    defined.update(self.mod_defined[f])
+                    goon = True
+            remaining.difference_update(set(ordered_list))
+
+        ordered_list.extend(list(remaining))
+        return ordered_list
+    
+    
+    
+def sort(files):
+    """Given a list of fortran 90/95 files, return a file list sorted by module
+    dependency. If a file depends on a parent through a USE MODULE statement, 
+    this parent file will occur earlier in the list. 
+    
+    Parameters
+    ----------
+    files : sequence
+      The sequence of file names to be sorted.
+    """
+    FS = FortranFileSorter(files)
+    FS.scan()
+    return FS.sort() 
+
+
+import sys
+if __name__ == "__main__":
+    print sys.argv[1:]
+    sort(sys.argv[1:])
+
+
+
diff --git a/HySoP/src/hysop++/tests/CMakeLists.txt b/HySoP/src/hysop++/tests/CMakeLists.txt
index e16d2d63c31dfb62856c04ea233266894d40cdd3..cd300769e9ca3ffd1f1b7d67a595c8676ced83e2 100644
--- a/HySoP/src/hysop++/tests/CMakeLists.txt
+++ b/HySoP/src/hysop++/tests/CMakeLists.txt
@@ -1,7 +1,7 @@
 
-include("${CMAKE_SOURCE_DIR}/CMake/GoogleTestHelper.cmake")
+#include("${CMAKE_SOURCE_DIR}/CMake/GoogleTestHelper.cmake")
 
-add_subdirectory("testPolynoms")
-add_subdirectory("testPlanner")
-add_subdirectory("testDiffSolver")
-add_subdirectory("testPoissonSolver")
+#add_subdirectory("testPolynoms")
+#add_subdirectory("testPlanner")
+#add_subdirectory("testDiffSolver")
+#add_subdirectory("testPoissonSolver")