diff --git a/CMakeLists.txt b/CMakeLists.txt
index 48778d5b8007bf3f824e5976aafb785aa9a99cbe..3ea4e54f02bd3d98f048102a66246ff386f72ab1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,10 +45,13 @@ if(ENABLE_GPU)
                 message("CUDA is compatible")
                 set(WARNING_SUPPRESSION_AND_OPTION_NVCC  -Xcudafe "--display_error_number --diag_suppress=2977 --diag_suppress=2976 --diag_suppress=2979 --diag_suppress=186" --expt-extended-lambda)
         elseif ( CUDA_VERSION_MAJOR EQUAL 11 AND CUDA_VERSION_MINOR EQUAL 0 )
-                message("CUDA is compatible")
-                set(WARNING_SUPPRESSION_AND_OPTION_NVCC  -Xcudafe "--display_error_number --diag_suppress=3059 --diag_suppress=3058 --diag_suppress=3057 --diag_suppress=3056 --diag_suppress=611 --diag_suppress=186" --expt-extended-lambda)
-        else()
-                message(FATAL_ERROR "CUDA is incompatible, version 9.2 10.1 10.2 and 11.0 is only supported")
+                message("CUDA is compatible 11.0")
+                set(WARNING_SUPPRESSION_AND_OPTION_NVCC  -Xcudafe "--display_error_number --diag_suppress=3059 --diag_suppress=3058 --diag_suppress=3057 --diag_suppress=3056 --diag_suppress=611  --diag_suppress=186" --expt-extended-lambda)
+	elseif ( CUDA_VERSION_MAJOR EQUAL 11 AND CUDA_VERSION_MINOR EQUAL 1 )
+                message("CUDA is compatible 11.1")
+                set(WARNING_SUPPRESSION_AND_OPTION_NVCC  -Xcudafe "--display_error_number --diag_suppress=3124 --diag_suppress=3126 --diag_suppress=3125 --diag_suppress=3123 --diag_suppress=611  --diag_suppress=186 --diag_suppress=128" --expt-extended-lambda)
+	else()
+                message(FATAL_ERROR "CUDA is incompatible, version 9.2 10.1 10.2 11.0 and 11.1 is only supported")
         endif()
 endif()
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b7c1cd3442afec536cd803c0428ef172491d5262..49d873c2ec77003be5667d7d4bb2d41bcff39a4c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -105,6 +105,12 @@ install(FILES HDF5_wr/HDF5_wr.hpp
 	HDF5_wr/HDF5_reader_vd.hpp
 	DESTINATION openfpm_io/include/HDF5_wr)
 
+install(FILES RawReader/InitGridWithPixel.hpp
+	DESTINATION openfpm_io/include/RawReader/)
+
+install(FILES util/PathsAndFiles.hpp
+	DESTINATION openfpm_io/include/util)
+
 install(FILES Plot/GoogleChart.hpp Plot/util.hpp
 	DESTINATION openfpm_io/include/Plot )
 
