From 8145e769e7b9264c7a310706e881482766681342 Mon Sep 17 00:00:00 2001
From: Michael Kuron <mkuron@icp.uni-stuttgart.de>
Date: Wed, 31 Jan 2018 12:11:15 +0100
Subject: [PATCH] [API] Remove boost::filesystem

API change for vtk::VTKOutput::getFilenames
---
 CMakeLists.txt                                | 44 +++++++++++++++-
 .../MotionSingleHeavySphere.cpp               | 12 ++---
 .../BidisperseFluidizedBedDPM.cpp             |  6 +--
 apps/tools/povrayFileCompressor/main.cpp      | 35 +++++++------
 cmake/TestStdFilesystem.cpp                   | 16 ++++++
 src/core/Filesystem.h                         | 50 +++++++++++++++++++
 src/core/config/Config.cpp                    |  4 +-
 src/core/config/Config.h                      | 21 ++------
 src/core/logging/Logging.cpp                  | 11 ++--
 src/gather/FileGatherScheme.cpp               |  6 +--
 src/mesh/MeshIO.h                             |  6 +--
 src/mesh/vtk/VTKMeshWriter.h                  | 12 ++---
 src/python_coupling/PythonCallback.cpp        |  8 +--
 src/vtk/VTKOutput.cpp                         | 42 ++++++++--------
 src/vtk/VTKOutput.h                           |  5 +-
 src/waLBerlaDefinitions.in.h                  |  3 ++
 tests/core/mpi/MPITextFileTest.cpp            | 10 ++--
 tests/geometry/VoxelFileTest.cpp              | 30 ++++++-----
 .../HinderedSettlingDynamicsDPM.cpp           |  6 +--
 .../SphereWallCollisionBehaviorDPM.cpp        |  6 +--
 .../SettlingSphereMEM.cpp                     |  6 +--
 .../SettlingSphereMEMDynamicRefinement.cpp    |  6 +--
 .../SettlingSphereMEMStaticRefinement.cpp     |  6 +--
 23 files changed, 222 insertions(+), 129 deletions(-)
 create mode 100644 cmake/TestStdFilesystem.cpp
 create mode 100644 src/core/Filesystem.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 013862580..b579381c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -436,6 +436,46 @@ endif()
 
 
 
