From 465263f4eeb70673bd495a60317f3b22b74dab4e Mon Sep 17 00:00:00 2001
From: jstark <jstark@mpi-cbg.de>
Date: Fri, 20 Aug 2021 15:38:13 +0200
Subject: [PATCH] Fixed examples, i.e. stack-size type and default values.

---
 .../example_sussman_disk/Makefile             |  24 +
 .../example_sussman_disk/config.cfg           |   2 +
 .../example_sussman_disk/main.cpp             | 439 ++++++++++++++++++
 .../example_sussman_images_2D/main.cpp        |  34 +-
 .../example_sussman_images_3D/main.cpp        |  32 +-
 .../example_sussman_sphere/main.cpp           |  37 +-
 6 files changed, 516 insertions(+), 52 deletions(-)
 create mode 100644 example/Numerics/Sussman_redistancing/example_sussman_disk/Makefile
 create mode 100644 example/Numerics/Sussman_redistancing/example_sussman_disk/config.cfg
 create mode 100644 example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp

diff --git a/example/Numerics/Sussman_redistancing/example_sussman_disk/Makefile b/example/Numerics/Sussman_redistancing/example_sussman_disk/Makefile
new file mode 100644
index 000000000..6e12dc3ea
--- /dev/null
+++ b/example/Numerics/Sussman_redistancing/example_sussman_disk/Makefile
@@ -0,0 +1,24 @@
+include ../../../example.mk
+
+CC=mpic++
+
+LDIR =
+
+OBJ = main.o
+
+%.o: %.cpp
+	$(CC) -O3 -c --std=c++14 -o $@ $< $(INCLUDE_PATH)
+
+example_sussman_disk: $(OBJ)
+	$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
+
+all: example_sussman_disk
+
+run: all
+	mpirun --oversubscribe -np 2 ./example_sussman_disk
+
+.PHONY: clean all run
+
+clean:
+	rm -f *.o *~ core example_sussman_disk
+
diff --git a/example/Numerics/Sussman_redistancing/example_sussman_disk/config.cfg b/example/Numerics/Sussman_redistancing/example_sussman_disk/config.cfg
new file mode 100644
index 000000000..1eecbac35
--- /dev/null
+++ b/example/Numerics/Sussman_redistancing/example_sussman_disk/config.cfg
@@ -0,0 +1,2 @@
+[pack]
+files = main.cpp Makefile
diff --git a/example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp b/example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp
new file mode 100644
index 000000000..3725674c4
--- /dev/null
+++ b/example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp
@@ -0,0 +1,439 @@
+//
+// Created by jstark on 2020-05-18.
+//
+/**
+ * @file example_sussman_disk/main.cpp
+ * @page Examples_SussmanRedistancing Examples Sussman Redistancing
+ *
+ * @subpage example_sussman_disk
+ * @subpage example_sussman_sphere
+ * @subpage example_sussman_images_2D
+ * @subpage example_sussman_images_3D
+ *
+ * In each of these examples, we either create a geometrical object on a grid or load a binary image / volume onto
+ * the grid. The geometrical objects are initially defined by the following indicator function
+ *
+ * @f[ \phi_{\text{indicator}} = \begin{cases}
+ *    +1 & \text{point lies inside the object} \\
+ *    -1 & \text{point lies outside the object} \\
+ * \end{cases} @f]
+ 
+ * This indicator function is already some form of a level-set-function.
+ * In order to convert Phi_indicator into a signed-distance function (SDF), where @f[|\nabla\phi| = 1@f] we
+ * will perform Sussman redistancing (see: <a href="https://www.researchgate
+ * .net/publication/2642502_An_Efficient_Interface_Preserving_Level_Set_Re
+ * -Distancing_Algorithm_And_Its_Application_To_Interfacial_Incompressible_Fluid_Flow.html">M. Sussman and E. Fatemi,
+ * “Efficient, interface-preserving level set redistancing algorithm and its application to interfacial
+ * incompressible fluid flow” (1999)</a>, Appendix A).
+ *
+ * In the Sussman-redistancing, a level-set-function, which can be as simple as a step-function but requires a switch
+ * of sign accross the surface of the object, is reinitialized to a SDF by finding the steady-state solution of the
+ * following PDE:
+ * @f[ \phi_{t} + sgn(\phi_{0})(|\nabla\phi| - 1) = 0  @f]
+ *
+ * For improved numerical stability and faster convergence, the sign function is replaced by:
+ * @f[ sgn_{\epsilon}(\phi) = \frac{\phi}{ \sqrt{\phi^2 + |\nabla\phi|^2 \Delta x^2} }@f]
+ *
+ * where the \a &phi; is the approximation of the SDF from the last iteration (see: <a href="https://www.math.uci
+ * .edu/~zhao/publication/mypapers/ps/local_levelset.ps">Peng \a et \a al. "A PDE-Based Fast Local
+ * Level Set Method"</a>, equation (36)).
+ */
+
+
+
+
+
+/**
+ * @page example_sussman_disk Disk 2D
+ *
+ * # Get the signed distance function for a 2D disk via Sussman Redistancing #
+ *
+ * In this example, we perform Sussman redistancing on a 2D disk. Here, the disk is constructed via
+ * equation. For image based reconstruction and redistancing see @ref example_sussman_images_2D.
+ *
+ * A disk with center a, b can be constructed by the following equation:
+ *
+ *
+ * @f[ (x-a)^2 + (y-b)^2 <= r^2 @f]
+ *
+ * We will create a disk on a 2D grid, where the disk is represented by a -1/+1 step function
+ * (indicator function) as:
+ *
+ * @f[ \phi_{\text{indicator}} = \begin{cases}
+ *    +1 & \text{point lies inside the object} \\
+ *     0 & \text{object surface} \\
+ *    -1 & \text{point lies outside the object} \\
+ * \end{cases} @f]
+ *
+ * By Sussman redistancing, this indicator function is transformed into a signed distance function:
+ *
+ * @f[ \phi_{\text{SDF}} = \begin{cases}
+ *    +d & \text{orthogonal distance to the closest surface of a point lying inside the object} \\
+ *     0 & \text{object surface} \\
+ *    -d & \text{orthogonal distance to the closest surface of a point lying outside the object} \\
+ * \end{cases} @f]
+ *
+ * Once we have received the Phi_SDF from the redistancing, particles can be placed on narrow band around the interface.
+ *
+ * * Creates 2D disk with -1/+1 indicator function
+ * * Runs Sussman redistancing (see @ref RedistancingSussman.hpp)
+ * * Places particles on narrow band around interface
+ *
+ * Output:
+ * print on promt : Iteration, Change, Residual (see: #DistFromSol::change, #DistFromSol::residual)
+ * writes vtk and hdf5 files of:
+ * 1.) 2D grid with disk pre-redistancing and post-redistancing (Phi_0 and Phi_SDF, respectively)
+ * 2.) particles on narrow band around interface
+ *
+ * ## Visualization of example output in Paraview ##
+ * @htmlonly
+ * <img src="http://openfpm.mpi-cbg.de/web/images/examples/sussman_redistancing/example_sussman_circle_paraview.png" width="1024px"/>
+ * @endhtmlonly
+ */
+
+/**
+ * @page example_sussman_disk Disk 2D
+ *
+ * ## Include ## {#e2d_c_include}
+ *
+ * These are the header files that we need to include:
+ *
+ * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Include
+ *
+ */
+//! @cond [Include] @endcond
+
+// Include Redistancing header files
+#include "util/PathsAndFiles.hpp"
+#include "level_set/redistancing_Sussman/RedistancingSussman.hpp"
+#include "level_set/redistancing_Sussman/NarrowBand.hpp"
+#include "Draw/DrawDisk.hpp"
+//! @cond [Include] @endcond
+
+/**
+ * @page example_sussman_disk Disk 2D
+ *
+ * ## Initialization and output folder ## {#e2d_c_init}
+ *
+ * We start with
+ * * Initializing OpenFPM
+ * * Setting the output path and creating an output folder
+ *
+ * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Initialization and output folder
+ *
+ */
+//! @cond [Initialization and output folder] @endcond
+int main(int argc, char* argv[])
+{
+	//	initialize library
+	openfpm_init(&argc, &argv);
+	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// Set current working directory, define output paths and create folders where output will be saved
+	std::string cwd                     = get_cwd();
+	const std::string path_output       = cwd + "/output_disk";
+	
+	create_directory_if_not_exist(path_output);
+	//! @cond [Initialization and output folder] @endcond
+	
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Indices for the grid ## {#e2d_c_indices}
+	 *
+	 * Optionally, we can define the grid dimensionality and some indices for better code readability later on.
+	 * * \p x: First dimension
+	 * * \p y: Second dimension
+	 * * \p Phi_0_grid: Index of property that stores the initial level-set-function
+	 * * \p Phi_SDF_grid: Index of property where the redistancing result should be written to
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Indices grid
+	 *
+	 */
+	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	//! @cond [Indices grid] @endcond
+	// Grid dimension
+	const unsigned int grid_dim         = 2;
+	// Some indices for the grid / grid properties
+	const size_t x                      = 0;
+	const size_t y                      = 1;
+	
+	const size_t Phi_0_grid             = 0;
+	const size_t Phi_SDF_grid           = 1;
+	//! @cond [Indices grid] @endcond
+	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Create the grid ## {#e2d_c_grid}
+	 *
+	 * In order to get a grid, we
+	 * * Define the grid size in terms of number of grid points per dimension
+	 * * Create a Box that defines our domain
+	 * * Create a Ghost object that will define the extension of the ghost part
+	 * * Create a 2D grid with two properties of type double, one for the pre-redistancing Phi_initial and one, where
+	 *   the post-redistancing Phi_SDF should be written to.
+	 * * Set some property names (optionally. These names show up when opening the grid vtk in Paraview.)
+	 *
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Grid creation
+	 *
+	 */
+	//! @cond [Grid creation] @endcond
+	// Here we create a 2D grid that stores 2 properties:
+	// Prop1: store the initial Phi;
+	// Prop2: here the re-initialized Phi (signed distance function) will be written to in the re-distancing step
+	size_t sz[grid_dim] = {128, 128}; // Grid size in terms of number of grid points per dimension
+	Box<grid_dim, double> box({0.0, 0.0}, {5.0, 5.0}); // 2D
+	Ghost<grid_dim, long int> ghost(0);
+	typedef aggregate<double, double> props;
+	typedef grid_dist_id<grid_dim, double, props > grid_in_type;
+	grid_in_type g_dist(sz, box, ghost);
+	g_dist.setPropNames({"Phi_0", "Phi_SDF"});
+	//! @cond [Grid creation] @endcond
+	
+	
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Get disk on the grid ## {#e2d_c_getdisk}
+	 *
+	 *
+	 * On the grid that we have just created, we can now initialize Phi_0 as a disk of defined radius.
+	 * The center of the disk is passed as x_center and y_center (see @ref DrawDisk.hpp). Phi_0 will then be:
+	 *
+	 * @f[ \phi_{\text{indicator}} = \begin{cases}
+     *    +1 & \text{point lies inside the object} \\
+     *     0 & \text{object surface} \\
+	 *    -1 & \text{point lies outside the object} \\
+     * \end{cases} @f]
+	 *
+	 * Optionally, we can save this initial grid as a vtk file, if we want to visualize and check it in Paraview.
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Get disk
+	 */
+	//! @cond [Get disk] @endcond
+	// Now we initialize the grid with a disk. Outside the disk, the value of Phi_0 will be -1, inside +1.
+	double radius = 1.0; // Radius of the disk
+	init_grid_with_disk<Phi_0_grid>(g_dist, radius, 2.5, 2.5); // Initialize disk onto grid, centered at (2.5, 2.5)
+	
+	g_dist.write(path_output + "/grid_disk_preRedistancing_radius" + std::to_string((int)radius) , FORMAT_BINARY); // Save the disk as vtk file
+	//! @cond [Get disk] @endcond
+	
+	
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Set the redistancing options ## {#e2d_c_redistoptions}
+	 *
+	 * For the redistancing, we can choose some options. These options will then be passed bundled as a structure to
+	 * the redistancing function. Setting these options is optional, since they all have a Default value as well. In
+	 * particular the following options can be set by the user:
+	 * * \p min_iter: Minimum number of iterations before steady state in narrow band will be checked (Default: 1e5).
+	 * * \p max_iter: Maximum number of iterations you want to run the redistancing, even if steady state might not yet
+	 *                have been reached (Default: 1e12).
+	 * * \p convTolChange.value: Convergence tolerance for the maximal change of Phi within the narrow band between
+	 *                           two consecutive iterations (Default: 1e-15).
+	 * * \p convTolChange.check: Set true, if you want to use the maximal change of Phi between two iterations as
+	 *                           measure of how close you are to the steady state solution. Redistancing will then stop
+	 *                           if convTolChange.value is reached or if the current iteration is bigger than max_iter.
+	 * * \p convTolResidual.value: Convergence tolerance for the residual, that is max{abs(magnitude gradient of phi -
+	 *                              1)} of Phi in the narrow band (Default 1e-3).
+	 * * \p convTolResidual.check: Set true, if you want to use the residual of the current iteration as measure of how
+	 *                             close you are to the steady state solution. Redistancing will then stop if
+	 *                             convTolResidual.value is reached or if the current iteration is bigger than max_iter.
+	 * * \p interval_check_convergence: Interval of #iterations at which convergence to steady state is checked
+	 *                                  (Default: 100).
+	 * * \p width_NB_in_grid_points: Width of narrow band in number of grid points. Must be at least 4, in order to
+	 *                               have at least 2 grid points on each side of the interface. Is automatically set
+	 *                               to 4, if a value smaller than 4 is chosen (Default: 4).
+	 * * \p print_current_iterChangeResidual: If true, the number of the current iteration, the corresponding change
+	 *                                        w.r.t the previous iteration and the residual is printed (Default: false).
+	 * * \p print_steadyState_iter: If true, the number of the steady-state-iteration, the corresponding change
+	 *                              w.r.t the previous iteration and the residual is printed (Default: false).
+	 * * \p save_temp_grid: If true, save the temporary grid as hdf5 that can be reloaded onto a grid (Default: false).
+	 *
+	 *
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Redistancing options
+	 */
+	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	//! @cond [Redistancing options] @endcond
+	// Now we want to convert the initial Phi into a signed distance function (SDF) with magnitude of gradient = 1.
+	// For the initial re-distancing we use the Sussman method. First of all, we can set some redistancing options.
+	Redist_options redist_options;
+	redist_options.min_iter                             = 1e3;
+	redist_options.max_iter                             = 1e4;
+	
+	redist_options.convTolChange.value                  = 1e-7;
+	redist_options.convTolChange.check                  = true;
+	redist_options.convTolResidual.value                = 1e-6; // is ignored if convTolResidual.check = false;
+	redist_options.convTolResidual.check                = false;
+	
+	redist_options.interval_check_convergence           = 1e3;
+	redist_options.width_NB_in_grid_points              = 10;
+	redist_options.print_current_iterChangeResidual     = true;
+	redist_options.print_steadyState_iter               = true;
+	redist_options.save_temp_grid                       = true;
+	//! @cond [Redistancing options] @endcond
+	
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Run the redistancing ## {#e2d_c_runredist}
+	 *
+	 * Now, we can instantiate the Sussman-redistancing class using the redist_options we have just set (or use the
+	 * defaults) and run the redistancing. If we are interested in the time-step that was automatically computed
+	 * internally according to the CFL-condition, we can access it with #RedistancingSussman::get_time_step(). If, for
+	 * whatever reason, we wish to change this timestep, we can do that with #RedistancingSussman::set_user_time_step
+	 * (T dt). However, be careful when setting your own timestep: if chosen too large, the CFL-condition may be no
+	 * longer fulfilled and the method can become unstable. For the #RedistancingSussman::run_redistancing we need to
+	 * provide two template parameters. These are the indices of the respective property that: 1.) contains the
+	 * initial Phi, 2.) should contain the output of the redistancing.
+	 * You can use the same index twice, if you want that your input will be overwritten by the output. This time, it
+	 * makes sense, to save the output grid, since this is already our grid
+	 * containing the signed distance function in Prop. 2. The vtk-file can be opened in Paraview. If we want, we can
+	 * further save the result as hdf5 file that can be reloaded onto an openFPM grid.
+	 *
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Run redistancing
+	 */
+	//! @cond [Run redistancing] @endcond
+	RedistancingSussman<grid_in_type> redist_obj(g_dist, redist_options);   // Instantiation of Sussman-redistancing class
+	// std::cout << "dt = " << redist_obj.get_time_step() << std::endl;
+	// Run the redistancing. In the <> brackets provide property-index where 1.) your initial Phi is stored and 2.)
+	// where the resulting SDF should be written to.
+	redist_obj.run_redistancing<Phi_0_grid, Phi_SDF_grid>();
+	
+	g_dist.write(path_output + "/grid_disk_postRedistancing", FORMAT_BINARY); // Save the result as vtk file
+	g_dist.save(path_output + "/grid_disk_postRedistancing" + ".bin"); // Save the result as hdf5 file that can be
+	// reloaded onto an openFPM grid
+	//! @cond [Run redistancing] @endcond
+	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Initialize empty vector for narrow band particles ## {#e2d_c_initnbvector}
+	 *
+	 * Next, we want to place particles in a narrow band around the interface. For this, we need to create an empty
+	 * vector in the same domain as our grid from before. We therefore re-use the \p box and \p ghost that we defined
+	 * during grid creation. This time, we have to set the boundary conditions (see general OpenFPM vector_dist
+	 * documentation for details.) We also have to choose now, how many properties our particle should store. Minimum is
+	 * one, but you can have particles with arbitrary many properties, depending on what you want to use them for
+	 * later on. Here, we exemplarily define 3 properties.
+	 *
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Initialize narrow band
+	 */
+	//! @cond [Initialize narrow band] @endcond
+	//	Get narrow band: Place particles on interface (narrow band width e.g. 2 grid points on each side of the interface)
+	size_t bc[grid_dim] = {PERIODIC, PERIODIC};
+	// Create an empty vector to which narrow-band particles will be added. You can choose, how many properties you want.
+	// Minimum is 1 property, to which the Phi_SDF can be written
+	// In this example we chose 3 properties. The 1st for the Phi_SDF, the 2nd for the gradient of phi and the 3rd for
+	// the magnitude of the gradient
+	typedef aggregate<double, double[grid_dim], double> props_nb;
+	typedef vector_dist<grid_dim, double, props_nb> vd_type;
+	Ghost<grid_dim, double> ghost_vd(0);
+	vd_type vd_narrow_band(0, box, bc, ghost_vd);
+	vd_narrow_band.setPropNames({"Phi_SDF", "Phi_grad", "Phi_magnOfGrad"});
+	//! @cond [Initialize narrow band] @endcond
+	
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Instantiate narrow band ## {#e2d_c_instnarrowband}
+	 *
+	 * Before we fill the empty vector that we just created with particles, we define how thick the narrow band
+	 * around the interface should be.
+	 * This is independent of the redist_options.width_NB_in_grid_points that we chose before. However, it makes
+	 * sense to use a width during redistancing which is at least as large as the width that we want to place the
+	 * particles in. The reason is that convergence criteria were checked for that part of the grid only, which
+	 * belonged to the narrow band.
+	 *
+	 * Depending on the type of the variable which you define, the width can be either set in terms of number of
+	 * grid points (size_t), physical width (double) or extension of narrow band as physical width inside of object
+	 * and outside the object (double, double).
+	 *
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Instantiate narrow band
+	 */
+	//! @cond [Instantiate narrow band] @endcond
+	size_t thickness_of_narrowBand_in_grid_points = 6;
+	NarrowBand<grid_in_type> narrowBand(g_dist, thickness_of_narrowBand_in_grid_points); // Instantiation of NarrowBand class
+	//! @cond [Instantiate narrow band] @endcond
+	
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Indices for the narrow band vector ## {#e2d_c_indices}
+	 *
+	 * Again, we can define some indices for better code readability. This is just an example, you may want to choose
+	 * different names and have a different number of properties thus different number of indices.
+	 *
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Indices narrow band
+	 *
+	 */
+	//////////////////////////////////////////////////////////////////////////////////////////////
+	//! @cond [Indices narrow band] @endcond
+	// Some indices
+	const size_t Phi_SDF_vd             = 0;
+	const size_t Phi_grad_vd            = 1;
+	const size_t Phi_magnOfGrad_vd      = 2;
+	//! @cond [Indices narrow band] @endcond
+	
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Fill the vector with particles placed within a narrow band around the interface ## {#e2d_c_getnarrowband}
+	 *
+	 * Now, we finally fill the vector with particles placed in a narrow band around the interface. The first
+	 * template parameter that we pass, must always be the index of the grid property that contains the Phi_SDF.
+	 *
+	 * Then you can decide between the following options, what you want to copy from the grid to the particles:
+	 * * Only copy the Phi_SDF: \p narrowBand.get_narrow_band<Phi_SDF_grid, Phi_SDF_vd>(g_dist, vd_narrow_band);
+	 * * Copy Phi_SDF as well as the first order upwind gradient of Phi_SDF: \p narrowBand
+	 *   .get_narrow_band<Phi_SDF_grid, Phi_SDF_vd, Phi_grad_vd>(g_dist, vd_narrow_band);
+	 * * Copy Phi_SDF as well as the first order upwind gradient of Phi_SDF and the corresponding gradient magnitude:
+	 *   \p narrowBand.get_narrow_band<Phi_SDF_grid, Phi_SDF_vd, Phi_grad_vd, Phi_magnOfGrad_vd>(g_dist,
+	 *   vd_narrow_band);
+	 * * Copy an arbitrary property: \p narrowBand.get_narrow_band_copy_specific_property<Phi_SDF_grid,
+	 *   Prop_index_grid, Prop_index_vector>(g_dist, vd_narrow_band);
+	 *
+	 * We save the particles in a vtk file (open in Paraview) and as hdf5 file (can be loaded back on particles).
+	 *
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Get narrow band
+	 */
+	// Get the narrow band. You can decide, if you only want the Phi_SDF saved to your particles or
+	// if you also want the gradients or gradients and magnitude of gradient.
+	// The function will know depending on how many property-indices you provide in the <> brackets.
+	// First property-index must always be the index of the SDF on the grid!
+	// E.g.: The following line would only write only the Phi_SDF from the grid to your narrow-band particles
+	// narrowBand.get_narrow_band<Phi_SDF_grid, Phi_SDF_vd>(g_dist, vd_narrow_band);
+	// Whereas this will give you the gradients and magnOfGrad of Phi as well:
+	//! @cond [Get narrow band] @endcond
+	narrowBand.get_narrow_band<Phi_SDF_grid, Phi_SDF_vd, Phi_grad_vd, Phi_magnOfGrad_vd>(g_dist, vd_narrow_band);
+	
+	vd_narrow_band.write(path_output + "/vd_narrow_band_disk", FORMAT_BINARY); // Save particles as vtk file
+	vd_narrow_band.save(path_output + "/vd_narrow_band_disk.bin"); // Save particles as hdf5 file -> can be reloaded as particles
+	//! @cond [Get narrow band] @endcond
+	
+	/**
+	 * @page example_sussman_disk Disk 2D
+	 *
+	 * ## Terminate ## {#e2d_c_terminate}
+	 *
+	 * We end with terminating OpenFPM
+	 *
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Terminate
+	 */
+	//! @cond [Terminate] @endcond
+	openfpm_finalize(); // Finalize openFPM library
+	return 0;
+}
+//! @cond [Terminate] @endcond
+
+/**
+ * @page example_sussman_disk Disk 2D
+ *
+ * ## Full code ## {#e2d_c_full}
+ *
+ * @include example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp
+ */
+
+
+
+
+
diff --git a/example/Numerics/Sussman_redistancing/example_sussman_images_2D/main.cpp b/example/Numerics/Sussman_redistancing/example_sussman_images_2D/main.cpp
index 9a2b15076..d17017f82 100644
--- a/example/Numerics/Sussman_redistancing/example_sussman_images_2D/main.cpp
+++ b/example/Numerics/Sussman_redistancing/example_sussman_images_2D/main.cpp
@@ -11,7 +11,7 @@
  * * Build a 2D cartesian OpenFPM grid with same dimensions as the image (1 particle for each pixel in x and y) or
  *   refined by arbitrary factor in dimension of choice (e.g. to get a isotropic grid)
  * * Assign pixel value to a grid node property