diff --git a/src/RawReader/InitGridWithPixel.hpp b/src/RawReader/InitGridWithPixel.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..bd53a1ce70550f7a1c50de06000aa8c88dc4e2f8
--- /dev/null
+++ b/src/RawReader/InitGridWithPixel.hpp
@@ -0,0 +1,165 @@
+//
+// Created by jstark on 2019-11-07.
+//
+/**
+ * @file InitGridWithPixel.hpp
+ *
+ * @brief Header file containing functions for loading pixel values from 2D image or 3D image stack (volume) stored
+ * in a binary file onto an openFPM grid.
+ *
+ * @details Can be run in parallel.
+ *
+ * @author Justina Stark
+ * @date November 2019 - August 2020
+ */
+#ifndef IMAGE_BASED_RECONSTRUCTION_GETINITIALGRID_HPP
+#define IMAGE_BASED_RECONSTRUCTION_GETINITIALGRID_HPP
+
+#include <iostream>
+#include <typeinfo>
+#include <cmath>
+
+#include "Vector/vector_dist.hpp"
+#include "Grid/grid_dist_id.hpp"
+#include "data_type/aggregate.hpp"
+#include "Decomposition/CartDecomposition.hpp"
+
+#include "level_set/redistancing_Sussman/HelpFunctionsForGrid.hpp"
+typedef signed char BYTE;
+/**@brief Read the number of pixels per dimension from a csv-file in order to create a grid with the same size.
+ *
+ * @param path_to_file Std::string containing the path to the csv file that holds the image/volume size in
+ *                     #pixels per dimension.
+ * @return Std::vector containing the count of pixels for each dimension as it was read from the csv file.
+ */
+std::vector<size_t> get_size(const std::string & path_to_file)
+{
+	std::vector<size_t> stack_dimst_1d;
+	//	stream input csv file and error check
+	std::ifstream file(path_to_file);
+	if (!file)
+	{
+		std::cout << "Error opening file" << std::endl;
+		exit (EXIT_FAILURE);
+	}
+
+	// get its size
+	std::streampos fileSize;
+	file.seekg(0, std::ios::end);
+	fileSize = file.tellg();
+	file.seekg(0, std::ios::beg);
+
+	// reserve capacity
+	stack_dimst_1d.reserve(fileSize);
+
+	std::string field;
+	while ( getline(file, field) )         // 1 field per axis
+	{
+		std::istringstream iss(field);
+		size_t val;
+		iss >> val;
+		stack_dimst_1d.push_back(val);       // add the #pixels for current axis to the array
+	}
+
+	// reverse order to compensate reverse reading
+	std::reverse(std::begin(stack_dimst_1d), std::end(stack_dimst_1d));
+	
+	return stack_dimst_1d;
+}
+
+
+/**@brief Converts the pixel values stored in a binary file into doubles and loads them onto an OpenFPM grid.
+ *
+ * @tparam Phi_0 Index of property in which pixel value should be stored.
+ * @tparam grid_type Type of OpenFPM grid.
+ * @param grid Grid of type grid_type, on which image / image-stack should be loaded.
+ * @param file_name Std::string containing the path + name of the binary file that stores the pixel values.
+ * @param stack_dims Size_t variable that contains the dimensionality of the image / image stack. Can be given
+ *                   manually or loaded from a csv file before (see: #get_size())
+ */
+template <size_t Phi_0, typename grid_type>
+void load_pixel_onto_grid(grid_type & grid, std::string file_name, std::vector <size_t> & stack_dims)
+{
+	constexpr size_t x = 0;
+	constexpr size_t y = 1;
+	constexpr size_t z = 2;
+
+	std::ifstream file_stream (file_name, std::ifstream::binary);
+	
+	auto & v_cl = create_vcluster();
+	if (v_cl.rank() == 0)
+	{
+		for (size_t d = 0; d < grid_type::dims; d++)
+		{
+			std::cout << "# grid points in dimension " << d << " = "  << grid.size(d) << std::endl;
+		}
+	}
+	
+	// initialize complete grid including ghost layer with -1
+	init_grid_and_ghost<Phi_0>(grid, -1.0);
+	
+	// assign pixel values to domain. For each pixel get factor_refinement number of grid points with corresponding value
+	auto dom = grid.getDomainIterator();
+	std::vector<BYTE> pixel_line; // one x-line of the image stack which will be read
+	
+	size_t sz_img[grid_type::dims];
+	for (size_t d = 0; d < grid_type::dims; d++)
+	{
+		sz_img[d] = stack_dims[d];
+	}
+	grid_sm<grid_type::dims,void> ginfo_image(sz_img); // in order to get the image related key later on
+	
+	double refinement[grid_type::dims];
+	for (size_t d = 0; d < grid_type::dims; d++)
+	{
+		refinement[d] = (double) grid.size(d) / (double)stack_dims[d]; // get the factor, by which the grid resolution differs from the image stack resolution
+		if (v_cl.rank() == 0) std::cout << "effective refinement in dimension " << d << " = " << refinement[d] << std::endl;
+	}
+	
+	while(dom.isNext())
+	{
+		auto key = dom.get();
+		auto gkey = grid.getGKey(key);
+		
+		// get l as the length of one x-line of the original image stack for the specific patch on the processor
+		auto & gbox = grid.getLocalGridsInfo();
+		auto & DomBox = gbox.get(key.getSub()).Dbox;
+		int l = (size_t) std::round((DomBox.getHigh(0) - DomBox.getLow(0) + 1) / refinement[x]);
+		
+		// in case that the grid has a different resolution than the underlying image stack:
+		// create a key which is used to get the offset for the file reading
+		// the indices in this key are corrected by the refinement factor
+		for (size_t d = 0; d < grid_type::dims; d++)
+		{
+			gkey.set_d(d, std::round(gkey.get(d) / refinement[d]));
+		}
+		
+		// the offset matches the pixel from the image stack to the corresponding current position of the iterator
+		// in the grid
+		size_t offset = ginfo_image.LinId(gkey);
+		file_stream.seekg(offset); // jump to the correct position in the file
+		
+		// prepare space for the pixel values of one x-line in the original image stack
+		pixel_line.resize(l);
+		// stream the file and fill pixel values into pixel_line
+		file_stream.read((char*) & pixel_line[0], l);
+		
+		// run over a whole grid-line in x and assign pixel values from pixel_line to grid nodes
+		// if the grid is finer in x as the image stack, the same pixel value from pixel_line is
+		// assigned refinement[x] times
+		for (size_t i = 0; i < l * refinement[x]; i++)
+		{
+			auto key = dom.get();
+			grid.template get<Phi_0>(key) = (double) pixel_line[(size_t)floor(i / refinement[x])];
+			++dom;
+		}
+		// now one grid line in x is finished and the iterator dom has advanced accordingly s.t. next loop continues
+		// with next line, meaning that y increased by 1 (or z respectivley, when y = ymax + 1)
+	}
+	
+	grid.template ghost_get<Phi_0>();
+}
+
+
+
+#endif //IMAGE_BASED_RECONSTRUCTION_GETINITIALGRID_HPP
diff --git a/src/VTKWriter/VTKWriter_graph.hpp b/src/VTKWriter/VTKWriter_graph.hpp
index bb5be70cdf655d27b9a5913904e43f5ba80589fb..3b4bb1e61a00b564d4c0cd902b030c588915cd29 100644
--- a/src/VTKWriter/VTKWriter_graph.hpp
+++ b/src/VTKWriter/VTKWriter_graph.hpp
@@ -611,6 +611,7 @@ public:
 template<typename Graph, unsigned int i>
 class prop_output<false, Graph, i>
 {
+public:
 	/*! \brief Return the point data section for a graph g
 	 *
 	 * \param g graph
@@ -774,7 +775,7 @@ class prop_output<false, Graph, i>
 	 */
 	static std::string get_attributes_vertex()
 	{
-		return Graph::V_type::attributes::name[i];
+		return std::string("attr" + std::to_string(i));
 	}
 
 	/*! \brief Get the attributes name for edge
@@ -784,7 +785,7 @@ class prop_output<false, Graph, i>
 	 */
 	static std::string get_attributes_edge()
 	{
-		return Graph::E_type::attributes::name[i];
+		return std::string("attr" + std::to_string(i));
 	}
 };
 