+############################################################################################################################
+##
+##  Find optional C++ libraries
+##
+############################################################################################################################
+
+try_compile( WALBERLA_USE_STD_FILESYSTEM "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdFilesystem.cpp"
+             COMPILE_DEFINITIONS -DWALBERLA_USE_STD_FILESYSTEM -std=c++14 )
+if( WALBERLA_USE_STD_FILESYSTEM )
+   message( STATUS "Found std::filesystem")
+else()
+   try_compile( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdFilesystem.cpp"
+                COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM -std=c++14 )
+   if( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+      message( STATUS "Found std::experimental::filesystem")
+   endif()
+   if( NOT WALBERLA_CXX_COMPILER_IS_MSVC AND NOT WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+      unset( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM CACHE )
+      try_compile( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdFilesystem.cpp"
+                   COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM -std=c++14
+                   LINK_LIBRARIES stdc++fs )
+      if( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+         message( STATUS "Found std::experimental::filesystem in libstdc++fs")
+      list ( APPEND SERVICE_LIBS -lstdc++fs )
+      endif()
+   endif()
+   if( NOT WALBERLA_CXX_COMPILER_IS_MSVC AND NOT WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+      unset( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM CACHE )
+      try_compile( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdFilesystem.cpp"
+                   COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM -std=c++14
+                   LINK_LIBRARIES c++experimental )
+      if( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+         message( STATUS "Found std::experimental::filesystem in libc++experimental")
+         list ( APPEND SERVICE_LIBS -lc++experimental )
+      endif()
+   endif()
+endif()
+
+
+
 ############################################################################################################################
 ##
 ##  Visual Studio Setup
@@ -574,7 +614,9 @@ endif()
 #############################################################################################################################
 set ( waLBerla_REQUIRED_MIN_BOOST_VERSION "1.48")
 
-list ( APPEND waLBerla_REQUIRED_BOOST_COMPONENTS filesystem system )
+if ( NOT WALBERLA_USE_STD_FILESYSTEM AND NOT WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+  list ( APPEND waLBerla_REQUIRED_BOOST_COMPONENTS filesystem system )
+endif()
 
 if ( WALBERLA_BUILD_WITH_PYTHON AND WALBERLA_CXX_COMPILER_IS_MSVC )
     list( APPEND waLBerla_REQUIRED_BOOST_COMPONENTS python3 )
diff --git a/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp b/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp
index c54228f17..fc6a084ff 100644
--- a/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp
+++ b/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp
@@ -944,9 +944,9 @@ int main( int argc, char **argv )
    WALBERLA_LOG_INFO_ON_ROOT("Basefolder for simulation results: " << basefolder);
 
    // create base directory if it does not yet exist
-   boost::filesystem::path tpath( basefolder );
-   if( !boost::filesystem::exists( tpath ) )
-      boost::filesystem::create_directory( tpath );
+   filesystem::path tpath( basefolder );
+   if( !filesystem::exists( tpath ) )
+      filesystem::create_directory( tpath );
 
    // setup of the LBM communication for synchronizing the pdf field between neighboring blocks
    std::function< void () > commFunction;
@@ -1255,9 +1255,9 @@ int main( int argc, char **argv )
    pdfFieldVTK->addBeforeFunction(VTKInfoLogger( &timeloop, blocks, bodyStorageID, basefolder, uInfty ));
 
    // create folder for log_vtk files to not pollute the basefolder
-   boost::filesystem::path tpath2( basefolder+"/log_vtk" );
-   if( !boost::filesystem::exists( tpath2 ) )
-      boost::filesystem::create_directory( tpath2 );
+   filesystem::path tpath2( basefolder+"/log_vtk" );
+   if( !filesystem::exists( tpath2 ) )
+      filesystem::create_directory( tpath2 );
 
 
    field::FlagFieldCellFilter< FlagField_T > fluidFilter( flagFieldID );
diff --git a/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp b/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp
index 7e5cab129..b31ea4a69 100644
--- a/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp
+++ b/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp
@@ -740,9 +740,9 @@ int main( int argc, char **argv ) {
    if( !funcTest )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( vtkBaseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( vtkBaseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
 
diff --git a/apps/tools/povrayFileCompressor/main.cpp b/apps/tools/povrayFileCompressor/main.cpp
index 86f1f9ee4..4d56bc779 100644
--- a/apps/tools/povrayFileCompressor/main.cpp
+++ b/apps/tools/povrayFileCompressor/main.cpp
@@ -21,17 +21,16 @@
 #include "geometry/mesh/TriangleMesh.h"
 #include "geometry/mesh/TriangleMeshIO.h"
 #include "core/Regex.h"
+#include "core/Filesystem.h"
 
 #include <fstream>
 #include <iomanip>
 #include <iostream>
 
 
-#define BOOST_FILESYSTEM_NO_DEPRECATED
-#include <boost/filesystem.hpp>
 #include <boost/algorithm/string.hpp>
 
-namespace fs = boost::filesystem;
+namespace filesystem = walberla::filesystem;
 
 bool verbose;
 bool quiet;
@@ -90,29 +89,29 @@ int main(int argc, char** argv)
    if( quiet && verbose )
       PRINT_ERR( "PovrayFileCompressor can't be quiet (-q) and verbose (-v) at the same time\n" )
 
-   fs::path inPath(argv[argc-2]);
-   if( !fs::exists(inPath) || !fs::is_directory(inPath) )
+   filesystem::path inPath(argv[argc-2]);
+   if( !filesystem::exists(inPath) || !filesystem::is_directory(inPath) )
       PRINT_ERR( "Path " << inPath << " does not exist or is not a directory!\n" );
 
-   fs::path outPath(argv[argc-1]);
-   if( !fs::exists(outPath) )
-      fs::create_directories(outPath);
+   filesystem::path outPath(argv[argc-1]);
+   if( !filesystem::exists(outPath) )
+      filesystem::create_directories(outPath);
 
    PRINT_DEF( "Input Path: " << inPath << "\nOutput Path: " << outPath << "\n" )
 
 
-   std::vector< std::vector<fs::path> > infiles;
+   std::vector< std::vector<filesystem::path> > infiles;
 
    PRINT_DEF( "Collecting files to compress ..." )
 
-   for(auto pit = fs::directory_iterator(inPath); pit != fs::directory_iterator(); ++pit)
+   for(auto pit = filesystem::directory_iterator(inPath); pit != filesystem::directory_iterator(); ++pit)
    {
-      if( !fs::is_directory( pit->status() ) )
+      if( !filesystem::is_directory( pit->status() ) )
          continue;
 
       PRINT_VER( "\nCollecting files to compress in: " << pit->path())
-      std::vector<fs::path> pfiles;
-      for(auto tit = fs::directory_iterator(pit->path()); tit != fs::directory_iterator(); ++tit)
+      std::vector<filesystem::path> pfiles;
+      for(auto tit = filesystem::directory_iterator(pit->path()); tit != filesystem::directory_iterator(); ++tit)
       {
          static const walberla::regex extensionExpression("\\.dat");
          if( walberla::regex_match( tit->path().extension().string(), extensionExpression ) )
@@ -140,14 +139,14 @@ int main(int argc, char** argv)
    {
       PRINT_VER( "Compress timestep " << t << "\n" )
       PRINT_VER( "Merge Splitted Meshes: \n" )
-      PRINT_VER( "Merge Mesh: " << fs::absolute(infiles[0][t]).string().c_str() << "\n" )
-      std::ifstream is( fs::absolute(infiles[0][t]).string().c_str() );
+      PRINT_VER( "Merge Mesh: " << filesystem::absolute(infiles[0][t]).string().c_str() << "\n" )
+      std::ifstream is( filesystem::absolute(infiles[0][t]).string().c_str() );
       walberla::geometry::readMeshPov(is, mesh, true);
       is.close();
 
       for( size_t p = 1u; p < processes; ++p ){
-         PRINT_VER( "Merge Mesh: " << fs::absolute(infiles[p][t]).string().c_str() << "\n" )
-         std::ifstream tis( fs::absolute(infiles[p][t]).string().c_str() );
+         PRINT_VER( "Merge Mesh: " << filesystem::absolute(infiles[p][t]).string().c_str() << "\n" )
+         std::ifstream tis( filesystem::absolute(infiles[p][t]).string().c_str() );
          walberla::geometry::readMeshPov(tis, mesh, false);
          tis.close();
       }
@@ -172,7 +171,7 @@ int main(int argc, char** argv)
          }
       }
 
-      fs::path oPath = fs::absolute(outPath) / infiles[0][t].filename();
+      filesystem::path oPath = filesystem::absolute(outPath) / infiles[0][t].filename();
       PRINT_VER( "Write New Mesh File: " << (oPath.string().c_str()) << "\n" )
       std::ofstream os( oPath.string().c_str() );
       walberla::geometry::writeMeshPov( os, mesh, 0u, n );
diff --git a/cmake/TestStdFilesystem.cpp b/cmake/TestStdFilesystem.cpp
new file mode 100644
index 000000000..ac85c4cce
--- /dev/null
+++ b/cmake/TestStdFilesystem.cpp
@@ -0,0 +1,16 @@
+#include <iostream>
+#if defined(WALBERLA_USE_STD_FILESYSTEM)
+#include <filesystem>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM)
+#include <experimental/filesystem>
+#endif
+
+int main() {
+#if defined(WALBERLA_USE_STD_FILESYSTEM)
+   std::filesystem::path p("/tmp/test.txt");
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM)
+   std::experimental::filesystem::path p("/tmp/test.txt");
+#endif
+   std::cout << p << std::endl;
+   return 0;
+}
diff --git a/src/core/Filesystem.h b/src/core/Filesystem.h
new file mode 100644
index 000000000..5ba210fc4
--- /dev/null
+++ b/src/core/Filesystem.h
@@ -0,0 +1,50 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla 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.
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Filesystem.h
+//! \ingroup core
+//! \author Michael Kuron <mkuron@icp.uni-stuttgart.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+
+#if defined(WALBERLA_USE_STD_FILESYSTEM)
+#include <filesystem>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM)
+#include <experimental/filesystem>
+#else
+#include <boost/filesystem.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#endif
+
+
+
+namespace walberla {
+namespace filesystem {
+
+#if defined(WALBERLA_USE_STD_FILESYSTEM)
+using namespace std::filesystem;
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM)
+using namespace std::experimental::filesystem;
+#else
+using namespace boost::filesystem;
+#endif
+
+}
+}
diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp
index 8660f5052..48277f3bc 100644
--- a/src/core/config/Config.cpp
+++ b/src/core/config/Config.cpp
@@ -262,7 +262,7 @@ void Config::parseFromFile( const char* filename, Block& block, unsigned int lev
             }
             else {
                removeTrailingWhiteSpaces( value );
-               std::string file( (boost::filesystem::path( getDirectory( filename ) ) / value).string() );
+               std::string file( (filesystem::path( getDirectory( filename ) ) / value).string() );
                parseFromFile( file.c_str(), block, level+1 );
             }
          }
@@ -395,7 +395,7 @@ void Config::extractBlock( const char* filename, std::stringstream& input, Block
             }
             else {
                removeTrailingWhiteSpaces( value );
-               std::string file( (boost::filesystem::path( getDirectory( filename ) ) / value).string() );
+               std::string file( (filesystem::path( getDirectory( filename ) ) / value).string() );
                parseFromFile( file.c_str(), block, level+1 );
             }
          }
diff --git a/src/core/config/Config.h b/src/core/config/Config.h
index d83f9baa1..9ed1ce819 100644
--- a/src/core/config/Config.h
+++ b/src/core/config/Config.h
@@ -37,11 +37,7 @@
 
 // boost includes
 #include <boost/algorithm/string/predicate.hpp>
-#include <boost/filesystem/path.hpp>
-
-#ifndef BOOST_FILESYSTEM_VERSION
-#define BOOST_FILESYSTEM_VERSION 1
-#endif
+#include "core/Filesystem.h"
 
 
 
@@ -687,13 +683,8 @@ inline void Config::convertToLowerCase( std::string& s )
  */
 inline std::string Config::getDirectory( const std::string& path )
 {
-   boost::filesystem::path p( path );
-#        if BOOST_FILESYSTEM_VERSION>2
-   return p.branch_path().string();
-#        else
-#        warning BOOST FILESYSTEM VERSION IS RATHER OLD! PLEASE USE BOOST VERSION 1.46 OR HIGHER
+   filesystem::path p( path );
    return p.parent_path().string();
-#        endif
 }
 //**********************************************************************************************************************
 
@@ -707,12 +698,8 @@ inline std::string Config::getDirectory( const std::string& path )
  */
 inline std::string Config::getFilename( const std::string& path )
 {
-   boost::filesystem::path p( path );
-#        if BOOST_FILESYSTEM_VERSION>2
-   return p.leaf().string();
-#        else
-   return p.filename();
-#        endif
+   filesystem::path p( path );
+   return p.filename().string();
 }
 //**********************************************************************************************************************
 
diff --git a/src/core/logging/Logging.cpp b/src/core/logging/Logging.cpp
index ea8bde365..60fc970bc 100644
--- a/src/core/logging/Logging.cpp
+++ b/src/core/logging/Logging.cpp
@@ -21,8 +21,7 @@
 
 #include "Logging.h"
 
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
+#include "core/Filesystem.h"
 #include <ctime>
 
 
@@ -105,9 +104,9 @@ void Logging::includeLoggingToFile( const std::string & file, bool append )
    std::ostringstream filename;
    if( file.empty() )
    {
-      boost::filesystem::path logDir( "logging" );
-      if( !boost::filesystem::exists( logDir ) )
-         boost::filesystem::create_directory( logDir );
+      filesystem::path logDir( "logging" );
+      if( !filesystem::exists( logDir ) )
+         filesystem::create_directory( logDir );
 
       if( numberOfProcesses_ == 1 )
          filename << "logging/logfile.txt";
@@ -120,7 +119,7 @@ void Logging::includeLoggingToFile( const std::string & file, bool append )
          filename << file;
       else
       {
-         boost::filesystem::path filePath( file );
+         filesystem::path filePath( file );
          const std::string stem      = filePath.stem().string();
          const std::string extension = filePath.extension().string();
          const std::string modifiedFilename = stem + std::string("_") + rank.str() + extension;
diff --git a/src/gather/FileGatherScheme.cpp b/src/gather/FileGatherScheme.cpp
index b19f8d93c..0aa2e40d7 100644
--- a/src/gather/FileGatherScheme.cpp
+++ b/src/gather/FileGatherScheme.cpp
@@ -27,7 +27,7 @@
 #include "core/mpi/RecvBuffer.h"
 #include "core/mpi/SendBuffer.h"
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 #include <boost/lexical_cast.hpp>
 
 
@@ -56,7 +56,7 @@ FileGatherScheme::~FileGatherScheme()
 
 void FileGatherScheme::deleteTemporaryFiles()
 {
-   using namespace boost::filesystem;
+   using namespace filesystem;
    using std::string;
 
    for(int rank=0; rank < MPIManager::instance()->numProcesses(); ++rank)
@@ -108,7 +108,7 @@ void FileGatherScheme::writeToFile()
 
 void FileGatherScheme::collectFromFiles()
 {
-   using namespace boost::filesystem;
+   using namespace filesystem;
    using namespace std;
 
    if ( fileStream_.is_open() )
diff --git a/src/mesh/MeshIO.h b/src/mesh/MeshIO.h
index 493276526..119fdddff 100644
--- a/src/mesh/MeshIO.h
+++ b/src/mesh/MeshIO.h
@@ -28,7 +28,7 @@
 #include <fstream>
 #include <string>
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 
 #ifdef _MSC_VER
 #  pragma warning(push)
@@ -57,10 +57,10 @@ namespace mesh {
 template< typename MeshType >
 void readAndBroadcast( const std::string & filename, MeshType & mesh )
 {
-   if( !boost::filesystem::exists( filename ) )
+   if( !filesystem::exists( filename ) )
       WALBERLA_ABORT( "The mesh file \"" << filename << "\" does not exist!" );
 
-   std::string extension = boost::filesystem::extension( filename );
+   std::string extension = filesystem::path( filename ).extension().string();
 
    std::string str;
 
diff --git a/src/mesh/vtk/VTKMeshWriter.h b/src/mesh/vtk/VTKMeshWriter.h
index 025779e4f..0019a1b14 100644
--- a/src/mesh/vtk/VTKMeshWriter.h
+++ b/src/mesh/vtk/VTKMeshWriter.h
@@ -29,7 +29,7 @@
 #include "vtk/Base64Writer.h"
 #include "vtk/UtilityFunctions.h"
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 
 #include <iostream>
 #include <vector>
@@ -194,15 +194,15 @@ VTKMeshWriter<MeshType>::VTKMeshWriter( const shared_ptr<const MeshType> & mesh,
    {
       std::ostringstream folder;
       folder << baseFolder_ << '/' << identifier_;
-      if( boost::filesystem::exists( folder.str() ) )
-         boost::filesystem::remove_all( folder.str() );
+      if( filesystem::exists( folder.str() ) )
+         filesystem::remove_all( folder.str() );
 
       std::ostringstream pvdFile;
       pvdFile << baseFolder_ << '/' << identifier_ << ".pvd";
-      if( boost::filesystem::exists( pvdFile.str() ) )
-         boost::filesystem::remove( pvdFile.str() );
+      if( filesystem::exists( pvdFile.str() ) )
+         filesystem::remove( pvdFile.str() );
 
-      boost::filesystem::create_directories( folder.str() );
+      filesystem::create_directories( folder.str() );
    }
    WALBERLA_MPI_BARRIER();
 }
diff --git a/src/python_coupling/PythonCallback.cpp b/src/python_coupling/PythonCallback.cpp
index 5573970b1..b801e1c4c 100644
--- a/src/python_coupling/PythonCallback.cpp
+++ b/src/python_coupling/PythonCallback.cpp
@@ -31,7 +31,7 @@
 #include "helper/ExceptionHandling.h"
 
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 
 namespace walberla {
 namespace python_coupling {
@@ -53,15 +53,15 @@ namespace python_coupling {
       code << "] \n";
 
 
-      boost::filesystem::path path ( fileOrModuleName );
-      path = boost::filesystem::absolute( path );
+      filesystem::path path ( fileOrModuleName );
+      path = filesystem::absolute( path );
       if ( path.extension() == ".py" )
       {
          moduleName = path.stem().string();
 
 
          if ( ! path.parent_path().empty() )  {
-            std::string p = boost::filesystem::canonical(path.parent_path()).string();
+            std::string p = filesystem::canonical(path.parent_path()).string();
             code << "sys.path.append( r'" << p << "')" << "\n";
          }
       }
diff --git a/src/vtk/VTKOutput.cpp b/src/vtk/VTKOutput.cpp
index b9a5e0f7d..7e660ac31 100644
--- a/src/vtk/VTKOutput.cpp
+++ b/src/vtk/VTKOutput.cpp
@@ -138,20 +138,20 @@ void VTKOutput::init( const std::string & identifier )
 
    WALBERLA_ROOT_SECTION()
    {
-      boost::filesystem::path path( baseFolder_ + "/" + identifier_ );
-      if( boost::filesystem::exists( path ) && executionCounter_ == 0 )
-         boost::filesystem::remove_all( path );
+      filesystem::path path( baseFolder_ + "/" + identifier_ );
+      if( filesystem::exists( path ) && executionCounter_ == 0 )
+         filesystem::remove_all( path );
 
-      boost::filesystem::path pvd( baseFolder_ + "/" + identifier_ + ".pvd" );
-      if( boost::filesystem::exists( pvd ) && executionCounter_ == 0 )
+      filesystem::path pvd( baseFolder_ + "/" + identifier_ + ".pvd" );
+      if( filesystem::exists( pvd ) && executionCounter_ == 0 )
          std::remove( pvd.string().c_str() );
 
-      boost::filesystem::path basePath( baseFolder_ );
-      if( !boost::filesystem::exists( basePath ) )
-         boost::filesystem::create_directories( basePath );
+      filesystem::path basePath( baseFolder_ );
+      if( !filesystem::exists( basePath ) )
+         filesystem::create_directories( basePath );
 
-      if ( !boost::filesystem::exists( path ) )
-         boost::filesystem::create_directories( path );
+      if ( !filesystem::exists( path ) )
+         filesystem::create_directories( path );
    }
 
    WALBERLA_MPI_WORLD_BARRIER();
@@ -181,9 +181,9 @@ void VTKOutput::forceWrite( uint_t number, const bool immediatelyWriteCollectors
    {
       if( !useMPIIO_ )
       {
-         boost::filesystem::path tpath( path.str() );
-         if( !boost::filesystem::exists( tpath ) )
-            boost::filesystem::create_directory( tpath );
+         filesystem::path tpath( path.str() );
+         if( !filesystem::exists( tpath ) )
+            filesystem::create_directory( tpath );
       }
    }
    WALBERLA_MPI_WORLD_BARRIER();
@@ -1730,7 +1730,7 @@ void VTKOutput::writePVTI( const uint_t collector ) const
 
    ofs << "  </PCellData>\n";
 
-   std::vector< boost::filesystem::path > files;
+   std::vector< filesystem::path > files;
    getFilenames( files, collector );
 
    for( auto file = files.begin(); file != files.end(); ++file )
@@ -1780,7 +1780,7 @@ void VTKOutput::writePVTI_sampled( const uint_t collector ) const
 
    ofs << "  </PCellData>\n";
 
-   std::vector< boost::filesystem::path > files;
+   std::vector< filesystem::path > files;
    getFilenames( files, collector );
 
    for( auto file = files.begin(); file != files.end(); ++file )
@@ -1928,7 +1928,7 @@ void VTKOutput::writePVTU( const uint_t collector ) const
 
    ofs << "  </PCellData>\n";
 
-   std::vector< boost::filesystem::path > files;
+   std::vector< filesystem::path > files;
    getFilenames( files, collector );
 
    for( auto file = files.begin(); file != files.end(); ++file )
@@ -1980,17 +1980,17 @@ bool VTKOutput::writeCombinedVTU( std::string localPart, const uint_t collector
 
 
 
-void VTKOutput::getFilenames( std::vector< boost::filesystem::path >& files, const uint_t collector ) const
+void VTKOutput::getFilenames( std::vector< filesystem::path >& files, const uint_t collector ) const
 {
    std::ostringstream path;
    path << baseFolder_ << "/" << identifier_ << "/" << executionFolder_ << "_" << collector;
-   boost::filesystem::path directory( path.str() );
+   filesystem::path directory( path.str() );
 
-   WALBERLA_ASSERT( boost::filesystem::exists( directory ) );
+   WALBERLA_ASSERT( filesystem::exists( directory ) );
 
-   for( boost::filesystem::directory_iterator file( directory ); file != boost::filesystem::directory_iterator(); ++file )
+   for( filesystem::directory_iterator file( directory ); file != filesystem::directory_iterator(); ++file )
    {
-      WALBERLA_ASSERT( boost::filesystem::is_regular_file( file->path() ) && !boost::filesystem::is_directory( file->path() ) );
+      WALBERLA_ASSERT( filesystem::is_regular_file( file->path() ) && !filesystem::is_directory( file->path() ) );
       files.push_back( file->path() );
    }
 }
diff --git a/src/vtk/VTKOutput.h b/src/vtk/VTKOutput.h
index 2f51b9b21..9b5945630 100644
--- a/src/vtk/VTKOutput.h
+++ b/src/vtk/VTKOutput.h
@@ -33,8 +33,7 @@
 
 #include "domain_decomposition/StructuredBlockStorage.h"
 
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
+#include "core/Filesystem.h"
 #include <functional>
 #include <boost/tuple/tuple.hpp>
 
@@ -271,7 +270,7 @@ private:
    bool writeCombinedVTI_sampled( std::string localPart, const uint_t collector ) const;
    bool writeCombinedVTU(std::string localPart, const uint_t collector) const;
 
-   void getFilenames( std::vector< boost::filesystem::path >& blocks, const uint_t collector ) const;
+   void getFilenames( std::vector< filesystem::path >& blocks, const uint_t collector ) const;
    void writePPointData( std::ofstream& ofs ) const;
    void writePCellData( std::ofstream& ofs ) const;
 
diff --git a/src/waLBerlaDefinitions.in.h b/src/waLBerlaDefinitions.in.h
index 0c4408a40..703bee6fc 100644
--- a/src/waLBerlaDefinitions.in.h
+++ b/src/waLBerlaDefinitions.in.h
@@ -42,6 +42,9 @@
 #cmakedefine WALBERLA_CXX_COMPILER_IS_MSVC
 #cmakedefine WALBERLA_CXX_COMPILER_IS_CLANG
 
+#cmakedefine WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM
+#cmakedefine WALBERLA_USE_STD_FILESYSTEM
+
 // SIMD
 #cmakedefine WALBERLA_SIMD_FORCE_SCALAR
 
diff --git a/tests/core/mpi/MPITextFileTest.cpp b/tests/core/mpi/MPITextFileTest.cpp
index a1551d8bd..1500d730f 100644
--- a/tests/core/mpi/MPITextFileTest.cpp
+++ b/tests/core/mpi/MPITextFileTest.cpp
@@ -27,7 +27,7 @@
 #include "core/mpi/MPIManager.h"
 #include "core/mpi/MPITextFile.h"
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 
 #include <vector>
 #include <sstream>
@@ -61,8 +61,8 @@ void testSameSizeFile( const std::string & filename, const size_t chunkSize )
    WALBERLA_MPI_BARRIER();
    WALBERLA_ROOT_SECTION()
    {
-      if( boost::filesystem::exists( filename ) )
-         boost::filesystem::remove( filename );
+      if( filesystem::exists( filename ) )
+         filesystem::remove( filename );
    }
    WALBERLA_MPI_BARRIER();
 }
@@ -98,8 +98,8 @@ void testDifferentSizeFile( const std::string & filename, const size_t minChunkS
    WALBERLA_MPI_BARRIER();
    WALBERLA_ROOT_SECTION()
    {
-      if( boost::filesystem::exists( filename ) )
-         boost::filesystem::remove( filename );
+      if( filesystem::exists( filename ) )
+         filesystem::remove( filename );
    }
    WALBERLA_MPI_BARRIER();
 }
diff --git a/tests/geometry/VoxelFileTest.cpp b/tests/geometry/VoxelFileTest.cpp
index 8de8c2156..3d6d18fa1 100644
--- a/tests/geometry/VoxelFileTest.cpp
+++ b/tests/geometry/VoxelFileTest.cpp
@@ -52,7 +52,7 @@
 #include "core/logging/Logging.h"
 #include "core/mpi/MPIManager.h"
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 #include <boost/foreach.hpp>
 #include <random>
 
@@ -209,14 +209,12 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
    using namespace walberla;
    using geometry::VoxelFileReader;
 
-   namespace fs = boost::filesystem;
-
    WALBERLA_LOG_INFO( "Running Test with size " << xSize << "x" << ySize << "x" << zSize << " T = " << typeid(T).name() );
 
-   fs::path path(filename);
+   filesystem::path path(filename);
 
-   if( fs::exists( path ) )
-      fs::remove( path );
+   if( filesystem::exists( path ) )
+      filesystem::remove( path );
 
    CellInterval aabb(0, 0, 0, cell_idx_c(xSize - 1), cell_idx_c(ySize - 1), cell_idx_c(zSize - 1));
    uint_t numCells = aabb.numCells();
@@ -249,8 +247,8 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
 
    data.clear();
 
-   WALBERLA_CHECK( fs::exists( path ) );
-   WALBERLA_CHECK( fs::is_regular_file( path ) );
+   WALBERLA_CHECK( filesystem::exists( path ) );
+   WALBERLA_CHECK( filesystem::is_regular_file( path ) );
 
    geometryFile.open(filename);
    WALBERLA_CHECK( geometryFile.isOpen() );
@@ -396,8 +394,8 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
    geometryFile.close();
    WALBERLA_CHECK( !geometryFile.isOpen() );
 
-   if( fs::exists( path ) )
-      fs::remove( path );
+   if( filesystem::exists( path ) )
+      filesystem::remove( path );
 
    geometryFile.create(filename, xSize, ySize, zSize);
 
@@ -465,8 +463,8 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
    }
    WALBERLA_CHECK( runtimeErrorThrown );
    geometryFile.close();
-   if( fs::exists( fs::path(filename + "0") ) )
-      fs::remove( fs::path(filename + "0") );
+   if( filesystem::exists( filesystem::path(filename + "0") ) )
+      filesystem::remove( filesystem::path(filename + "0") );
 
    if(xSize > 0)
    {
@@ -487,12 +485,12 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
       }
       WALBERLA_CHECK( runtimeErrorThrown );
       geometryFile.close();
-      if( fs::exists( fs::path(filename + "1") ) )
-         fs::remove( fs::path(filename + "1") );
+      if( filesystem::exists( filesystem::path(filename + "1") ) )
+         filesystem::remove( filesystem::path(filename + "1") );
    }
 
-   if( fs::exists( path ) )
-      fs::remove( path );
+   if( filesystem::exists( path ) )
+      filesystem::remove( path );
 
 }
 
diff --git a/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp b/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp
index cc700fde4..0fd036d1a 100644
--- a/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp
+++ b/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp
@@ -703,9 +703,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    ///////////////////////////////
diff --git a/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp b/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp
index 3ac3679f5..8be264759 100644
--- a/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp
+++ b/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp
@@ -595,9 +595,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    ///////////////////////////////
diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp
index 1b0d57f8e..6674cde01 100644
--- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp
@@ -312,9 +312,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    //////////////////////////////////////
diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp
index 469892c98..44b17eb70 100644
--- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp
@@ -516,9 +516,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    //////////////////////////////////////
diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp
index 7a0734d33..391ab7b89 100644
--- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp
@@ -405,9 +405,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    //////////////////////////////////////
-- 
GitLab