- * * Run the Sussman Redistancing and get the narrow band around the interface (see also: @ref example_sussman_circle
+ * * Run the Sussman Redistancing and get the narrow band around the interface (see also: @ref example_sussman_disk
  *   and example_sussman_sphere)
  *
  * Output:
@@ -148,7 +148,7 @@ int main(int argc, char* argv[])
 	 *
 	 */
 	//! @cond [Size] @endcond
-	std::vector<size_t> stack_size = get_size(path_to_size);
+	std::vector<int> stack_size = get_size(path_to_size);
 	auto & v_cl = create_vcluster();
 	if (v_cl.rank() == 0)
 	{
@@ -160,7 +160,8 @@ int main(int argc, char* argv[])
 	}
 	
 	//  Array with grid dimensions after refinement. This size-array will be used for the grid creation.
-	const size_t sz[grid_dim] = {(size_t)std::round(stack_size[x] * refinement[x]), (size_t)std::round(stack_size[y] * refinement[y])}; // 2D
+	const size_t sz[grid_dim] = {(size_t)std::round(stack_size[x] * refinement[x]), (size_t)std::round(stack_size[y] *
+							refinement[y])}; // 2D
 	//! @cond [Size] @endcond
 	// Here we create a 2D grid that stores 2 properties:
 	// Prop1: store the initial Phi;
@@ -172,7 +173,7 @@ int main(int argc, char* argv[])
 	 *
 	 * Once we have loaded the geometrical object from the 2D image onto the grid, we can perform Sussman
 	 * redistancing and get the narrow band the same way as it is explained in detail here: @ref
-	 * example_sussman_circle and here: @ref example_sussman_sphere.
+	 * example_sussman_disk and here: @ref example_sussman_sphere.
 	 *
 	 *
 	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_images_2D/main.cpp Redistancing
@@ -195,22 +196,21 @@ int main(int argc, char* argv[])
 	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 	// Now we want to convert the initial Phi into a signed distance function (SDF) with magnitude of gradient = 1
 	// For the initial re-distancing we use the Sussman method
-	// 1.) Set some redistancing options
+	// 1.) Set some redistancing options (for details see example sussman disk or sphere)
 	Redist_options redist_options;
-	redist_options.min_iter                             = 100;      // min. number of iterations before steady state in narrow band will be checked (default: 100)
-	redist_options.max_iter                             = 10000;    // max. number of iterations you want to run the
-																	// redistancing, even if steady state might not yet have been reached (default: 1e6)
+	redist_options.min_iter                             = 1e3;
+	redist_options.max_iter                             = 1e4;
 	
-	redist_options.convTolChange.value                  = 1e-6;     // convolution tolerance for the normalized total change of Phi in the narrow band between two consecutive iteratins (default: 1e-6)
-	redist_options.convTolChange.check                  = true;     // define here which of the convergence criteria above should be used. If both are true, termination only occurs when both are fulfilled or when iter > max_iter
-	redist_options.convTolResidual.value                = 1e-1;     // convolution tolerance for the normalized total residual of Phi versus the SDF (aka the error). Don't choose too small to not run forever. (default: 1e-1)
-	redist_options.convTolResidual.check                = false;    // (default: false)
+	redist_options.convTolChange.value                  = 1e-7;
+	redist_options.convTolChange.check                  = true;
+	redist_options.convTolResidual.value                = 1e-6; // is ignored if convTolResidual.check = false;
+	redist_options.convTolResidual.check                = false;
 	
-	redist_options.interval_check_convergence           = 1;        // interval of #iterations at which convergence is checked (default: 100)
-	redist_options.width_NB_in_grid_points              = 6;        // width of narrow band in number of grid points.
-	// Must be at least 4, in order to have at least 2 grid points on each side of the interface. (default: 4)
-	redist_options.print_current_iterChangeResidual     = true;     // if true, prints out every current iteration + corresponding change from the previous iteration + residual from SDF (default: false)
-	redist_options.print_steadyState_iter               = true;     // if true, prints out the final iteration number when steady state was reached + final change + residual (default: true)
+	redist_options.interval_check_convergence           = 1e3;
+	redist_options.width_NB_in_grid_points              = 10;
+	redist_options.print_current_iterChangeResidual     = true;
+	redist_options.print_steadyState_iter               = true;
+	redist_options.save_temp_grid                       = true;
 	
 	RedistancingSussman<grid_in_type> redist_obj(g_dist, redist_options);   // Instantiation of Sussman-redistancing class
 //	std::cout << "dt = " << redist_obj.get_time_step() << std::endl;
diff --git a/example/Numerics/Sussman_redistancing/example_sussman_images_3D/main.cpp b/example/Numerics/Sussman_redistancing/example_sussman_images_3D/main.cpp
index 6dcdb680f..cbec16e6f 100644
--- a/example/Numerics/Sussman_redistancing/example_sussman_images_3D/main.cpp
+++ b/example/Numerics/Sussman_redistancing/example_sussman_images_3D/main.cpp
@@ -141,7 +141,7 @@ int main(int argc, char* argv[])
 	 *
 	 */
 	//! @cond [Size] @endcond
-	std::vector<size_t> stack_size = get_size(path_to_size);
+	std::vector<int> stack_size = get_size(path_to_size);
 	auto & v_cl = create_vcluster();
 	if (v_cl.rank() == 0)
 	{
@@ -166,7 +166,7 @@ int main(int argc, char* argv[])
 	 *
 	 * Once we have loaded the geometrical object from the 3D stack onto the grid, we can perform Sussman
 	 * redistancing and get the narrow band the same way as it is explained in detail here: @ref
-	 * example_sussman_circle and here: @ref example_sussman_sphere.
+	 * example_sussman_disk and here: @ref example_sussman_sphere.
 	 *
 	 *
 	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_images_3D/main.cpp Redistancing
@@ -189,25 +189,21 @@ int main(int argc, char* argv[])
 	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 	// Now we want to convert the initial Phi into a signed distance function (SDF) with magnitude of gradient = 1
 	// For the initial re-distancing we use the Sussman method
-	// 1.) Set some redistancing options
+	// 1.) Set some redistancing options (for details see example sussman disk or sphere)
 	Redist_options redist_options;
-	redist_options.min_iter                             = 100;      // min. number of iterations before steady state in narrow band will be checked (default: 100)
-	redist_options.max_iter                             = 10000;    // max. number of iterations you want to run the
-															        // redistancing, even if steady state might not yet
-															        // have been reached (default: 1e6)
-	redist_options.convTolChange.value                  = 1e-6;     // convolution tolerance for the normalized total change of Phi in the narrow band between two consecutive iteratins (default: 1e-6)
-	redist_options.convTolChange.check                  = true;     // define here which of the convergence criteria above should be used. If both are true, termination only occurs when both are fulfilled or when iter > max_iter
-	redist_options.convTolResidual.value                = 1e-1;     // convolution tolerance for the normalized total residual of Phi versus the SDF (aka the error). Don't choose too small to not run forever. (default: 1e-1)
-	redist_options.convTolResidual.check                = false;    // (default: false)
+	redist_options.min_iter                             = 1e3;
+	redist_options.max_iter                             = 1e4;
 	
-	redist_options.interval_check_convergence           = 1;        // interval of #iterations at which convergence is checked (default: 100)
-	redist_options.width_NB_in_grid_points              = 6;        // width of narrow band in number of grid points.
-															        // Must be at least 4, in order to have at least 2
-															        // grid points on each side of the interface.
-															        // (default: 4)
-	redist_options.print_current_iterChangeResidual     = true;     // if true, prints out every current iteration + corresponding change from the previous iteration + residual from SDF (default: false)
-	redist_options.print_steadyState_iter               = true;     // if true, prints out the final iteration number when steady state was reached + final change + residual (default: true)
+	redist_options.convTolChange.value                  = 1e-7;
+	redist_options.convTolChange.check                  = true;
+	redist_options.convTolResidual.value                = 1e-6; // is ignored if convTolResidual.check = false;
+	redist_options.convTolResidual.check                = false;
 	
+	redist_options.interval_check_convergence           = 1e3;
+	redist_options.width_NB_in_grid_points              = 10;
+	redist_options.print_current_iterChangeResidual     = true;
+	redist_options.print_steadyState_iter               = true;
+	redist_options.save_temp_grid                       = true;
 	RedistancingSussman<grid_in_type> redist_obj(g_dist, redist_options);   // Instantiation of Sussman-redistancing class
 //	std::cout << "dt = " << redist_obj.get_time_step() << std::endl;
 	// Run the redistancing. in the <> brackets provide property-index where 1.) your initial Phi is stored and 2.) where the resulting SDF should be written to.
diff --git a/example/Numerics/Sussman_redistancing/example_sussman_sphere/main.cpp b/example/Numerics/Sussman_redistancing/example_sussman_sphere/main.cpp
index 9be98523c..966094a69 100644
--- a/example/Numerics/Sussman_redistancing/example_sussman_sphere/main.cpp
+++ b/example/Numerics/Sussman_redistancing/example_sussman_sphere/main.cpp
@@ -183,51 +183,54 @@ int main(int argc, char* argv[])
 	 *
 	 * ## Set the redistancing options ## {#e3d_s_redistoptions}
 	 *
-	 * For the redistancing, we can choose some options. These options will then be passed bundled as a structure to
+		 * For the redistancing, we can choose some options. These options will then be passed bundled as a structure to
 	 * the redistancing function. Setting these options is optional, since they all have a Default value as well. In
 	 * particular the following options can be set by the user:
-	 * * \p min_iter: Minimum number of iterations before steady state in narrow band will be checked (Default: 100).
+	 * * \p min_iter: Minimum number of iterations before steady state in narrow band will be checked (Default: 1e5).
 	 * * \p max_iter: Maximum number of iterations you want to run the redistancing, even if steady state might not yet
-	 *                have been reached (Default: 1e6).
-	 * * \p convTolChange.value: Convolution tolerance for the normalized total change of Phi in the narrow band between
-	 *                           two consecutive iterations (Default: 1e-6).
-	 * * \p convTolChange.check: Set true, if you want to use the normalized total change between two iterations as
+	 *                have been reached (Default: 1e12).
+	 * * \p convTolChange.value: Convergence tolerance for the maximal change of Phi within the narrow band between
+	 *                           two consecutive iterations (Default: 1e-15).
+	 * * \p convTolChange.check: Set true, if you want to use the maximal change of Phi between two iterations as
 	 *                           measure of how close you are to the steady state solution. Redistancing will then stop
 	 *                           if convTolChange.value is reached or if the current iteration is bigger than max_iter.
-	 * * \p convTolResidual.value: Convolution tolerance for the residual, that is abs(magnitude gradient of phi - 1) of
-	 *                             Phi in the narrow band (Default 1e-1).
+	 * * \p convTolResidual.value: Convergence tolerance for the residual, that is max{abs(magnitude gradient of phi -
+	 *                              1)} of Phi in the narrow band (Default 1e-3).
 	 * * \p convTolResidual.check: Set true, if you want to use the residual of the current iteration as measure of how
 	 *                             close you are to the steady state solution. Redistancing will then stop if
 	 *                             convTolResidual.value is reached or if the current iteration is bigger than max_iter.
 	 * * \p interval_check_convergence: Interval of #iterations at which convergence to steady state is checked
 	 *                                  (Default: 100).
-	 * * \p width_NB_in_grid_points: Width of narrow band in number of grid points. Must be at least 4, in order to 
-	 *                               have at least 2 grid points on each side of the interface. Is automatically set 
+	 * * \p width_NB_in_grid_points: Width of narrow band in number of grid points. Must be at least 4, in order to
+	 *                               have at least 2 grid points on each side of the interface. Is automatically set
 	 *                               to 4, if a value smaller than 4 is chosen (Default: 4).
 	 * * \p print_current_iterChangeResidual: If true, the number of the current iteration, the corresponding change
 	 *                                        w.r.t the previous iteration and the residual is printed (Default: false).
 	 * * \p print_steadyState_iter: If true, the number of the steady-state-iteration, the corresponding change
 	 *                              w.r.t the previous iteration and the residual is printed (Default: false).
+	 * * \p save_temp_grid: If true, save the temporary grid as hdf5 that can be reloaded onto a grid (Default: false).
 	 *
-	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_sphere/main.cpp Redistancing options
+	 *
+	 * @snippet example/Numerics/Sussman_redistancing/example_sussman_disk/main.cpp Redistancing options
 	 */
 	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 	//! @cond [Redistancing options] @endcond
 	// Now we want to convert the initial Phi into a signed distance function (SDF) with magnitude of gradient = 1.
 	// For the initial re-distancing we use the Sussman method. First of all, we can set some redistancing options.
 	Redist_options redist_options;
-	redist_options.min_iter                             = 100;
-	redist_options.max_iter                             = 1000;
+	redist_options.min_iter                             = 1e3;
+	redist_options.max_iter                             = 1e4;
 	
-	redist_options.convTolChange.value                  = 1e-12;
+	redist_options.convTolChange.value                  = 1e-7;
 	redist_options.convTolChange.check                  = true;
-	redist_options.convTolResidual.value                = 1e-1;
+	redist_options.convTolResidual.value                = 1e-6; // is ignored if convTolResidual.check = false;
 	redist_options.convTolResidual.check                = false;
 	
-	redist_options.interval_check_convergence           = 1;
-	redist_options.width_NB_in_grid_points              = 6;
+	redist_options.interval_check_convergence           = 1e3;
+	redist_options.width_NB_in_grid_points              = 10;
 	redist_options.print_current_iterChangeResidual     = true;
 	redist_options.print_steadyState_iter               = true;
+	redist_options.save_temp_grid                       = true;
 	//! @cond [Redistancing options] @endcond
 	
 	/**
-- 
GitLab