diff --git a/src/util/PathsAndFiles.hpp b/src/util/PathsAndFiles.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..92331d8aa1c9b9a6d6561c838361860fbfe27dfc
--- /dev/null
+++ b/src/util/PathsAndFiles.hpp
@@ -0,0 +1,123 @@
+//
+// Created by jstark on 2019-12-03.
+//
+/**
+ * @file PathsAndFiles.hpp
+ *
+ * @brief Header file containing functions for creating files and folders.
+ *
+ * @author Justina Stark
+ * @date December 2019
+ */
+
+#ifndef FILES_READ_AND_WRITE_PATHSANDFILES_HPP
+#define FILES_READ_AND_WRITE_PATHSANDFILES_HPP
+#include <unistd.h>
+#include <iostream>
+#include <fstream>
+#include <boost/filesystem.hpp>
+#include "VCluster/VCluster.hpp"
+/**@brief Gets the current working directory and returns path as string.
+ *
+ * @return Std::string of path to current working directory.
+ */
+std::string get_cwd()
+{
+	char *cwd = nullptr;
+	size_t size;
+	cwd = getcwd(cwd, size);
+	
+	// convert current directory to string
+	std::string s_cwd;
+	s_cwd = cwd;
+
+	//	std::cout << "The current working directory is: " << dir << std::endl;
+	return s_cwd;
+}
+/**@brief Checks if a file already exists.
+ *
+ * @param path Std::string with path of file for which existence should be checked.
+ * @return True, if file exists, false if not.
+ */
+bool check_if_file_exists(std::string path)
+{
+	try
+	{
+		// Create a filesystem::path object from given path string
+		boost::filesystem::path pathObj(path);
+		if (boost::filesystem::exists(pathObj) && boost::filesystem::is_regular_file(pathObj))
+		{
+			return true;
+//			BOOST_LOG_TRIVIAL(info) << path << " -> File exists.";
+		}
+		
+	}
+	catch (boost::filesystem::filesystem_error & e)
+	{
+		std::cerr << e.what() << std::endl;
+//		BOOST_LOG_TRIVIAL(error) << "Error when checking existence of file ( " << path << " ): " << e.what();
+	}
+	return false;
+}
+/**@brief Creates a file if not already existent.
+ *
+ * @param path Std::string that contains path including filename of the file that should be created.
+ */
+void create_file_if_not_exist(std::string path)
+{
+	auto & v_cl = create_vcluster();
+	if (v_cl.rank() == 0)
+	{
+		if ( ! check_if_file_exists(path))
+		{
+			std::ofstream outfile (path);
+//			BOOST_LOG_TRIVIAL(info) << "Created file with name: " << path;
+		}
+	}
+}
+
+
+/**@brief Checks if a directory already exists.
+ *
+ * @param path Std::string with path of directory for which existence should be checked.
+ * @return True, if directory exists, false if not.
+ */
+bool check_if_directory_exists(std::string path)
+{
+	try
+	{
+		// Create a filesystem::path object from given path string
+		boost::filesystem::path pathObj(path);
+		if (boost::filesystem::exists(pathObj) && boost::filesystem::is_directory(pathObj)) return true;
+	}
+	catch (boost::filesystem::filesystem_error & e)
+	{
+		std::cerr << e.what() << std::endl;
+	}
+	return false;
+}
+/**@brief Creates a directory if not already existent.
+ *
+ * @param path Std::string that contains path including name of the folder that should be created.
+ */
+void create_directory_if_not_exist(std::string path)
+{
+	auto & v_cl = create_vcluster();
+	if (v_cl.rank() == 0)
+	{
+		if ( ! check_if_directory_exists(path))
+		{
+			boost::filesystem::create_directory(path);
+//			BOOST_LOG_TRIVIAL(info) << "Created directory with name: " << path;
+		}
+		else std::cout << "Folder for current settings ( '" << path << "' ) already exists. New files will be saved to this folder." << std::endl;
+//		BOOST_LOG_TRIVIAL(info) << "Folder for current settings ( '" << path << "' ) already exists. New files will be saved to this folder.";
+	}
+}
+
+
+
+
+
+#endif //FILES_READ_AND_WRITE_PATHSANDFILES_HPP
+