diff --git a/.gitignore b/.gitignore
index c3b074a7a2bf1db27187ab2b651ebcd2f4126599..f531e9199adb33270686c22a61c239834ce0b555 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,8 @@
 *.so
 *.dylib
 *.vtu
+*.nc
 lib
 include
 vis
+data
diff --git a/amatos2d/compile/Makefiles/Makefile.common b/amatos2d/compile/Makefiles/Makefile.common
index 4f106850b25625ec177cb2dac61ac9e0147d91b9..01f1cc20542256180b97aa9867fd1ed34e5823f0 100644
--- a/amatos2d/compile/Makefiles/Makefile.common
+++ b/amatos2d/compile/Makefiles/Makefile.common
@@ -46,6 +46,12 @@ ifeq ($(strip $(SYSTEM)), gfortran)
    SEROBJ+= MISC_wrapper.o
 endif
 
+AMATLIBCALL = -lamatos
+ifeq ($(strip $(MAKETHING)), SAMATOS)
+   AMATLIBCALL = -lsamatos
+endif
+
+
 # -------- include additional Macros ----------------------------#
 FFLAGS += $(MACROS:%=$(MF)%)
 CFLAGS += $(MACROS:%=$(MF)%)
@@ -103,7 +109,7 @@ libncugrid.a: IO_ncugrid.o
 
 $(NCUSLIB): $(NCULIB)
 	@echo "make: Creating dynamic shared object (dso) library"
-	$(LOADER) $(SHFLAGS) -o $(NCUSLIB) IO_ncugrid.o -L$(LIBDIR) -lamatos $(NETCDFLIB)
+	$(LOADER) $(SHFLAGS) -o $(NCUSLIB) IO_ncugrid.o -L$(LIBDIR) $(AMATLIBCALL) $(NETCDFLIB)
 
 testncugrid: test_io_ncugrid.o
 	@echo "make: Linking object modules and libraries"
diff --git a/amatos2d/compile/Makefiles/Makefile_macosxGfortran_amatos b/amatos2d/compile/Makefiles/Makefile_macosxGfortran_amatos
index b21840771cf935892d1867e78a4e14ffd76289a7..7ed8a01524a728fbd925d84a4e3636b689609ffa 100644
--- a/amatos2d/compile/Makefiles/Makefile_macosxGfortran_amatos
+++ b/amatos2d/compile/Makefiles/Makefile_macosxGfortran_amatos
@@ -71,8 +71,8 @@ endif
 BITMAPLIB =
 BITMAPINC =
 ifeq ($(strip $(IO_PGM)),yes)
-  BITMAPLIB = -L/sw2/lib -lnetpbm
-  BITMAPINC = -I/sw2/include
+  BITMAPLIB = -L/opt/local/lib -lnetpbm
+  BITMAPINC = -I/opt/local/include
 endif
 
 # SET NETCDF PATHS
@@ -81,8 +81,8 @@ NETCDFLIB =
 NETCDFINC =
 NCUGRIDLIB =
 ifneq ($(strip $(NO_NETCDF)), yes)
-  NETCDFLIB = -L/sw2/lib -lnetcdff -lnetcdf
-  NETCDFINC = -I/sw2/include
+  NETCDFLIB = -L/opt/local/lib -lnetcdff -lnetcdf
+  NETCDFINC = -I/opt/local/include
   NCUGRIDLIB = -lncugrid
 endif
 
diff --git a/amatos2d/compile/Makefiles/Makefile_macosxGfortran_amatos.alternative b/amatos2d/compile/Makefiles/Makefile_macosxGfortran_amatos.alternative
new file mode 100644
index 0000000000000000000000000000000000000000..a54b7e75438ce322af9c1533151eb9f14604ccf5
--- /dev/null
+++ b/amatos2d/compile/Makefiles/Makefile_macosxGfortran_amatos.alternative
@@ -0,0 +1,230 @@
+##################################################################
+#   AMATOS                                                       #
+#   Adaptive Mesh generator for                                  #
+#   ATmospheric and Oceanic Simulation                           #
+##################################################################
+# makefile to build AMATOS / library objects of amatos API       #
+# j. behrens 2/95, 3/96, 5/97, 12/2003                           #
+# l. mentrup 1/2005                                              #
+# --- this is for Mac OS X on Intel architecture ---             #
+# --- using the intel Fortran compiler ---                       #
+##################################################################
+
+# MACHINE
+MACHINE = macosx_gfortran
+
+# SYSTEM
+SYSTEM = gfortran
+
+# SET MAKETHING CORRESPONDING TO MACHINE:
+MAKETHING= AMATOS
+AMATFLAG = $(MF)$(MAKETHING)
+
+SAVETHING= SAVETEST
+
+# OPTIMIZATION SETTINGS [debug|opt|norm|opt]
+MODE := debug
+
+# CREATE SHARED LIBRARIES
+CREATE_SHARED := no #yes
+
+# FURTHER OPTIONS
+DBL_DBL    := yes
+
+# PARALLELISM SETTINGS
+OMP := no
+MPI := no
+
+# LIBRARY SETTINGS [yes|no]
+# Usage: $(MAKE) NO_NETCDF=yes
+NO_NETCDF := no
+
+# LIBRARY SETTINGS [yes|no]
+# Usage: make IO_EMIT=yes IO_PGM=yes
+IO_EMIT := no
+IO_PGM  := yes
+
+# ADDITIONAL MACRO DEFS
+MACROS =
+
+# SET MAIN DIRECTORY PATH
+# !! This has to be alterd by user !!
+ROOTDIR = $(HOME)/Documents/Teaching/WS2021/Transport-20/tracertransportsoftware
+
+# SET atlas/blas DIRECTORY PATH
+# !! This has to be alterd by user !!
+BLASLIB = -L/opt/local/lib/lapack -lblas
+
+# SET LAPACK DIRECTORY PATH
+# !! This has to be alterd by user !!
+LAPACKLIB = -L/opt/local/lib/lapack -llapack \
+                        -L/$(ROOTDIR)/amatos2d/3rdparty/LAPACK95 -llapack95
+
+# SET IO_EMIT LIBRARY PATH
+# !! This has to be alterd by user !!
+EMITLIB =
+ifeq ($(strip $(IO_EMIT)),yes)
+  EMITLIB = -lstdc++ #-lresolv -lsocket -lnsl -lCstd
+endif
+
+# SET BITMAP LIBRARY PATH
+# !! This has to be alterd by user !!
+BITMAPLIB =
+BITMAPINC =
+ifeq ($(strip $(IO_PGM)),yes)
+  BITMAPLIB = -L/opt/local/lib -lnetpbm
+  BITMAPINC = -I/opt/local/include
+endif
+
+# SET NETCDF PATHS
+# !! This has to be alterd by user !!
+NETCDFLIB =
+NETCDFINC =
+NCUGRIDLIB =
+ifneq ($(strip $(NO_NETCDF)), yes)
+  NETCDFLIB = -L/opt/local/lib -lnetcdff -lnetcdf
+  NETCDFINC = -I/opt/local/include
+  NCUGRIDLIB = -lncugrid
+endif
+
+# SET MORE DIRECTORY PATHS
+MAINDIR = $(ROOTDIR)/amatos2d
+
+BUILDIR = $(MAINDIR)/compile/$(MACHINE)
+LIBDIR  = $(ROOTDIR)/lib/$(MACHINE)
+INCDIR  = $(ROOTDIR)/include/$(MACHINE)
+DATDIR  = $(MAINDIR)/data
+SRCDIR  = $(MAINDIR)/src
+
+TSTDIR  = $(SRCDIR)/test
+GRIDDIR = $(SRCDIR)/gridgen
+SYSDIR  = $(SRCDIR)/system/$(SYSTEM)
+TIMDIR  = $(SRCDIR)/timing
+
+GRIDLIB = libamatos.a
+GRDSLIB = libamatos.dylib
+NCULIB  = libncugrid.a
+NCUSLIB = libncugrid.dylib
+MODEND  = mod
+GRDMOD  = *.$(MODEND)
+
+#----------------------------------------------------------------#
+# library and include paths                                      #
+#----------------------------------------------------------------#
+LIB_SH     = $(LAPACKLIB) $(EMITLIB)
+LIBS       = -L$(LIBDIR) -lamatos $(NCUGRIDLIB) $(NETCDFLIB) \
+             $(LAPACKLIB) $(BLASLIB) $(BITMAPLIB)
+INCPATH    = $(NETCDFINC) -I$(INCDIR) -I.
+INCPATH_CC = $(BITMAPINC)
+
+#----------------------------------------------------------------#
+# FLAGS FOR LINUX / gnu Fortran Compiler                         #
+#----------------------------------------------------------------#
+F90     = gfortran
+cc      = gcc
+CC      = g++
+LOADER  = gfortran
+AR      = ar
+CP      = cp
+CPFLAGS =
+ARFLAGS = vru
+# Compiler flag for macros
+MF = -D
+
+# --------------------- next are for debugging ------------------#
+ifeq ($(strip $(MODE)),debug)
+  FFLAGS  = -fbounds-check -ggdb -fpic -funderscoring # -C
+  CFLAGS  = -ggdb -fpic -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
+  LDFLAGS = -ggdb -mmacosx-version-min=10.11
+  SHFLAGS = -fpic -dynamiclib -mmacosx-version-min=10.11
+endif
+# --------------------- next are for optimized debugging --------#
+ifeq ($(strip $(MODE)),optdebug)
+  FFLAGS  = -fPIC -funderscoring # -C
+  CFLAGS  = -g -fpic
+  LDFLAGS = -g
+  SHFLAGS = -fPIC -shared
+endif
+# --------------------- next are for normal compilation ---------#
+ifeq ($(strip $(MODE)),norm)
+  FFLAGS  = -fPIC -funderscoring
+  CFLAGS  = -fpic
+  LDFLAGS =
+  SHFLAGS = -fPIC -shared
+endif
+# --------------------- next are for optimization ---------------#
+ifeq ($(strip $(MODE)),opt)
+  FFLAGS  = -O3 -fPIC -funderscoring
+  CFLAGS  = -O3 -fpic
+  LDFLAGS = -O3
+  SHFLAGS = -fPIC -shared
+endif
+
+# ----- next flags identify the fortran compiler ----------------#
+FFLAGS += $(MF)$(F90)
+CFLAGS += $(MF)$(F90) -D$(MACHINE)
+
+# --------------------- next are for Module IO_EMIT -------------#
+ifeq ($(strip $(IO_EMIT)),yes)
+  LIB_SH  += $(EMITLIB)
+  FFLAGS += $(MF)IO_EMIT
+  CFLAGS += $(MF)IO_EMIT
+endif
+# --------------------- next are for Module IO_PGM --------------#
+ifeq ($(strip $(IO_PGM)),yes)
+  LIBS  += $(BITMAPLIB)
+  FFLAGS += $(MF)IO_PGM
+  CFLAGS += $(MF)IO_PGM
+endif
+# --------------------- next are for NetCDF support -------------#
+ifeq ($(strip $(NO_NETCDF)),yes)
+  FFLAGS += $(MF)NO_NETCDF
+endif
+# --------------------- next are for OpenMP ---------------------#
+ifeq ($(strip $(OMP)),yes)
+  #LIBS   +=
+  #FFLAGS +=
+  #CFLAGS +=
+endif
+# --------------------- next are for MPI ------------------------#
+ifeq ($(strip $(MPI)),yes)
+  #LIBS   +=
+  #FFLAGS +=
+  #CFLAGS +=
+endif
+# --------------------- next are for double precision -----------#
+ifeq ($(strip $(DBL_DBL)), yes)
+  FFLAGS += -DDBL_DBL
+endif
+
+#----------------------------------------------------------------#
+# additional clear/clean-Items                                   #
+#----------------------------------------------------------------#
+CLEARSRC_EXT  =
+CLEAREX_EXT   = $(SAVETHING) *.dylib
+CLEARDAT_EXT  = $(SAVETHING:%=%_*)
+CLEARLIB_EXT  =
+CLEAN_EXT     = *.vtu 
+TIDY_EXT      = *.i90 *.s
+
+#----------------------------------------------------------------#
+# common stuff                                                   #
+#----------------------------------------------------------------#
+
+include $(MAINDIR)/compile/Makefiles/Makefile.common
+
+#----------------------------------------------------------------#
+# copy source files                                              #
+#----------------------------------------------------------------#
+
+include $(MAINDIR)/compile/Makefiles/Makefile.cpsrc
+
+#----------------------------------------------------------------#
+# test programs                                                  #
+#----------------------------------------------------------------#
+
+include $(MAINDIR)/compile/Makefiles/Makefile.TestsAmatos
+
+#----------------------------------------------------------------#
+# DEPENDENCIES ON INCLUDE FILES                                  #
+#----------------------------------------------------------------#
diff --git a/amatos2d/compile/macosx_gfortran/Makefile b/amatos2d/compile/macosx_gfortran/Makefile
index a54b7e75438ce322af9c1533151eb9f14604ccf5..acddd0255fe782ee1d741637daf9b4dbae1cbbfa 100644
--- a/amatos2d/compile/macosx_gfortran/Makefile
+++ b/amatos2d/compile/macosx_gfortran/Makefile
@@ -17,7 +17,7 @@ MACHINE = macosx_gfortran
 SYSTEM = gfortran
 
 # SET MAKETHING CORRESPONDING TO MACHINE:
-MAKETHING= AMATOS
+MAKETHING= SAMATOS
 AMATFLAG = $(MF)$(MAKETHING)
 
 SAVETHING= SAVETEST
@@ -26,7 +26,7 @@ SAVETHING= SAVETEST
 MODE := debug
 
 # CREATE SHARED LIBRARIES
-CREATE_SHARED := no #yes
+CREATE_SHARED := yes
 
 # FURTHER OPTIONS
 DBL_DBL    := yes
@@ -49,16 +49,15 @@ MACROS =
 
 # SET MAIN DIRECTORY PATH
 # !! This has to be alterd by user !!
-ROOTDIR = $(HOME)/Documents/Teaching/WS2021/Transport-20/tracertransportsoftware
+ROOTDIR = $(HOME)/Documents/Teaching/WS2021/Transport-20/TracerTransportSoftware
 
 # SET atlas/blas DIRECTORY PATH
 # !! This has to be alterd by user !!
-BLASLIB = -L/opt/local/lib/lapack -lblas
+BLASLIB = 
 
 # SET LAPACK DIRECTORY PATH
 # !! This has to be alterd by user !!
-LAPACKLIB = -L/opt/local/lib/lapack -llapack \
-                        -L/$(ROOTDIR)/amatos2d/3rdparty/LAPACK95 -llapack95
+LAPACKLIB = -framework Accelerate
 
 # SET IO_EMIT LIBRARY PATH
 # !! This has to be alterd by user !!
@@ -101,8 +100,8 @@ GRIDDIR = $(SRCDIR)/gridgen
 SYSDIR  = $(SRCDIR)/system/$(SYSTEM)
 TIMDIR  = $(SRCDIR)/timing
 
-GRIDLIB = libamatos.a
-GRDSLIB = libamatos.dylib
+GRIDLIB = libsamatos.a
+GRDSLIB = libsamatos.dylib
 NCULIB  = libncugrid.a
 NCUSLIB = libncugrid.dylib
 MODEND  = mod
@@ -112,7 +111,7 @@ GRDMOD  = *.$(MODEND)
 # library and include paths                                      #
 #----------------------------------------------------------------#
 LIB_SH     = $(LAPACKLIB) $(EMITLIB)
-LIBS       = -L$(LIBDIR) -lamatos $(NCUGRIDLIB) $(NETCDFLIB) \
+LIBS       = -L$(LIBDIR) -lsamatos $(NCUGRIDLIB) $(NETCDFLIB) \
              $(LAPACKLIB) $(BLASLIB) $(BITMAPLIB)
 INCPATH    = $(NETCDFINC) -I$(INCDIR) -I.
 INCPATH_CC = $(BITMAPINC)
@@ -134,7 +133,7 @@ MF = -D
 # --------------------- next are for debugging ------------------#
 ifeq ($(strip $(MODE)),debug)
   FFLAGS  = -fbounds-check -ggdb -fpic -funderscoring # -C
-  CFLAGS  = -ggdb -fpic -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
+  CFLAGS  = -ggdb -fpic
   LDFLAGS = -ggdb -mmacosx-version-min=10.11
   SHFLAGS = -fpic -dynamiclib -mmacosx-version-min=10.11
 endif
@@ -223,7 +222,7 @@ include $(MAINDIR)/compile/Makefiles/Makefile.cpsrc
 # test programs                                                  #
 #----------------------------------------------------------------#
 
-include $(MAINDIR)/compile/Makefiles/Makefile.TestsAmatos
+include $(MAINDIR)/compile/Makefiles/Makefile.TestsSamatos
 
 #----------------------------------------------------------------#
 # DEPENDENCIES ON INCLUDE FILES                                  #
diff --git a/amatos2d/compile/macosx_intel/Makefile b/amatos2d/compile/macosx_intel/Makefile
index 2d5716749b86ffa6af8a4ca029dda6785650b409..ce87c760220e6632960491c7e85b89e9da7742f1 100644
--- a/amatos2d/compile/macosx_intel/Makefile
+++ b/amatos2d/compile/macosx_intel/Makefile
@@ -49,7 +49,7 @@ MACROS =
 
 # SET MAIN DIRECTORY PATH
 # !! This has to be alterd by user !!
-ROOTDIR = $(HOME)/Documents/Development/amatos
+ROOTDIR = $(HOME)/Documents/Teaching/WS2021/Transport-20/TracerTransportSoftware
 
 # SET atlas/blas DIRECTORY PATH
 # !! This has to be alterd by user !!
@@ -72,8 +72,8 @@ endif
 BITMAPLIB =
 BITMAPINC =
 ifeq ($(strip $(IO_PGM)),yes)
-  BITMAPLIB = -L/sw2/lib -lnetpbm
-  BITMAPINC = -I/sw2/include
+  BITMAPLIB = -L/opt/local/lib -lnetpbm
+  BITMAPINC = -I/opt/local/include
 endif
 
 # SET NETCDF PATHS
@@ -88,11 +88,11 @@ ifneq ($(strip $(NO_NETCDF)), yes)
 endif
 
 # SET MORE DIRECTORY PATHS
-MAINDIR = $(ROOTDIR)/amatos2d/trunk
+MAINDIR = $(ROOTDIR)/amatos2d
 
 BUILDIR = $(MAINDIR)/compile/$(MACHINE)
-LIBDIR  = $(MAINDIR)/lib/$(MACHINE)
-INCDIR  = $(MAINDIR)/include/$(MACHINE)
+LIBDIR  = $(ROOTDIR)/lib/$(MACHINE)
+INCDIR  = $(ROOTDIR)/include/$(MACHINE)
 DATDIR  = $(MAINDIR)/data
 SRCDIR  = $(MAINDIR)/src
 #SRCDIR = $(ROOTDIR)/amatos2d/branches/FixPeriodicBC/src/
@@ -113,8 +113,8 @@ GRDMOD  = *.$(MODEND)
 # library and include paths                                      #
 #----------------------------------------------------------------#
 LIB_SH     = $(LAPACKLIB) $(EMITLIB)
-LIBS       = -L$(LIBDIR) -lamatos $(NCUGRIDLIB) $(NETCDFLIB) \
-             $(LAPACKLIB) $(BLASLIB) $(BITMAPLIB)
+LIBS       = $(NCUGRIDLIB) $(NETCDFLIB) \
+             $(LAPACKLIB) $(BLASLIB) $(BITMAPLIB) -L$(LIBDIR) -lamatos
 INCPATH    = $(NETCDFINC) -I$(INCDIR) -I.
 INCPATH_CC = $(BITMAPINC)
 
diff --git a/flash2d/compile/Makefiles/Makefile.common b/flash2d/compile/Makefiles/Makefile.common
index c81b7d589445c6bfbadfd015f44ebe264960afb1..49b85db9c8d1580cc068323ecb240e5d1367ccd3 100644
--- a/flash2d/compile/Makefiles/Makefile.common
+++ b/flash2d/compile/Makefiles/Makefile.common
@@ -8,7 +8,6 @@
 # OBJECTS                                                        #
 #----------------------------------------------------------------#
 MAINOBJ = \
-FLASH_metadata.o \
 FLASH_parameters.o \
 MISC_timing.o \
 MISC_system.o \
@@ -100,6 +99,10 @@ ShallowWaterCopy::
 	@cp $(DATDIR)/Triang.SWCosine.dat Triang.dat
 	@cp $(DATDIR)/Parameters.SW.dat Parameters.dat
 
+StackedCopy:
+	@make datasphere
+	@cp $(DATDIR)/Parameters_stacked.dat Parameters.dat
+    
 #----------------------------------------------------------------#
 # THIS CREATES PREDEFINED OPTIONS                                #
 #----------------------------------------------------------------#
@@ -240,6 +243,16 @@ ShallowWater:
 	@cp $(OPTDIR)/SLM_initial.SWCosine.f90 SLM_initial.f90
 	@cp $(OPTDIR)/IO_vtuplot.SW.F90 IO_vtuplot.F90
 
+Stacked:
+	@make maincopy
+	@cp $(OPTDIR)/FLASH_parameters_stacked.f90 FLASH_parameters.f90
+	@cp $(OPTDIR)/ADV_rhs_stacked.f90 ADV_rhs.f90
+	@cp $(OPTDIR)/ADV_semilagrange_stacked.F90 ADV_semilagrange.F90
+	@cp $(OPTDIR)/ADV_wind_stacked.f90 ADV_wind.f90
+	@cp $(OPTDIR)/SLM_advanced_stacked.f90 SLM_advanced.f90
+	@cp $(OPTDIR)/SLM_errorestimate_stacked.f90 SLM_errorestimate.f90
+	@cp $(OPTDIR)/SLM_simple_stacked.f90 SLM_simple.f90
+
 #----------------------------------------------------------------#
 # THIS COMPILES THE MAIN PROGRAM                                 #
 #----------------------------------------------------------------#
diff --git a/flash2d/compile/macosx_gfortran/Makefile b/flash2d/compile/macosx_gfortran/Makefile
index 7b58fd417218f1e963dcf9e936e5b07a145a3fca..a813df455f350119492527ecf8c8943be1d44bab 100644
--- a/flash2d/compile/macosx_gfortran/Makefile
+++ b/flash2d/compile/macosx_gfortran/Makefile
@@ -31,7 +31,7 @@ NO_MPSLM := yes
 
 # SET MAIN DIRECTORY PATH
 # !! This has to be alterd by user !!
-ROOTDIR = $(HOME)/Documents/Development/amatos
+ROOTDIR = $(HOME)/Documents/Teaching/WS2021/Transport-20/TracerTransportSoftware
 
 # SET atlas/blas DIRECTORY PATH
 # !! This has to be alterd by user !!
@@ -49,10 +49,10 @@ CCLIBDIR = -L/usr/lib/
 CCLIB = -lstdc++
 
 # SET MORE DIRECTORY PATHS
-LIBDIR  = $(ROOTDIR)/amatos2d/trunk/lib/$(MACHINE)
-INCDIR  = $(ROOTDIR)/amatos2d/trunk/include/$(MACHINE)
-MODDIR  = $(ROOTDIR)/amatos2d/trunk/include/$(MACHINE)
-MAINDIR = $(ROOTDIR)/flash2d/trunk
+LIBDIR  = $(ROOTDIR)/lib/$(MACHINE)
+INCDIR  = $(ROOTDIR)/include/$(MACHINE)
+MODDIR  = $(ROOTDIR)/include/$(MACHINE)
+MAINDIR = $(ROOTDIR)/flash2d/
 
 SRCDIR  = $(MAINDIR)/src/flash-sphere
 OPTDIR  = $(MAINDIR)/src/options-sphere
@@ -65,8 +65,8 @@ BUILDIR = $(MAINDIR)/compile/$(MACHINE)
 LIBNETCDF = 
 INCNETCDF =
 ifneq ($(strip $(NO_NETCDF)), yes)
-LIBNETCDF = -L$(LIBDIR) -lncugrid -L/sw2/lib -lnetcdff -lnetcdf
-INCNETCDF = -I/sw2/include
+LIBNETCDF = -L$(LIBDIR) -lncugrid -L/opt/local/lib -lnetcdff -lnetcdf
+INCNETCDF = -I/opt/local/include
 endif
 
 # SET VISNET DIRECTORY PATH
@@ -93,19 +93,19 @@ MODEND  = mod
 F90 	= gfortran
 cc 	= gcc
 CC 	= g++
-LOADER  = gfortran
+LOADER  = /usr/bin/gcc
 
 # --------------------- next are for debugging ------------------#
 ifeq ($(strip $(MODE)),debug)
-  FFLAGS  = -fbounds-check -ggdb -fpic -funderscoring # -C
+  FFLAGS  = -fbounds-check -ggdb  #-fpic -funderscoring -C
   CFLAGS  = -ggdb -fpic
-  LDFLAGS = -ggdb
+  LDFLAGS = -v -L/opt/local/lib/libgcc -lgfortran
 endif
 # --------------------- next are for normal compilation ---------#
 ifeq ($(strip $(MODE)),norm)
   FFLAGS  = -fPIC -funderscoring
   CFLAGS  = -fpic
-  LDFLAGS =
+  LDFLAGS = -v
 endif
 # --------------------- next are for optimization ---------------#
 ifeq ($(strip $(MODE)),opt)
diff --git a/flash2d/src/options-sphere/ADV_rhs_stacked.f90 b/flash2d/src/options-sphere/ADV_rhs_stacked.f90
new file mode 100644
index 0000000000000000000000000000000000000000..ea76ba6b98c8c89743049f3c442270cab82f39a1
--- /dev/null
+++ b/flash2d/src/options-sphere/ADV_rhs_stacked.f90
@@ -0,0 +1,105 @@
+!*****************************************************************
+!
+! MODULE NAME:
+!	ADV_rhs
+! FUNCTION:
+!	calculate the (nonhomogeneous) right hand side
+! CONTAINS:
+!-----------------------------------------------------------------
+!
+! NAME:
+!	slm_righthand
+! FUNCTION:
+!	calculate the rhs of the advection equation
+! SYNTAX:
+!	real= slm_righthand(real.arr, real)
+! ON INPUT:
+!	r_coord: coordinates of point		real
+!	r_time:  time coordinate (optional)	real
+! ON OUTPUT:
+!	r_rhs:   right hand side value		real
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! PUBLIC:
+!
+! COMMENTS:
+!	this is the homogeneous case!
+! USES:
+!	MISC_globalparam, MISC_error
+! LIBRARIES:
+!
+! REFERENCES:
+!
+! VERSION(S):
+!	1. original version		j. behrens	2/98
+!	2. compliant to amatos 1.0	j. behrens	12/2000
+!	3. compliant to amatos 1.2	j. behrens	3/2002
+!
+!*****************************************************************
+	MODULE ADV_rhs
+	  USE GRID_api
+	  PRIVATE
+	  PUBLIC :: slm_righthand, slm_verticalrhs
+	  CONTAINS
+!*****************************************************************
+	  FUNCTION slm_righthand(r_coord, i_layer, r_time) RESULT (r_rhs)
+
+!---------- local declarations
+
+	  IMPLICIT NONE
+
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension), INTENT(in) :: r_coord
+	  INTEGER (KIND = GRID_SI), INTENT(in)                         :: i_layer
+	  REAL (KIND = GRID_SR), INTENT(in), OPTIONAL                  :: r_time
+	  REAL (KIND = GRID_SR)                                        :: r_rhs
+	  REAL (KIND = GRID_SR)                                        :: r_tim
+
+!---------- set time
+
+	  IF(present(r_time)) THEN
+	    r_tim= r_time
+	  ELSE
+	    r_tim= 0.0
+	  END IF
+
+!---------- calculate the advection at (x,y) (velocity increasing)
+
+	  r_rhs= 0.0
+	
+	  RETURN
+	  END FUNCTION slm_righthand
+
+!*****************************************************************
+	  FUNCTION slm_verticalrhs(r_coord, i_layer, r_time) RESULT (r_rhs)
+
+!---------- local declarations
+
+	  IMPLICIT NONE
+
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension), INTENT(in) :: r_coord
+	  INTEGER (KIND = GRID_SI), INTENT(in)                         :: i_layer
+	  REAL (KIND = GRID_SR), INTENT(in), OPTIONAL                  :: r_time
+	  REAL (KIND = GRID_SR)                                        :: r_rhs
+	  REAL (KIND = GRID_SR)                                        :: r_tim
+
+!---------- set time
+
+	  IF(present(r_time)) THEN
+	    r_tim= r_time
+	  ELSE
+	    r_tim= 0.0
+	  END IF
+
+!---------- calculate the advection at (x,y) (velocity increasing)
+
+	  r_rhs= 0.0
+	
+	  RETURN
+	  END FUNCTION slm_verticalrhs
+
+!*****************************************************************
+	END MODULE ADV_rhs
diff --git a/flash2d/src/options-sphere/ADV_semilagrange_stacked.F90 b/flash2d/src/options-sphere/ADV_semilagrange_stacked.F90
new file mode 100644
index 0000000000000000000000000000000000000000..ea1c1ed5307be0288efe1f040f5289fe3b22029e
--- /dev/null
+++ b/flash2d/src/options-sphere/ADV_semilagrange_stacked.F90
@@ -0,0 +1,874 @@
+!*****************************************************************
+!
+! MODULE NAME:
+!    ADV_semilagrange
+! FUNCTION:
+!    perform semi-Lagrangian advection
+! CONTAINS:
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_adapt
+! FUNCTION:
+!    adapt the grid according to an error estimate
+! SYNTAX:
+!    CALL slm_adapt(grid, param, logical)
+! ON INPUT:
+!    p_ghand:   handle for the grid        TYPE (grid_handle)
+!    p_param:   global parameter structure    TYPE (global_param)
+! ON OUTPUT:
+!    l_changed: flag for changed grid    LOGICAL
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_initialize
+! FUNCTION:
+!    initialize the advection problem
+! SYNTAX:
+!    CALL slm_initialize(grid, param)
+! ON INPUT:
+!    p_param: parameter data structure    TYPE (global_param)
+! ON OUTPUT:
+!    p_ghand: grid handling data structure    TYPE (grid_handle)
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_finish
+! FUNCTION:
+!    terminate slm (free dynamically alloc. memory, ...)
+! SYNTAX:
+!    CALL slm_finish(grid, param)
+! ON INPUT:
+!    p_ghand: grid handling data structure    TYPE (grid_handle)
+!    p_param: parameter data structure    TYPE (global_param)
+! ON OUTPUT:
+!
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_timestepping
+! FUNCTION:
+!    perform the timestepping in the slm
+! SYNTAX:
+!    CALL slm_timestepping(grid, param, cmd)
+! ON INPUT:
+!    p_ghand: grid handling data structure    TYPE (grid_handle)
+!    p_param: parameter data structure    TYPE (global_param)
+!    p_cmdln: command line argument struct.    TYPE (cmdline)
+! ON OUTPUT:
+!    p_ghand: grid handling data structure    TYPE (grid_handle)
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! PUBLIC:
+!    slm_displace, slm_update, slm_upstream
+!    slm_initialize, slm_finish, slm_timestepping
+! COMMENTS:
+!
+! USES:
+!    MISC_globalparam, MISC_error, FEM_handle
+!    FEM_errorestimate, FEM_param
+! LIBRARIES:
+!
+! REFERENCES:
+!
+! VERSION(S):
+!    1. original version            j. behrens    10/96
+!    2. several improvements/fixes  j. behrens    11/96-1/97
+!    3. nodal values time depend.   j. behrens    1/97
+!    4. stop_watch removed, plot    j. behrens    1/97
+!       (position) changed, inner
+!       iteration counter added
+!    5. slm_adapt changed           j. behrens    2/97
+!    6. slm_adapt changed to hide
+!       grid data structures        j. behrens    7/97
+!    7. control data structure      j. behrens    12/97
+!    8. non-homog. rhs added        j. behrens    2/98
+!    9. compliant to amatos 1.0     j. behrens    12/2000
+!    10. compliant to amatos 1.2    j. behrens    3/2002
+!    11. compliant to amatos 2.0    j. behrens    7/2003
+!    12. added visnetplot           f. klaschka   12/2003
+!
+!*****************************************************************
+    MODULE ADV_semilagrange
+      USE FLASH_parameters
+      USE MISC_timing
+      USE IO_vtuplot
+#ifndef NO_NETCDF
+      USE IO_netcdfplot
+#endif
+      USE IO_utils
+      USE GRID_api
+      USE SLM_errorestimate
+      USE SLM_initial
+      USE SLM_simple
+      USE ADV_wind
+      USE ADV_rhs
+      PRIVATE
+      PUBLIC  :: slm_initialize, slm_finish, slm_timestepping
+
+!      USE SLM_advanced
+
+      CONTAINS
+!*****************************************************************
+      SUBROUTINE slm_adapt(p_ghand, p_param, l_changed, l_water)
+
+
+!---------- local declarations
+
+      IMPLICIT NONE
+      TYPE (grid_handle), INTENT(inout)      :: p_ghand
+      TYPE (control_struct), INTENT(in)      :: p_param
+      LOGICAL, INTENT(out)                   :: l_changed
+      LOGICAL, OPTIONAL, INTENT(in)          :: l_water
+      LOGICAL                                :: l_switch
+      REAL (KIND = GRID_SR)                                   :: r_errmx, &
+        r_refcrit, r_crscrit, r_fac
+      INTEGER                                :: i_size, &
+        i_manyc, i_manyr, i_alct, i_cnt
+      REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE        :: r_aux1
+      INTEGER, DIMENSION(:), ALLOCATABLE     :: i_aux1, i_aux2, i_aux3
+      LOGICAL                                :: l_ref, l_crs
+
+!---------- initialize refinement flag
+
+      l_changed= .FALSE.
+
+!---------- handle watermark switch
+
+      wat_present: IF(present(l_water)) THEN
+        l_switch= l_water
+      ELSE wat_present
+        l_switch= .TRUE.
+      END IF wat_present
+
+!---------- allocate work arrays
+
+      i_size= p_ghand%i_enumfine
+      allocate(r_aux1(i_size), i_aux1(i_size), i_aux2(i_size), &
+                   i_aux3(i_size), stat=i_alct)
+      not_alloc: IF(i_alct /= 0) THEN
+        CALL grid_error(35)
+      END IF not_alloc
+
+!---------- estimate the local error
+
+      CALL slm_errorest(p_ghand, i_size, r_aux1)
+
+!---------- set coarsening/refinement criterion
+
+      r_errmx= maxval(r_aux1(1:i_size))
+      r_crscrit= r_errmx* p_param%num%r_crstolerance
+      r_refcrit= r_errmx* p_param%num%r_reftolerance
+
+!---------- get level information and set up flags for refinement/coarsening
+
+      CALL grid_getinfo(p_ghand, l_finelevel= .TRUE., i_elementlevel= i_aux1, &
+                        i_elementstatus= i_aux3)
+      DO i_cnt=1,i_size
+        i_aux2(i_cnt)= 0
+        IF((i_aux1(i_cnt) > p_param%num%i_crslevel) .AND. &
+           (r_aux1(i_cnt) < r_crscrit)) i_aux2(i_cnt)= GRID_pleasecoarse
+        IF((i_aux1(i_cnt) < p_param%num%i_reflevel) .AND. &
+           (r_aux1(i_cnt) > r_refcrit)) i_aux2(i_cnt)= GRID_pleaserefine
+      END DO
+
+!---------- determine if there is enough to be done (this can be
+!           switched off by l_water=.FALSE.)
+
+      IF(l_switch) THEN
+        i_manyr= count(i_aux2 == GRID_pleaserefine)
+        r_fac= real(i_manyr,GRID_SR)/ real(i_size,GRID_SR)
+        enough_ref: IF(r_fac > p_param%num%r_refwatermark) THEN
+          l_ref= .TRUE.
+        ELSE
+          l_ref= .FALSE.
+        END IF enough_ref
+
+        i_manyc= count(i_aux2 == GRID_pleasecoarse)
+        r_fac= real(i_manyc,GRID_SR)/ real(i_size,GRID_SR)
+        enough_crs: IF(r_fac > p_param%num%r_crswatermark) THEN
+          l_crs= .TRUE.
+        ELSE
+          l_crs= .FALSE.
+        END IF enough_crs
+      ELSE
+        l_ref= .TRUE.
+        l_crs= .TRUE.
+      END IF
+
+!---------- update grid flags
+
+      update: IF(l_ref .OR. l_crs) THEN
+        IF(l_ref) i_aux3= merge(i_aux2, i_aux3, i_aux2==GRID_pleaserefine)
+        IF(l_crs) i_aux3= merge(i_aux2, i_aux3, i_aux2==GRID_pleasecoarse)
+        CALL grid_putinfo(p_ghand, l_finelevel= .TRUE., i_elementstatus= i_aux3)
+      END IF update
+
+!---------- deallocate work arrays
+
+      deallocate(r_aux1, i_aux1, i_aux2, i_aux3)
+
+!---------- adapt the grid
+
+      CALL grid_adapt(p_ghand, l_changed)
+
+      RETURN
+      END SUBROUTINE slm_adapt
+
+!*****************************************************************
+      SUBROUTINE slm_diagnostics(p_ghand, p_param, p_tinfo, c_action)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+      TYPE (grid_handle), INTENT(in)           :: p_ghand
+      TYPE (control_struct), INTENT(inout)     :: p_param
+      TYPE (rt_info), INTENT(in)               :: p_tinfo
+      CHARACTER (len=4), INTENT(in), OPTIONAL  :: c_action
+      INTEGER, SAVE                            :: i_iodiag
+      CHARACTER (len=32)                       :: c_file
+      CHARACTER (len=28)                       :: c_tmp
+      REAL (KIND = GRID_SR), PARAMETER                          :: r_1o3= (1./3.)
+      INTEGER                                  :: i_fst, i_tmp, &
+        i_size, i_alct, i_1, i_2, i_3, i_4, i_5, i_6
+      REAL (KIND = GRID_SR), SAVE                               :: r_rfm0, r_rsm0
+      REAL (KIND = GRID_SR)                                     :: r_dispn, r_rfm, r_rsm, &
+        r_ts, r_calci, r_calcs, r_mxnrm, r_l2nrm, r_max, r_min, r_diffn, &
+        r_medln
+      REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE          :: r_aux1, r_aux2, &
+        r_aux3, r_aux4
+      REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE        :: r_auxx
+      INTEGER, DIMENSION(1)                    :: i_valind
+
+!---------- action init
+
+      present_act: IF(present(c_action)) THEN
+        action_type: IF(c_action == 'init') THEN
+
+!---------- open file for diagnostic output
+
+          i_iodiag= 9
+          i_tmp   = p_param%num%i_experiment
+          write(c_tmp,*) trim(GRID_parameters%program_name), '_diag.'
+          write(c_file,1010) trim(c_tmp), i_tmp
+          c_file= adjustl(c_file)
+          open(i_iodiag, file= c_file, action= 'write', form= 'formatted', &
+               iostat= i_fst)
+          not_opened: IF(i_fst /= 0) THEN
+            CALL grid_error(36)
+          END IF not_opened
+          IF(GRID_parameters%iolog > 0) &
+            write(GRID_parameters%iolog,*) 'INFO: Filename: ', c_file, ' opened on unit: ', i_iodiag
+
+!---------- allocate workspace
+
+          i_size= p_ghand%i_nnumber
+          allocate(r_aux1(i_size), r_aux2(i_size), r_aux3(i_size), &
+                   r_aux4(i_size), r_auxx(1,i_size), stat=i_alct)
+          not_alloc: IF(i_alct /= 0) THEN
+            CALL grid_error(37)
+          END IF not_alloc 
+          r_aux1= 0.0; r_aux2= 0.0; r_aux3= 0.0; r_aux4= 0.0
+
+!---------- get minimum edge length
+
+          CALL grid_edgelength(p_ghand, r_min=r_medln)
+
+!---------- calculate reference values, ... extract actual calculated concentration
+
+          i_valind= (/ GRID_tracer /)
+          CALL grid_getinfo(p_ghand, i_arraypoint=i_valind, &
+                            r_nodevalues= r_auxx)
+          r_aux1(:)= r_auxx(1,:)
+          DEALLOCATE(r_auxx)
+
+!---------- calculate area pieces for each node
+
+          CALL grid_nodearea(p_ghand, i_size, r_aux2)
+
+!---------- calculate analytical solution
+
+          r_ts= p_param%num%r_deltatime* float(p_tinfo%i_step)
+          CALL slm_analyticsolution(p_ghand, r_ts, i_size, r_aux3)
+
+!---------- now the integral of the concentration (mass) is
+
+          r_calci= dot_product(r_aux1, r_aux2)
+          r_rfm0 = r_calci
+
+!---------- the integral of the squared concentration ("entropy"(?)) is
+
+          r_aux4 = r_aux1* r_aux1
+          r_calcs= dot_product(r_aux4, r_aux2)
+          r_rsm0 = r_calcs
+
+!---------- the maximum-norm of the error is
+
+          r_aux4 = abs(r_aux1- r_aux3)
+          r_mxnrm= maxval(r_aux4)
+
+!---------- the l2-norm of the error is
+
+          r_aux4 = r_aux4* r_aux4
+          r_l2nrm= dot_product(r_aux4, r_aux2)
+
+!---------- maximum and minimum
+
+          r_max  = maxval(r_aux1)
+          r_min  = minval(r_aux1)
+
+!---------- diffusion and dispersion (not yet implemented)
+
+          r_diffn= 0.0
+          r_dispn= 0.0
+
+!---------- print it
+
+          r_rfm= r_calci/r_rfm0
+          r_rsm= r_calcs/r_rsm0
+          write(i_iodiag,1100) GRID_parameters%program_name, GRID_parameters%version, &
+                               GRID_parameters%subversion, GRID_parameters%patchversion
+          i_1= p_tinfo%i_step
+          i_2= p_ghand%i_enumber
+          i_3= p_ghand%i_enumfine
+          i_4= p_ghand%i_gnumber
+          i_5= p_ghand%i_gnumfine
+          i_6= p_ghand%i_nnumber
+          write(i_iodiag,1000) i_1, i_2, i_3, i_4, i_5, i_6, r_min, r_max, &
+                               r_rfm, r_rsm, r_mxnrm, r_l2nrm, r_diffn, &
+                   r_dispn, r_medln
+
+!---------- deallocate workspace
+
+          deallocate(r_aux1, r_aux2, r_aux3, r_aux4)
+
+!---------- initialization done
+
+          RETURN
+
+!---------- action quit
+
+        ELSE IF(c_action == 'quit') THEN action_type
+
+!---------- close diagnostic output file
+
+          close(i_iodiag)
+           IF(GRID_parameters%iolog > 0) &
+            write(GRID_parameters%iolog,*) 'INFO: Closed file on unit: ', i_iodiag
+
+!---------- action quit done
+
+          RETURN
+        END IF action_type
+      END IF present_act
+
+!---------- action diag (default): allocate workspace
+
+      i_size= p_ghand%i_nnumber
+      allocate(r_aux1(i_size), r_aux2(i_size), r_aux3(i_size), &
+               r_aux4(i_size), r_auxx(1,i_size), stat=i_alct)
+      not_allc: IF(i_alct /= 0) THEN
+        CALL grid_error(37)
+      END IF not_allc 
+      r_aux1= 0.0; r_aux2= 0.0; r_aux3= 0.0; r_aux4= 0.0
+
+!---------- get minimum edge length
+
+      CALL grid_edgelength(p_ghand, r_min=r_medln)
+
+!---------- calculate reference values, ... extract actual calculated concentration
+
+      i_valind= (/ GRID_tracer /)
+      CALL grid_getinfo(p_ghand, i_arraypoint=i_valind, &
+                 r_nodevalues= r_auxx)
+      r_aux1(:)= r_auxx(1,:)
+      DEALLOCATE(r_auxx)
+
+!---------- calculate area pieces for each node
+
+      CALL grid_nodearea(p_ghand, i_size, r_aux2)
+
+!---------- calculate analytical solution
+
+      r_ts= p_param%num%r_deltatime* float(p_tinfo%i_step)
+      CALL slm_analyticsolution(p_ghand, r_ts, i_size, r_aux3)
+
+!---------- now the integral of the concentration (mass) is
+
+      r_calci= dot_product(r_aux1, r_aux2)
+
+!---------- the integral of the squared concentration ("entropy"(?)) is
+
+      r_aux4 = r_aux1* r_aux1
+      r_calcs= dot_product(r_aux4, r_aux2)
+
+!---------- the maximum-norm of the error is
+
+      r_aux4 = abs(r_aux1- r_aux3)
+      r_mxnrm= maxval(r_aux4)
+
+!---------- the l2-norm of the error is
+
+      r_aux4 = r_aux4* r_aux4
+      r_l2nrm= dot_product(r_aux4, r_aux2)
+
+!---------- maximum and minimum
+
+      r_max  = maxval(r_aux1)
+      r_min  = minval(r_aux1)
+
+!---------- diffusion and dispersion (not yet implemented)
+
+      r_diffn= 0.0
+      r_dispn= 0.0
+
+!---------- print it
+
+      r_rfm= r_calci/r_rfm0
+      r_rsm= r_calcs/r_rsm0
+      i_1= p_tinfo%i_step
+      i_2= p_ghand%i_enumber
+      i_3= p_ghand%i_enumfine
+      i_4= p_ghand%i_gnumber
+      i_5= p_ghand%i_gnumfine
+      i_6= p_ghand%i_nnumber
+      write(i_iodiag,1000) i_1, i_2, i_3, i_4, i_5, i_6, r_min, r_max, &
+                           r_rfm, r_rsm, r_mxnrm, r_l2nrm, r_diffn, &
+                           r_dispn, r_medln
+
+!---------- deallocate workspace
+
+      deallocate(r_aux1, r_aux2, r_aux3, r_aux4)
+
+      RETURN
+ 1000      FORMAT(1x, i10, 1x, i10, 1x, i10, 1x, i10, 1x, i10, 1x, i10, &
+             1x, e15.8, 1x, e15.8, 1x, e15.8, 1x, e15.8,&
+             1x, e15.8, 1x, e15.8, 1x, e15.8, 1x, e15.8,&
+             1x, e15.8)
+ 1010      FORMAT(a28,i4.4)
+ 1100      FORMAT(1x,'*******************************************', &
+                '*******************************************', &
+                '*******************************************', &
+                '*******************************************', &
+                '*************************************',/ &
+             1x,'***** PROGRAM: ',a15,174x,'*****',/ &
+             1x,'***** VERSION: ',i2.2,'.',i2.2,'.',i2.2,181x,'*****',/ &
+             1x,'***** Diagnostic output ',180x,'*****',/ &
+             1x,'*******************************************', &
+                '*******************************************', &
+                '*******************************************', &
+                '*******************************************', &
+                '*************************************',/ &
+             1x,'* timestep ','  elements ','  fine el. ','     edges ', &
+                '  fine ed. ','     nodes ','        minimum ', &
+                '        maximum ','            RFM ','            RSM ', &
+                    '       max-norm ','        l2-norm ','      diffusion ', &
+                '     dispersion ',' min.edge len.*',/ &
+             1x,'*******************************************', &
+                '*******************************************', &
+                '*******************************************', &
+                '******************************************', &
+                '**************************************')
+      END SUBROUTINE slm_diagnostics
+
+!*****************************************************************
+      SUBROUTINE slm_initialize(p_ghand, p_param)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps), INTENT(out) :: p_ghand
+      TYPE (control_struct), INTENT(inout)          :: p_param
+
+      INTEGER                                     :: i_steps
+      CHARACTER (len=32)                          :: c_file
+      CHARACTER (len=28)                          :: c_tmp
+      INTEGER                                     :: i_tmp, i_cnt
+      LOGICAL                                     :: l_refined
+      INTEGER                                     :: i_vertnum, i_alct
+      REAL (KIND = GRID_SR), DIMENSION(:,:), POINTER               :: r_vertinit
+
+!---------- decide whether a new experiment is startet or an old one is continued
+
+      new_experiment: IF(p_param%num%i_experiment <= 0) THEN
+
+!---------- reset timesteps (start with 1 in any case)
+
+        time_one: IF(p_param%num%i_frsttimestep /= 1) THEN
+          IF(GRID_parameters%iolog > 0) &
+            write(GRID_parameters%iolog,*) 'WARNING      : Timestep counters reset due to new experiment'
+          i_steps= p_param%num%i_lasttimestep- p_param%num%i_frsttimestep
+          p_param%num%i_frsttimestep= 1
+          p_param%num%i_lasttimestep= p_param%num%i_frsttimestep+ i_steps
+        END IF time_one
+
+!---------- initialize variables for stacked layers
+
+        i_stcnumlayers = p_param%tst%tst_int(1,1)
+        i_stctracer = grid_registerfemvar(1,i_length=i_stcnumlayers)
+        allocate(r_stclayerpressure(i_stcnumlayers), stat=i_alct)
+        not_allc: IF(i_alct /= 0) THEN
+            CALL grid_error(c_error='[slm_initialize]: Could not allocate layers pressure array')
+        END IF not_allc 
+        
+
+!---------- initialize grid parameters
+
+        CALL grid_setparameter(p_ghand, i_coarselevel= p_param%num%i_crslevel, &
+                               i_finelevel= p_param%num%i_reflevel)
+
+!---------- define domain, first read data from file (compiled here)
+
+        CALL grid_readdomain(i_vertnum, r_vertinit, c_readfile=p_param%io%c_domainfile)
+        CALL grid_definegeometry(i_vertnum, r_vertexarr= r_vertinit)
+
+!---------- create initial triangulation
+
+        CALL grid_createinitial(p_ghand, c_filename=p_param%io%c_triangfile)
+
+!---------- initialize grid and adapt at steep gradients
+
+        i_cnt= 0
+        l_refined= .TRUE.
+        refine_loop: DO WHILE (l_refined)
+          CALL slm_initialvalues(p_ghand(i_timeplus))
+          CALL slm_adapt(p_ghand(i_timeplus), p_param, l_refined, &
+                         l_water=.FALSE.)
+        END DO refine_loop
+
+!---------- duplicate grid (old time)
+
+        CALL grid_timeduplicate(p_ghand(i_timeplus), p_ghand(i_time))
+
+!---------- initialize wind field calculation
+
+        CALL slm_windinit(p_param)
+
+!---------- if an old experiment is to be continued from stored data:
+
+      ELSE new_experiment
+
+!---------- create grid from saveset, first compile filename
+
+        i_tmp= p_param%num%i_experiment- 1
+        write(c_tmp,*) trim(GRID_parameters%program_name), '_save.'
+        write(c_file,1010) trim(c_tmp), i_tmp
+        c_file= adjustl(c_file)
+
+        CALL grid_readinitial(p_ghand, c_file)
+
+!---------- initialize wind field calculation
+
+        CALL slm_windinit(p_param)
+
+      END IF new_experiment
+
+      RETURN
+ 1010      FORMAT(a28,i4.4)
+      END SUBROUTINE slm_initialize
+
+!*****************************************************************
+      SUBROUTINE slm_finish(p_ghand, p_param)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps), INTENT(in) :: p_ghand
+      TYPE (control_struct), INTENT(in)                          :: p_param
+      CHARACTER (len=32)                                       :: c_file
+      CHARACTER (len=28)                                       :: c_tmp
+      INTEGER                                                  :: i_tmp
+
+!---------- open and write saveset, if required
+
+      save_req: IF(p_param%io%i_savelast /= 0) THEN
+
+        i_tmp= p_param%num%i_experiment
+        write(c_tmp,*) trim(GRID_parameters%program_name), '_save.'
+        write(c_file,1010) trim(c_tmp), i_tmp
+        c_file= adjustl(c_file)
+        CALL grid_writesaveset(c_file, p_ghand)
+
+!---------- write parameter file for next experiment
+
+        CALL io_putinputfile(p_param)
+      END IF save_req
+
+!---------- gracefully terminate wind field calculations
+
+      CALL slm_windquit
+
+      RETURN
+ 1010      FORMAT(a28,i4.4)
+      END SUBROUTINE slm_finish
+
+!*****************************************************************
+      SUBROUTINE slm_timestepping(p_ghand, p_param)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      INTEGER (KIND = GRID_SI), PARAMETER                 :: i_innermax=15
+      TYPE (grid_handle), DIMENSION(GRID_timesteps), &
+                          INTENT(inout)                   :: p_ghand
+      TYPE (control_struct), INTENT(inout)                :: p_param
+      INTEGER (KIND = GRID_SI)                            :: i_timecount
+      TYPE (sw_info)                                      :: p_time, p_timeaux
+      LOGICAL                                             :: l_refined
+      REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE    :: r_tracer
+      REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE  :: r_coord, r_aux
+      REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE  :: r_3dtracer
+      CHARACTER (len=32)                                  :: c_file, c_matfile
+      CHARACTER (len=28)                                  :: c_tmp
+      INTEGER (KIND = GRID_SI)                            :: i_tmp, &
+        i_size, i_alct, i_tst, i_fst, i_lay, i_start
+      INTEGER (KIND = GRID_SI)                            :: i_iomatl=21
+      REAL (KIND = GRID_SR)                               :: r_modtime
+      INTEGER (KIND = GRID_SI)                            :: i_newlen, i_ndep
+      INTEGER (KIND = GRID_SI)                            :: i_layerid
+      INTEGER (KIND = GRID_SI), DIMENSION(i_stcnumlayers) :: i_valind
+
+!---------- initialize constant
+
+      i_ndep = 1_GRID_SI
+
+!---------- initialize timestep info structure
+
+      p_timestepinfo%i_step       = 0
+      p_timestepinfo%i_adapit     = 0
+      p_timestepinfo%l_ploted     = .FALSE.
+      p_timestepinfo%l_saved      = .FALSE.
+      p_timestepinfo%r_modeltime  = 0.0
+
+!---------- initialize timing structure
+
+      p_time%p_tim%r_tim   = 0.0
+      p_time%p_tim%r_lap   = 0.0
+      p_time%p_tim%c_tim   = '                '
+      p_timeaux%p_tim%r_tim= 0.0
+      p_timeaux%p_tim%r_lap= 0.0
+      p_timeaux%p_tim%c_tim= '                '
+
+!---------- initialize stop watches
+
+      CALL stop_watch_init(1,(/'total time      '/),p_timeaux)
+      CALL stop_watch_init(8,(/'plotting        ', 'grid duplication', &
+                               'trajectory calc.', 'right hand side ', &
+                               'grid value updt.', 'grid adaption   ', &
+                               'diagnostics     ', 'whole timestep  '/), p_time)
+                               
+!---------- if diagnostics are demanded, initialize diagnostical output
+
+      IF(p_param%io%l_diagnostics) THEN
+        p_timestepinfo%i_step= 0
+        CALL slm_diagnostics(p_grid(i_timeplus), p_param, p_timestepinfo, c_action='init')
+      END IF
+
+!---------- plot initial data
+
+      i_timecount= 0
+#ifndef NO_NETCDF
+      IF(p_param%io%l_netcdf) THEN
+        CALL plot_netcdf(p_ghand(i_timeplus), i_time=i_timecount)
+      END IF
+#endif
+      IF(p_param%io%l_vtu) THEN
+        CALL generate_vtu(p_ghand(i_timeplus), i_time=i_timecount)
+      END IF
+!---------- put out initial information
+
+      CALL io_putruntimeinfo(p_ghand(i_timeplus), p_timestepinfo, p_time)
+
+!---------- timestep loop
+
+      CALL stop_watch('start',1,p_timeaux)
+      CALL stop_watch('start',8,p_time)
+      i_timecount = 0_GRID_SI
+      p_timestepinfo%r_modeltime = p_param%num%r_starttime
+      time_loop: DO WHILE (p_timestepinfo%r_modeltime < p_param%num%r_finaltime - p_param%num%r_deltatime)
+        i_timecount                = i_timecount+ 1_GRID_SI
+        p_timestepinfo%i_step      = i_timecount
+        p_timestepinfo%r_modeltime = p_timestepinfo%r_modeltime + p_param%num%r_deltatime
+        p_timestepinfo%i_adapit    = 0_GRID_SI
+
+!---------- duplicate old grid, use it as first guess for new grid
+
+        CALL stop_watch('start',2,p_time)
+        CALL grid_timeduplicate(p_ghand(i_time), p_ghand(i_timeplus))
+        CALL stop_watch('stop ',2,p_time)
+
+!---------- adaptive (inner) loop
+
+        l_refined= .TRUE.
+        adap_loop: DO WHILE(l_refined .AND. p_timestepinfo%i_adapit < i_innermax)
+          p_timestepinfo%i_adapit= p_timestepinfo%i_adapit+ 1
+
+!---------- allocate and extract working arrays
+!---------- use amatos 1.2 functionality to calculate only new nodes
+
+          i_size= p_ghand(i_timeplus)%i_nnumber
+          allocate(r_aux(GRID_dimension,i_size), stat=i_alct)
+          not_alloc: IF(i_alct /= 0) THEN
+            CALL grid_error(38)
+          END IF not_alloc
+
+!-SLM--------- do the following SLM calculations in arrays (grid-point-wise)
+
+          CALL grid_getinfo(p_ghand(i_timeplus), r_nodecoordinates=r_aux, &
+                            i_newsdepth= 1, i_nlength= i_newlen)
+          allocate(r_tracer(i_newlen), r_coord(GRID_dimension,i_newlen), stat=i_alct)
+          not_alloc0: IF(i_alct /= 0) THEN
+            CALL grid_error(38)
+          END IF not_alloc0
+          r_coord(:,1:i_newlen)= r_aux(:,1:i_newlen)
+          deallocate(r_aux)
+
+!-SLM--------- allocate 3d tracer field
+
+          allocate(r_3dtracer(i_stcnumlayers,i_newlen), stat=i_alct)
+          not_alloc1: IF(i_alct /= 0) THEN
+            CALL grid_error(38)
+          END IF not_alloc1
+
+!-SLM--------- loop over stacked layers
+
+          layer_loop: DO i_lay=1,i_stcnumlayers
+
+!-SLM--------- call the SLM step
+
+            r_modtime= p_timestepinfo%r_modeltime- p_param%num%r_deltatime
+            CALL slm_step(p_ghand, p_param, p_time, r_modtime, i_newlen, &
+                          r_coord, r_tracer, i_ndep, i_lay)
+
+!-SLM--------- store layer data in 3D array
+
+            r_3dtracer(i_lay,:)= r_tracer(:)
+
+          END DO layer_loop
+
+!-SLM--------- call vertical advection step
+
+          CALL slm_verticalstep(p_ghand, p_param, p_time, r_modtime, i_newlen, &
+                                r_coord, r_3dtracer, i_ndep)
+
+!-SLM--------- update grid data structure and deallocate work arrays
+!-SLM--------- change back from (grid-point)arrays to grid data structure
+
+          i_valind= (/ ((i_stctracer-1+i_lay), i_lay=1,i_stcnumlayers) /)
+          CALL grid_putinfo(p_ghand(i_timeplus), i_arraypoint= i_valind, &
+                            i_newsdepth= 1, r_nodevalues= r_3dtracer)
+          deallocate(r_coord, r_tracer, r_3dtracer)
+
+!-SLM--------- adapt the grid corresponding to an error estimate
+
+          CALL stop_watch('start',6,p_time)
+          CALL slm_adapt(p_ghand(i_timeplus), p_param, l_refined)
+          CALL stop_watch('stop ',6,p_time)
+
+        END DO adap_loop
+
+!---------- diagnostics, if requested
+
+        IF(p_param%io%l_diagnostics) THEN
+          CALL stop_watch('start',7,p_time)
+          CALL slm_diagnostics(p_grid(i_timeplus), p_param, p_timestepinfo, c_action='diag')
+          CALL stop_watch('stop ',7,p_time)
+        END IF
+
+!---------- plot data (every [i_plotoffset]th timestep)
+
+        CALL stop_watch('start',1,p_time)
+        plot_step: IF(mod(i_timecount, p_param%io%i_plotoffset) == 0) THEN
+#ifndef NO_NETCDF
+          IF(p_param%io%l_netcdf) THEN
+            CALL plot_netcdf(p_ghand(i_timeplus), i_time=i_timecount)
+            p_timestepinfo%l_ploted= .TRUE.
+          END IF
+#endif
+          IF(p_param%io%l_vtu) THEN
+            CALL generate_vtu(p_ghand(i_timeplus), i_time=i_timecount)
+            p_timestepinfo%l_ploted= .TRUE.
+          END IF
+        END IF plot_step
+        CALL stop_watch('stop ',1,p_time)
+
+!---------- put a saveset to disc every ... timesteps
+
+        save_step: IF((mod(i_timecount, p_param%io%i_saveoffset) == 0) .AND. &
+                      (i_timecount > 1)) THEN
+          i_tmp= p_param%num%i_experiment
+           write(c_tmp,*) trim(GRID_parameters%program_name), '_save.'
+          write(c_file,1010) trim(c_tmp), i_tmp
+          c_file= adjustl(c_file)
+          CALL grid_writesaveset(c_file,p_ghand)
+          p_timestepinfo%l_saved= .TRUE.
+        END IF save_step
+
+!---------- runtime information output
+
+        CALL stop_watch('stop ',8,p_time)
+        CALL io_putruntimeinfo(p_ghand(i_timeplus), p_timestepinfo, p_time)
+        CALL stop_watch_init(8,(/'plotting        ', 'grid duplication', &
+                                 'trajectory calc.', 'right hand side ', &
+                                 'grid value updt.', 'grid adaption   ', &
+                                 'diagnostics     ', 'whole timestep  '/), p_time)
+        CALL stop_watch('start',8,p_time)
+
+!---------- remove obsolecent grid items
+
+        CALL grid_sweep
+
+!---------- toggle time handles for next step if gfx-proces has not exited
+
+        CALL grid_timetoggle
+
+      END DO time_loop
+      CALL stop_watch('stop ',1,p_timeaux)
+
+!---------- print total time
+
+       write(GRID_parameters%ioout,1005)
+      write(GRID_parameters%ioout,1003) p_timeaux%p_tim(1)%r_tim
+      write(GRID_parameters%ioout,1004)
+      IF(GRID_parameters%iolog > 0) THEN
+        write(GRID_parameters%iolog,1003) p_timeaux%p_tim(1)%r_tim
+      END IF
+
+!---------- terminate diagnostics
+
+      IF(p_param%io%l_diagnostics) THEN
+        CALL slm_diagnostics(p_grid(i_timeplus), p_param, p_timestepinfo, c_action='quit')
+      END IF
+
+      RETURN
+ 1000      FORMAT(1x,'***** ***** ***** ***** ***** ***** ***** ***** ***** *****',/ &
+             1x,'*****            Runtime Information Output           *****',/ &
+             1x,'***** ----- ----- ----- ----- ----- ----- ----- ----- *****')
+ 1003      FORMAT(1x,'***** Total time for timesteps ',10x,e12.4,' *****')
+ 1004      FORMAT(1x,'***** ***** ***** ***** ***** ***** ***** ***** ***** *****',/)
+ 1005      FORMAT(1x,'***** ***** ***** ***** ***** ***** ***** ***** ***** *****',/ &
+             1x,'*****             Final Information Output            *****',/ &
+             1x,'***** ----- ----- ----- ----- ----- ----- ----- ----- *****')
+ 1010      FORMAT(a28,i4.4)
+      END SUBROUTINE slm_timestepping
+
+    END MODULE ADV_semilagrange
diff --git a/flash2d/src/options-sphere/ADV_wind_stacked.f90 b/flash2d/src/options-sphere/ADV_wind_stacked.f90
new file mode 100644
index 0000000000000000000000000000000000000000..b1267a9ce7b744a5a1b7d6b86211530d9bc3bef3
--- /dev/null
+++ b/flash2d/src/options-sphere/ADV_wind_stacked.f90
@@ -0,0 +1,864 @@
+!*****************************************************************
+!
+! MODULE NAME:
+!    ADV_wind
+! FUNCTION:
+!    calculate the windfield for the advection problem
+! CONTAINS:
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_windfield
+! FUNCTION:
+!    calculate the advecting force for simple advection
+! SYNTAX:
+!    real.arr= slm_windfield(real.arr, real)
+! ON INPUT:
+!    r_coord: coordinates of point        real
+!    r_time:  time coordinate (optional)    real
+! ON OUTPUT:
+!    r_field: windfield            real
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! PUBLIC:
+!
+! COMMENTS:
+!
+! USES:
+!    MISC_globalparam, MISC_error
+! LIBRARIES:
+!
+! REFERENCES:
+!
+! VERSION(S):
+!    1. original version        j. behrens    12/97
+!    2. bug fix concerning interp.    j. behrens    2/98
+!    3. compliant to amatos 1.0    j. behrens    12/2000
+!    4. compliant to amatos 1.2    j. behrens    3/2002
+!    5. new version for course tracer transport    j. behrens 01/2012
+!
+!*****************************************************************
+    MODULE ADV_wind
+      USE GRID_api
+      USE FLASH_parameters
+      PRIVATE
+      INTEGER, PARAMETER        :: i_ioerr=0
+      REAL (KIND = GRID_SR)     :: r_intervallen, &
+                                   r_scalfacx, r_scalfacy, r_scalfacz, &
+                                   r_readlast, r_scalinvx, r_scalinvy, r_scalinvz
+!       REAL (KIND = GRID_SR), DIMENSION(:,:,:,:), ALLOCATABLE :: r_flowx
+!       REAL (KIND = GRID_SR), DIMENSION(:,:,:,:), ALLOCATABLE :: r_flowy
+!       REAL (KIND = GRID_SR), DIMENSION(:,:,:,:), ALLOCATABLE :: r_flowz
+!       REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE       :: r_lat
+!       REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE       :: r_lon
+!       REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE       :: r_alt
+!       REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE       :: r_times
+      REAL*4, DIMENSION(:,:,:,:), ALLOCATABLE :: r_flowx
+      REAL*4, DIMENSION(:,:,:,:), ALLOCATABLE :: r_flowy
+      REAL*4, DIMENSION(:,:,:,:), ALLOCATABLE :: r_flowz
+      REAL*4, DIMENSION(:), ALLOCATABLE       :: r_lat
+      REAL*4, DIMENSION(:), ALLOCATABLE       :: r_lon
+      REAL*4, DIMENSION(:), ALLOCATABLE       :: r_alt
+      REAL*8, DIMENSION(:), ALLOCATABLE       :: r_times
+      INTEGER (KIND = GRID_SI)  :: i_lon, i_lat, i_layer, i_timesteps
+      INTEGER (KIND = GRID_SI)  :: i_pointsx, i_pointsy, i_pointsz, &
+                                   i_timeinterval, i_intervalnum
+
+      PUBLIC                    :: slm_windfield, slm_windinit, slm_windquit
+      PUBLIC                    :: slm_vertwind
+
+      CONTAINS
+!*****************************************************************
+      FUNCTION slm_windfield(r_coord, i_layerid, r_time) RESULT (r_field)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension), INTENT(in) :: r_coord
+      INTEGER (KIND = GRID_SI), INTENT(in)                         :: i_layerid
+      REAL (KIND = GRID_SR), INTENT(in), OPTIONAL                  :: r_time
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)             :: r_field
+
+      REAL (KIND = GRID_SR)                                        :: r_tim
+
+!---------- set time
+
+      IF(present(r_time)) THEN
+        r_tim= r_time
+      ELSE
+        r_tim= 0.0_GRID_SR
+      END IF
+
+!---------- decide, if data has to be read
+
+      data_read: IF(r_readlast <= r_tim) THEN
+
+!---------- update values for next open
+
+        r_readlast    = r_readlast+ r_intervallen
+        i_timeinterval= i_timeinterval+ 1
+      END IF data_read
+
+!---------- interpolate to coordinate
+
+      r_field= data_interpol(r_coord, i_layerid, i_timeinterval)
+
+      RETURN
+      END FUNCTION slm_windfield
+
+!*****************************************************************
+      FUNCTION slm_vertwind(r_coord, i_layerid) RESULT (r_wwind)
+
+!---------- declarations
+
+      IMPLICIT NONE
+
+!---------- i/o parameters
+
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension), INTENT(in) :: r_coord
+      INTEGER (KIND = GRID_SI), INTENT(in)                         :: i_layerid
+      REAL (KIND = GRID_SR)                                        :: r_wwind
+
+!---------- interpolate to coordinate
+! Note that the time interval will be globally adjusted in the 
+! horizontal wind field computation!
+
+      r_wwind= vertical_interpol(r_coord, i_layerid, i_timeinterval)
+
+      RETURN
+      END FUNCTION slm_vertwind
+!*****************************************************************
+      SUBROUTINE slm_windinit(p_control)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (control_struct)     :: p_control
+      INTEGER (KIND = GRID_SI)  :: i_iofil= 19
+      CHARACTER (len=80)        :: a_filrow
+      INTEGER (KIND = GRID_SI)  :: i_iost, i_ioend, i_alct, i_cnt
+      INTEGER (KIND = GRID_SI)  :: i_mon, i_day, i_year
+      REAL (KIND = GRID_SR)     :: r_tim, r_start, r_t
+
+
+!---------- read current data from NetCDF file
+
+      CALL read_netcdf_currents(p_control)
+
+!---------- initialize some values
+
+      r_readlast    = 0.0_GRID_SR
+      i_timeinterval= 0_GRID_SI
+      r_intervallen = 21600._GRID_SR   ! we get a new wind value every 6 hours
+      r_start       = 1937256._GRID_SR ! this is the hours from 1800-01-01 for 2021...
+
+!---------- compute starting time frame
+
+      i_year= p_control%tst%tst_int(1,2)
+      i_mon = p_control%tst%tst_int(1,3)
+      i_day = p_control%tst%tst_int(1,4)
+      r_tim = time_from_datecomponents(i_year,i_mon,i_day,0,0,0,r_start)
+      time_loop: DO i_cnt=1,i_timesteps-1
+        r_t = r_times(i_cnt)
+        IF(r_times(i_cnt) .LT. r_tim) THEN
+          IF(r_times(i_cnt+1) .GE. r_tim) THEN
+            i_timeinterval = i_cnt
+            exit time_loop
+          END IF
+        END IF
+      END DO time_loop 
+
+!      RETURN
+      END SUBROUTINE slm_windinit
+
+!*****************************************************************
+      SUBROUTINE slm_windquit
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+!---------- deallocate wind data arrays
+
+      DEALLOCATE(r_flowx, r_flowy, r_flowz)
+      DEALLOCATE(r_lon, r_lat, r_alt, r_times)
+
+!      RETURN
+      END SUBROUTINE slm_windquit
+
+!*****************************************************************
+      SUBROUTINE read_netcdf_currents(p_control)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+      INCLUDE "netcdf.inc"
+      
+!---------- input parameters      
+      TYPE (control_struct), INTENT(in)      :: p_control
+      
+!---------- local variables
+      CHARACTER (len=io_fillen)              :: c_uname, c_vname, c_wname
+      INTEGER (KIND = GRID_SI)               :: i_alct, i_ncstat
+      INTEGER (KIND = GRID_SI)               :: i_filexid, i_fileyid, i_filezid
+      INTEGER (KIND = GRID_SI)               :: i_dimid, i_varid
+      INTEGER (KIND = GRID_SI)               :: i_tm, i_ln, i_lt, i_ly
+!       REAL (KIND = GRID_SR), DIMENSION(:,:,:,:), ALLOCATABLE :: r_auxx
+!       REAL (KIND = GRID_SR), DIMENSION(:,:,:,:), ALLOCATABLE :: r_auxy
+!       REAL (KIND = GRID_SR), DIMENSION(:,:,:,:), ALLOCATABLE :: r_auxz
+      REAL*4, DIMENSION(:,:,:,:), ALLOCATABLE :: r_auxx
+      REAL*4, DIMENSION(:,:,:,:), ALLOCATABLE :: r_auxy
+      REAL*4, DIMENSION(:,:,:,:), ALLOCATABLE :: r_auxz
+
+!---------- initialize file names
+      WRITE(GRID_parameters%ioout,*) &
+        '***** ***** ***** ***** INITIALIZE  ***** ***** ***** *****'
+      WRITE(GRID_parameters%ioout,*) &
+        '***** reading NetCDF file header ...                  *****'
+
+      WRITE(c_uname,*) trim(p_control%tst%tst_char(1))
+      c_uname= adjustl(c_uname)
+      WRITE(c_vname,*) trim(p_control%tst%tst_char(2))
+      c_vname= adjustl(c_vname)
+      WRITE(c_wname,*) trim(p_control%tst%tst_char(3))
+      c_wname= adjustl(c_wname)
+
+!---------- open current files
+
+      i_ncstat= nf_open(c_uname,NF_NOWRITE,i_filexid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not open data file for u')
+      i_ncstat= nf_open(c_vname,NF_NOWRITE,i_fileyid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not open data file for v')
+      i_ncstat= nf_open(c_wname,NF_NOWRITE,i_filezid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not open data file for w')
+    
+!---------- determine lon/lat/time/levels dimension sizes (grid size of currents field)
+
+      i_ncstat= nf_inq_dimid(i_filexid, 'lon', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify lon dimension')
+      i_ncstat= nf_inq_dimlen(i_filexid, i_dimid, i_lon)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read lon dimension')
+      
+      i_ncstat= nf_inq_dimid(i_filexid, 'lat', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify lat dimension')
+      i_ncstat= nf_inq_dimlen(i_filexid, i_dimid, i_lat)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read lat dimension')
+
+      i_ncstat= nf_inq_dimid(i_filexid, 'time', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify time dimension')
+      i_ncstat= nf_inq_dimlen(i_filexid, i_dimid, i_timesteps)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read time dimension')
+
+      i_ncstat= nf_inq_dimid(i_filexid, 'level', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify time dimension')
+      i_ncstat= nf_inq_dimlen(i_filexid, i_dimid, i_layer)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read time dimension')
+
+!---------- make sure layer number in file is larger than required from parameters
+
+      IF(i_layer .LT. p_control%tst%tst_int(1,1)) &
+        CALL grid_error(c_error='[read_netcdf_currents]: too few layers in NetCDF file')
+
+!---------- check dimension match in v- and w-component files
+
+      i_ncstat= nf_inq_dimid(i_fileyid, 'lon', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify lon dimension')
+      i_ncstat= nf_inq_dimlen(i_fileyid, i_dimid, i_ln)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read lon dimension')
+      IF(i_lon /= i_ln) &
+        CALL grid_error(c_error='[read_netcdf_currents]: lon dimension mismatch')
+
+      i_ncstat= nf_inq_dimid(i_fileyid, 'lat', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify lat dimension')
+      i_ncstat= nf_inq_dimlen(i_fileyid, i_dimid, i_lt)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read lat dimension')
+      IF(i_lat /= i_lt) &
+        CALL grid_error(c_error='[read_netcdf_currents]: lat dimension mismatch')
+
+      i_ncstat= nf_inq_dimid(i_fileyid, 'time', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify time dimension')
+      i_ncstat= nf_inq_dimlen(i_fileyid, i_dimid, i_tm)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read time dimension')
+      IF(i_timesteps /= i_tm) &
+        CALL grid_error(c_error='[read_netcdf_currents]: time dimension mismatch')
+
+      i_ncstat= nf_inq_dimid(i_fileyid, 'level', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify time dimension')
+      i_ncstat= nf_inq_dimlen(i_fileyid, i_dimid, i_ly)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read time dimension')
+      IF(i_layer /= i_ly) &
+        CALL grid_error(c_error='[read_netcdf_currents]: layer dimension mismatch')
+
+      i_ncstat= nf_inq_dimid(i_filezid, 'lon', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify lon dimension')
+      i_ncstat= nf_inq_dimlen(i_filezid, i_dimid, i_ln)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read lon dimension')
+      IF(i_lon /= i_ln) &
+        CALL grid_error(c_error='[read_netcdf_currents]: lon dimension mismatch')
+
+      i_ncstat= nf_inq_dimid(i_filezid, 'lat', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify lat dimension')
+      i_ncstat= nf_inq_dimlen(i_filezid, i_dimid, i_lt)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read lat dimension')
+      IF(i_lat /= i_lt) &
+        CALL grid_error(c_error='[read_netcdf_currents]: lat dimension mismatch')
+
+      i_ncstat= nf_inq_dimid(i_filezid, 'time', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify time dimension')
+      i_ncstat= nf_inq_dimlen(i_filezid, i_dimid, i_tm)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read time dimension')
+      IF(i_timesteps /= i_tm) &
+        CALL grid_error(c_error='[read_netcdf_currents]: time dimension mismatch')
+
+      i_ncstat= nf_inq_dimid(i_filezid, 'level', i_dimid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not identify time dimension')
+      i_ncstat= nf_inq_dimlen(i_filezid, i_dimid, i_ly)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read time dimension')
+      IF(i_ly .LT. p_control%tst%tst_int(1,1)) &
+        CALL grid_error(c_error='[read_netcdf_currents]: w-layer dimension mismatch')
+
+!---------- allocate latitude and longitude coordinate arrays
+
+      ALLOCATE(r_lat(i_lat), r_lon(i_lon), r_alt(i_layer), r_times(i_timesteps), stat= i_alct)
+      IF(i_alct /= 0) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not allocate lat/lon/alt/time field')
+
+!---------- read latitude and longitude coordinate values
+
+      i_ncstat= nf_inq_varid(i_filexid, 'lon', i_varid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not determine lon varid')
+      i_ncstat= nf_get_var_real(i_filexid, i_varid, r_lon)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read lon data')
+
+      i_ncstat= nf_inq_varid(i_filexid, 'lat', i_varid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not determine lat varid')
+      i_ncstat= nf_get_var_real(i_filexid, i_varid, r_lat)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read lat data')
+
+      i_ncstat= nf_inq_varid(i_filexid, 'level', i_varid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not determine level varid')
+      i_ncstat= nf_get_var_real(i_filexid, i_varid, r_alt)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read level data')
+
+      i_ncstat= nf_inq_varid(i_filexid, 'time', i_varid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not determine time varid')
+      i_ncstat= nf_get_var_double(i_filexid, i_varid, r_times)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read time data')
+
+!---------- copy globally available pressure level information
+
+      r_stclayerpressure(1:i_stcnumlayers) = r_alt(1:i_stcnumlayers)
+
+!---------- allocate current data arrays
+      WRITE(GRID_parameters%ioout,*) &
+        '***** reading NetCDF file core data ...               *****'
+
+      ALLOCATE(r_flowx(i_lon, i_lat, i_layer, i_timesteps), &
+               r_flowy(i_lon, i_lat, i_layer, i_timesteps), &
+               r_flowz(i_lon, i_lat, i_layer, i_timesteps), &
+               r_auxx(i_timesteps, i_layer, i_lat, i_lon), &
+               r_auxy(i_timesteps, i_layer, i_lat, i_lon), &
+               r_auxz(i_timesteps, i_layer, i_lat, i_lon), stat= i_alct)
+      IF(i_alct /= 0) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not allocate currents fields')
+
+!---------- read x-/y-direction data of currents
+
+      i_ncstat= nf_inq_varid(i_filexid, 'uwnd', i_varid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not determine varid of uwnd')
+      i_ncstat= nf_get_var_real(i_filexid, i_varid, r_auxx)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read uwnd data')
+
+      i_ncstat= nf_inq_varid(i_fileyid, 'vwnd', i_varid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not determine varid of vwnd')
+      i_ncstat= nf_get_var_real(i_fileyid, i_varid, r_auxy)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read vwnd data')
+
+      i_ncstat= nf_inq_varid(i_filezid, 'omega', i_varid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not determine varid of omega')
+      i_ncstat= nf_get_var_real(i_filezid, i_varid, r_auxz)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not read omega data')
+
+!---------- reshape fields for better accessibility
+      WRITE(GRID_parameters%ioout,*) &
+        '***** reshaping core data arrays ...                  *****'
+
+      r_flowx = reshape(r_auxx, shape(r_flowx), order=(/4,3,2,1/))
+      r_flowy = reshape(r_auxy, shape(r_flowy), order=(/4,3,2,1/))
+      r_flowz = reshape(r_auxz, shape(r_flowz), order=(/4,3,2,1/))
+      DEALLOCATE(r_auxx, r_auxy, r_auxz)
+
+!---------- Fix mask values
+      WRITE(GRID_parameters%ioout,*) &
+        '***** cleaning core data arrays ...                   *****'
+
+      DO i_tm=1,i_timesteps
+        DO i_ly= 1,i_layer
+          DO i_lt= 1,i_lat
+            DO i_ln= 1,i_lon
+              IF(r_flowx(i_ln,i_lt,i_ly,i_tm) .LE. -8.99E+30) &
+                r_flowx(i_ln,i_lt,i_ly,i_tm)= 0.0
+              IF(r_flowy(i_ln,i_lt,i_ly,i_tm) .LE. -8.99E+30) &
+                r_flowy(i_ln,i_lt,i_ly,i_tm)= 0.0
+              IF(r_flowz(i_ln,i_lt,i_ly,i_tm) .LE. -8.99E+30) &
+                r_flowz(i_ln,i_lt,i_ly,i_tm)= 0.0
+            END DO
+          END DO
+        END DO
+      END DO
+
+!---------- close currents files
+
+      i_ncstat= nf_close(i_filexid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not close uwnd data file')
+      i_ncstat= nf_close(i_fileyid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not close vwnd data file')
+      i_ncstat= nf_close(i_filezid)
+      IF(i_ncstat /= NF_NOERR) &
+        CALL grid_error(c_error='[read_netcdf_currents]: could not close omega data file')
+
+      WRITE(GRID_parameters%ioout,*) &
+        '***** finished ingesting wind data                    *****'
+      WRITE(GRID_parameters%ioout,*) &
+        '***** ***** ***** ***** ***** ***** ***** ***** ***** *****'
+
+!      RETURN
+      END SUBROUTINE read_netcdf_currents
+
+!*****************************************************************
+
+      FUNCTION data_interpol(r_cart, i_layer, i_tim) RESULT (r_field)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)    :: r_cart
+      INTEGER (KIND = GRID_SI)                            :: i_layer
+      INTEGER (KIND = GRID_SI)                            :: i_tim
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)    :: r_field
+
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimspherical) :: r_inter
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimspherical) :: r_coord
+      INTEGER (KIND = GRID_SI)                            :: i_lox, i_hix, i_loy, i_hiy, i_cnt
+      REAL (KIND = GRID_SR)                               :: r_dx, r_dy, r_lx, r_hx, &
+        r_ly, r_hy, r_l1, r_h1, r_l2, r_h2, r_dxi, r_dyi
+      REAL (KIND = GRID_SR)                               :: r_scalx, r_scaly
+      REAL (KIND = GRID_SR)                               :: r_deg
+      REAL (KIND = GRID_SR)                               :: r_earth
+     
+!---------- initialize radians
+
+      r_deg= 360._GRID_SR/(r_earthrad*2.*GRID_PI)
+     
+!---------- compute lat/lon coordinates from Cartesian (given) coordinates
+
+      r_coord = grid_kartgeo(r_cart)
+
+!---------- find wind box corresponding to coordinate
+
+      i_lox=1_GRID_SI
+      i_hix=2_GRID_SI
+      i_loy=1_GRID_SI
+      i_hiy=2_GRID_SI
+
+      determine_lon: DO i_cnt=1, i_lon-1
+        IF(r_lon(i_cnt) .LT. r_coord(1)) THEN
+          IF(r_lon(i_cnt +1) .GE. r_coord(1)) THEN
+            i_lox= i_cnt
+            i_hix= i_cnt+1
+            exit determine_lon
+          END IF
+        END IF
+      END DO determine_lon
+      IF(r_lon(i_lon) .LT. r_coord(1)) THEN
+        i_lox = i_lon-1
+        i_hix = i_lon
+      END IF
+
+      determine_lat: DO i_cnt=1, i_lat-1
+        IF(r_lat(i_cnt) .LT. r_coord(2)) THEN
+          IF(r_lat(i_cnt +1) .GE. r_coord(2)) THEN
+            i_loy= i_cnt
+            i_hiy= i_cnt+1
+            exit determine_lat
+          END IF
+        END IF
+      END DO determine_lat
+      IF(r_lat(i_lat) .LT. r_coord(2)) THEN
+        i_loy = i_lat-1
+        i_hiy = i_lat
+      END IF
+      
+
+!---------- calculate weights for bilinear interpolation
+!           NOTE: We do not consider the distance stretching with height!
+
+      r_dx= r_lon(i_hix)- r_lon(i_lox)
+      r_dy= r_lat(i_hiy)- r_lat(i_loy)
+      r_lx= r_coord(1) - r_lon(i_lox)
+      r_ly= r_coord(2) - r_lat(i_loy)
+      r_hx= r_lon(i_hix) - r_coord(1)
+      r_hy= r_lat(i_hiy) - r_coord(2)
+      r_scalx=r_deg
+      r_scaly=r_deg*cos(r_coord(2))
+
+!---------- linear interpolation in x-direction
+
+      IF(r_dx /= 0.0_GRID_SR) THEN
+        r_dxi= 1._GRID_SR/r_dx
+        r_l1= (r_hx* r_flowx(i_lox, i_loy, i_layer, i_tim)+ &
+               r_lx* r_flowx(i_hix, i_loy, i_layer, i_tim))* r_dxi
+        r_h1= (r_hx* r_flowx(i_lox, i_hiy, i_layer, i_tim)+ &
+               r_lx* r_flowx(i_hix, i_hiy, i_layer, i_tim))* r_dxi
+        r_l2= (r_hx* r_flowy(i_lox, i_loy, i_layer, i_tim)+ &
+               r_lx* r_flowy(i_hix, i_loy, i_layer, i_tim))* r_dxi
+        r_h2= (r_hx* r_flowy(i_lox, i_hiy, i_layer, i_tim)+ &
+               r_lx* r_flowy(i_hix, i_hiy, i_layer, i_tim))* r_dxi
+      ELSE
+        r_l1= r_flowx(i_lox, i_loy, i_layer, i_tim)
+        r_h1= r_flowx(i_lox, i_hiy, i_layer, i_tim)
+        r_l2= r_flowy(i_lox, i_loy, i_layer, i_tim)
+        r_h2= r_flowy(i_lox, i_hiy, i_layer, i_tim)
+      END IF
+
+!---------- linear interpolation in y-direction
+
+      IF(r_dy /= 0.0_GRID_SR) THEN
+        r_dyi= 1._GRID_SR/r_dy
+        r_inter(1)= (r_hy* r_l1+ r_ly* r_h1)* r_dyi* r_scalx
+        r_inter(2)= (r_hy* r_l2+ r_ly* r_h2)* r_dyi* r_scaly
+      ELSE
+        r_inter(1)= r_l1* r_scalx
+        r_inter(2)= r_l2* r_scaly
+      END IF
+
+!---------- calculate wind vector in kartesian coordinates
+
+	  r_field= kartwind(r_inter,r_coord)
+
+      RETURN
+      END FUNCTION data_interpol
+
+!*****************************************************************
+      FUNCTION vertical_interpol(r_cart, i_layer, i_tim) RESULT (r_inter)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension) :: r_cart
+      INTEGER (KIND = GRID_SI)                         :: i_layer
+      INTEGER (KIND = GRID_SI)                         :: i_tim
+      REAL (KIND = GRID_SR)                            :: r_inter
+
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimspherical) :: r_coord
+      INTEGER (KIND = GRID_SI)                         :: i_lox, i_hix, i_loy, i_hiy, i_cnt
+      REAL (KIND = GRID_SR)                            :: r_dx, r_dy, r_lx, r_hx, &
+        r_ly, r_hy, r_l1, r_h1, r_l2, r_h2, r_dxi, r_dyi
+      REAL (KIND = GRID_SR)                            :: r_scalx, r_scaly
+      REAL (KIND = GRID_SR)                            :: r_deg
+      REAL (KIND = GRID_SR)                            :: r_earth
+          
+!---------- compute lat/lon coordinates from Cartesian (given) coordinates
+
+      r_coord = grid_kartgeo(r_cart)
+
+!---------- find wind box corresponding to coordinate
+
+      i_lox=1_GRID_SI
+      i_hix=2_GRID_SI
+      i_loy=1_GRID_SI
+      i_hiy=2_GRID_SI
+
+      determine_lon: DO i_cnt=1, i_lon-1
+        IF(r_lon(i_cnt) .LT. r_coord(1)) THEN
+          IF(r_lon(i_cnt +1) .GE. r_coord(1)) THEN
+            i_lox= i_cnt
+            i_hix= i_cnt+1
+            exit determine_lon
+          END IF
+        END IF
+      END DO determine_lon
+      IF(r_lon(i_lon) .LT. r_coord(1)) THEN
+        i_lox = i_lon-1
+        i_hix = i_lon
+      END IF
+
+      determine_lat: DO i_cnt=1, i_lat-1
+        IF(r_lat(i_cnt) .LT. r_coord(2)) THEN
+          IF(r_lat(i_cnt +1) .GE. r_coord(2)) THEN
+            i_loy= i_cnt
+            i_hiy= i_cnt+1
+            exit determine_lat
+          END IF
+        END IF
+      END DO determine_lat
+      IF(r_lat(i_lat) .LT. r_coord(2)) THEN
+        i_loy = i_lat-1
+        i_hiy = i_lat
+      END IF
+      
+
+!---------- calculate weights for bilinear interpolation
+!           NOTE: We do not consider the distance stretching with height!
+
+      r_dx= r_lon(i_hix)- r_lon(i_lox)
+      r_dy= r_lat(i_hiy)- r_lat(i_loy)
+      r_lx= r_coord(1) - r_lon(i_lox)
+      r_ly= r_coord(2) - r_lat(i_loy)
+      r_hx= r_lon(i_hix) - r_coord(1)
+      r_hy= r_lat(i_hiy) - r_coord(2)
+
+!---------- linear interpolation in x-direction
+
+      IF(r_dx /= 0.0_GRID_SR) THEN
+        r_dxi= 1._GRID_SR/r_dx
+        r_l1= (r_hx* r_flowz(i_lox, i_loy, i_layer, i_tim)+ &
+               r_lx* r_flowz(i_hix, i_loy, i_layer, i_tim))* r_dxi
+        r_h1= (r_hx* r_flowz(i_lox, i_hiy, i_layer, i_tim)+ &
+               r_lx* r_flowz(i_hix, i_hiy, i_layer, i_tim))* r_dxi
+      ELSE
+        r_l1= r_flowz(i_lox, i_loy, i_layer, i_tim)
+        r_h1= r_flowz(i_lox, i_hiy, i_layer, i_tim)
+      END IF
+
+!---------- linear interpolation in y-direction
+
+      IF(r_dy /= 0.0_GRID_SR) THEN
+        r_dyi= 1._GRID_SR/r_dy
+        r_inter= (r_hy* r_l1+ r_ly* r_h1)* r_dyi
+      ELSE
+        r_inter= r_l1
+      END IF
+
+      RETURN
+      END FUNCTION vertical_interpol
+
+!*****************************************************************
+      FUNCTION time_from_datecomponents(i_year, i_month, i_day, i_hour, i_minute, &
+                                        i_second, r_start, l_leap) RESULT (r_longtime)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+      INTEGER (KIND = GRID_SI), INTENT(in)  :: i_year
+      INTEGER (KIND = GRID_SI), INTENT(in)  :: i_month
+      INTEGER (KIND = GRID_SI), INTENT(in)  :: i_day
+      INTEGER (KIND = GRID_SI), INTENT(in)  :: i_hour
+      INTEGER (KIND = GRID_SI), INTENT(in)  :: i_minute
+      INTEGER (KIND = GRID_SI), INTENT(in)  :: i_second
+      REAL (KIND = GRID_SR), INTENT(in)     :: r_start
+      LOGICAL, INTENT(in), OPTIONAL         :: l_leap
+      REAL (KIND = GRID_SR)                 :: r_longtime
+      
+      INTEGER (KIND = GRID_SI), DIMENSION(12) :: i_montharray
+      LOGICAL                                 :: l_leapyear
+      REAL (KIND = GRID_SR)                   :: r_accumhours
+      INTEGER (KIND = GRID_SI)                :: i_cnt, i_current
+     
+!---------- conversion function -- DOES NOT WORK (2022-01-25, JB)
+! reference: https://wiki.usask.ca/display/MESH/How+to+manually+calculate+NetCDF+times
+
+!       r_longtime = real((1461*(i_year + 4800 + (i_month - 14)/12))/4 + &
+!                        (367*(i_month - 2 - 12*((i_month - 14)/12)))/12 - &
+!                        (3*((i_year + 4900 + (i_month - 14)/12)/100))/4 + i_day - 32075) + &
+!                        i_hour/24.0 + i_minute/24.0/60.0 + i_second/24.0/60.0/60.0
+
+!---------- handle optional leap year variable
+
+      IF(present(l_leap)) THEN
+        l_leapyear= l_leap
+      ELSE
+        l_leapyear= .FALSE.
+      END IF
+
+!---------- define month's days
+
+      IF(l_leapyear) THEN
+        i_montharray = (/ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /)
+      ELSE
+        i_montharray = (/ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /)
+      END IF
+
+!---------- compute accumulated hours from start for the months
+
+      r_accumhours = 0.
+      i_current    = 0
+      DO i_cnt=1,i_month
+        r_accumhours = r_accumhours+ 24. * i_current
+        i_current = i_montharray(i_cnt)
+      END DO
+
+!---------- compute accumulated hours from days, hours, minutes and seconds
+      
+      r_accumhours = r_accumhours+ 24. * (i_day-1) + i_hour + i_minute/60 + i_second/3600
+
+!---------- add offset
+
+      r_longtime = r_accumhours + r_start
+
+      RETURN
+      END FUNCTION time_from_datecomponents
+
+!*****************************************************************
+      SUBROUTINE datecomponents_from_time(r_longtime, r_start, i_year, i_month, i_day, i_hour, &
+                                          i_minute, i_second, l_leap)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+      REAL (KIND = GRID_SR), INTENT(in)       :: r_longtime
+      REAL (KIND = GRID_SR), INTENT(in)       :: r_start
+      INTEGER (KIND = GRID_SI), INTENT(inout) :: i_year
+      INTEGER (KIND = GRID_SI), INTENT(out)   :: i_month
+      INTEGER (KIND = GRID_SI), INTENT(out)   :: i_day
+      INTEGER (KIND = GRID_SI), INTENT(out)   :: i_hour
+      INTEGER (KIND = GRID_SI), INTENT(out)   :: i_minute
+      INTEGER (KIND = GRID_SI), INTENT(out)   :: i_second
+      LOGICAL, OPTIONAL                       :: l_leap
+    
+      INTEGER (KIND = GRID_SI)               :: i_auxa, i_auxb, i_auxc
+      
+      INTEGER (KIND = GRID_SI), DIMENSION(12) :: i_montharray
+      LOGICAL                                 :: l_leapyear
+      REAL (KIND = GRID_SR)                   :: r_accumhours, r_time, r_remhours, r_hours
+      INTEGER (KIND = GRID_SI)                :: i_cnt, i_current
+
+!---------- conversion function -- DOES NOT WORK (2022-01-25, JB)
+! reference: https://wiki.usask.ca/display/MESH/How+to+manually+calculate+NetCDF+times
+
+!       i_auxa = 4*(floor(r_longtime) + 1401 + (((4*floor(r_longtime) + &
+!                274277)/146097)*3)/4 - 38) + 3
+!       i_auxb = mod(i_auxa, 1461)/4
+!       i_auxc = 5*i_auxb + 2
+! 
+!       i_day = (mod(i_auxc, 153))/5 + 1
+!       i_month = mod((i_auxc/153 + 2), 12) + 1
+!       i_year = i_auxa/1461 - 4716 + (12 + 2 - i_month)/12
+!       i_second = mod(nint((r_longtime - floor(r_longtime))*24.0*60.0*60.0), 60)
+!       i_minute = mod(nint((r_longtime - floor(r_longtime))*24.0*60.0 - i_second/60.0), 60)
+!       i_hour = nint((r_longtime - floor(r_longtime))*24.0 - i_minute/60.0 - i_second/60.0/60.0)
+
+!---------- handle optional leap year variable
+
+      IF(present(l_leap)) THEN
+        l_leapyear= l_leap
+      ELSE
+        l_leapyear= .FALSE.
+      END IF
+
+!---------- define month's days
+
+      IF(l_leapyear) THEN
+        i_montharray = (/ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /)
+      ELSE
+        i_montharray = (/ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /)
+      END IF
+
+!---------- compute month
+
+      r_time       = r_longtime - r_start
+      r_accumhours = 0.
+      i_current    = 0
+      i_cnt        = 1
+      DO WHILE ((r_accumhours .LT. r_time) .AND. (i_cnt .LE. 12))
+        i_current    = i_montharray(i_cnt)
+        r_accumhours = r_accumhours+ 24. * i_current
+        i_cnt        = i_cnt + 1
+      END DO
+      i_month = i_cnt
+
+!---------- from remaining hours compute days
+
+      r_remhours = r_time - (24. * sum(i_montharray(1:i_month)))
+      i_day      = floor(r_remhours/24) + 1
+      r_hours    = modulo(r_remhours,24._GRID_SR)
+
+!---------- now hours, minutes, seconds
+
+      i_hour     = floor(r_hours)
+      r_hours    = r_hours - REAL(i_hour,GRID_SR)
+      
+      i_minute   = floor(r_hours*60.)
+      r_hours    = r_hours*60. - REAL(i_minute,GRID_SR)
+      
+      i_second   = floor(r_hours*60.)
+
+      END SUBROUTINE datecomponents_from_time
+
+!*****************************************************************
+	  FUNCTION kartwind(r_lamphi, r_lpcoor) RESULT (r_kart)
+
+!---------- local declarations
+
+	  IMPLICIT NONE
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimspherical) :: r_lamphi, r_lpcoor
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)    :: r_kart
+	  REAL (KIND = GRID_SR)                               :: r_sl, r_cl, r_sp, r_cp
+
+!---------- calculate constants
+
+	  r_sl= sin(r_lpcoor(1))
+	  r_cl= cos(r_lpcoor(1))
+	  r_sp= sin(r_lpcoor(2))
+	  r_cp= cos(r_lpcoor(2))
+
+!---------- calculate 3D kartesian components
+
+	  r_kart(1)= -r_sl* r_lamphi(1)- r_sp* r_cl* r_lamphi(2)
+	  r_kart(2)=  r_cl* r_lamphi(1)- r_sp* r_sl* r_lamphi(2)
+	  r_kart(3)=                     r_cp*       r_lamphi(2)
+
+	  RETURN
+	  END FUNCTION kartwind
+
+!*****************************************************************
+    END MODULE ADV_wind
diff --git a/flash2d/src/options-sphere/FLASH_metadata_stacked.f90 b/flash2d/src/options-sphere/FLASH_metadata_stacked.f90
new file mode 100644
index 0000000000000000000000000000000000000000..daaecc2e29298d24cfbade188ef176fbfc16a998
--- /dev/null
+++ b/flash2d/src/options-sphere/FLASH_metadata_stacked.f90
@@ -0,0 +1,75 @@
+!*******************************************************************************
+!
+!> @file  FLASH_metadata.f90
+!> @brief contains metadata definitions for FLASH_parameters
+!
+!*******************************************************************************
+! MODULE DESCRIPTION:
+!> @brief   This is a meta data structure that contains info for the 
+!>          FLASH_parameters physical parameters, related to different
+!>          Test cases.
+!> @author  J. Behrens
+!> @version 1.0
+!> @date    5/2016
+!*****************************************************************
+    MODULE FLASH_metadata
+
+    IMPLICIT NONE
+
+!---------- character length for comparison
+
+    INTEGER, PARAMETER                          :: i_comparlen=12 
+
+!---------- meta data for logical parameters 
+
+    LOGICAL, PARAMETER                          :: l_logused= .FALSE.
+    INTEGER, PARAMETER                          :: i_lognum=1
+    CHARACTER (len=i_comparlen), DIMENSION(i_lognum)  :: c_logkeywds= &
+                                                (/ '            ' /)
+
+!---------- meta data for integer parameters 
+
+    LOGICAL, PARAMETER                          :: l_intused= .TRUE.
+    INTEGER, PARAMETER                          :: i_intnum=4
+    INTEGER, DIMENSION(i_intnum)                :: i_intsizes= (/ 1, 1, 1, 1 /)
+    CHARACTER (len=i_comparlen), DIMENSION(i_intnum)  :: c_intkeywds= &
+                                                (/ 'NUM_VERT_LAY', &
+                                                   'START_TIME_Y', &
+                                                   'START_TIME_M', &
+                                                   'START_TIME_D' /)
+
+!---------- meta data for character parameters 
+
+    LOGICAL, PARAMETER                          :: l_charused= .TRUE.
+    INTEGER, PARAMETER                          :: i_charnum=3
+    INTEGER, PARAMETER                          :: i_charlength= 64
+    CHARACTER (len=i_comparlen), DIMENSION(i_charnum) :: c_charkeywds= &
+                                                (/ 'UWIND_FILE_N', &
+                                                   'VWIND_FILE_N', &
+                                                   'OMEGA_FILE_N' /)
+
+!---------- meta data for real parameters 
+
+    LOGICAL, PARAMETER                          :: l_realused= .TRUE.
+    INTEGER, PARAMETER                          :: i_realnum=5
+    INTEGER, DIMENSION(i_realnum)               :: i_realsizes= (/ 1, 1, 1, 1, 1 /)
+    CHARACTER (len=i_comparlen), DIMENSION(i_realnum) :: c_realkeywds= &
+                                                (/ 'SEA_LEVEL_PR', &
+                                                   'SEA_LEVEL_TE', &
+                                                   'TEMP_LAPSE_R', &
+                                                   'IDEAL_GAS_CO', &
+                                                   'DRY_AIR_MOLA' /)
+
+!---------- convenience pointers
+
+    INTEGER, PARAMETER                          :: PARAM_SL_PRESS= 1
+    INTEGER, PARAMETER                          :: PARAM_SL_TMPTR= 2
+    INTEGER, PARAMETER                          :: PARAM_TEMPLAPS= 3
+    INTEGER, PARAMETER                          :: PARAM_IDEALGAS= 4
+    INTEGER, PARAMETER                          :: PARAM_DRYAIRML= 5
+    INTEGER, PARAMETER                          :: PARAM_UWINDFIL= 1
+    INTEGER, PARAMETER                          :: PARAM_VWINDFIL= 2
+    INTEGER, PARAMETER                          :: PARAM_OWINDFIL= 3
+    INTEGER, PARAMETER                          :: PARAM_NUMLAYER= 1
+
+	END MODULE FLASH_metadata
diff --git a/flash2d/src/options-sphere/FLASH_parameters_stacked.f90 b/flash2d/src/options-sphere/FLASH_parameters_stacked.f90
new file mode 100644
index 0000000000000000000000000000000000000000..9dd8c8ccad383f2486c5317674287b7f023c0e71
--- /dev/null
+++ b/flash2d/src/options-sphere/FLASH_parameters_stacked.f90
@@ -0,0 +1,126 @@
+!*****************************************************************
+!
+! MODULE NAME:
+!	FLASH_parameters
+! FUNCTION:
+!	defines global control structure
+! CONTAINS:
+!
+! PUBLIC:
+!	all
+! COMMENTS:
+!
+! LIBRARIES:
+!
+! REFERENCES:
+!
+! VERSION(S):
+!	1. original version		j. behrens	12/2000
+!
+!*****************************************************************
+    MODULE FLASH_parameters
+    USE GRID_api
+    
+    IMPLICIT NONE
+    INTEGER, PARAMETER :: io_fillen=128
+    INTEGER, PARAMETER :: i_redirout=8
+    INTEGER, PARAMETER :: i_redirlog=7
+    INTEGER, PARAMETER :: i_comparlen=14 
+
+!---------- structure for the command line
+
+    TYPE cmdline_param
+      SEQUENCE
+      CHARACTER (len=io_fillen) :: c_infile       ! input file name
+      CHARACTER (len=io_fillen) :: c_directory    ! input file name
+      LOGICAL                   :: l_output       ! redirect std output
+      LOGICAL                   :: l_logging      ! enable logging (verbose)
+    END TYPE cmdline_param
+
+!---------- structure for the i/o behaviour
+
+    TYPE io_param
+      SEQUENCE
+      LOGICAL                   :: l_diagnostics  ! switch on diagnostics
+      LOGICAL                   :: l_vtu          ! switch on vtu output
+      LOGICAL                   :: l_netcdf       ! switch on NetCDF output
+      INTEGER                   :: i_plotoffset   ! timesteps between plots
+      INTEGER                   :: i_saveoffset   ! timesteps between savesets
+      INTEGER                   :: i_savelast     ! indicator for last step saving
+      CHARACTER (len=io_fillen) :: c_domainfile   ! file with definitions for domain
+      CHARACTER (len=io_fillen) :: c_triangfile   ! file with initial triangulation
+    END TYPE io_param
+
+!---------- structure for global physical and steering parameters
+
+    TYPE num_param
+      SEQUENCE
+      REAL               :: r_deltatime     ! timestep length [s]
+      REAL               :: r_reftolerance  ! tolerance for refinement
+      REAL               :: r_crstolerance  ! tolerance for coarsening
+      REAL               :: r_refwatermark  ! watermark for refinement
+      REAL               :: r_crswatermark  ! watermark for coarsening
+      REAL               :: r_starttime     ! first time (overwrites i_frsttimestep)
+      REAL               :: r_finaltime     ! last time (overwrites i_lasttimestep)
+      INTEGER            :: i_experiment    ! current experiment identification
+      INTEGER            :: i_crslevel      ! coarsest requested level
+      INTEGER            :: i_reflevel      ! finest requested level
+      INTEGER            :: i_frsttimestep  ! first timestep of experiment
+      INTEGER            :: i_lasttimestep  ! last timestep of experiment
+      INTEGER            :: i_adviterations ! iterations in trajectory estimation
+    END TYPE num_param
+
+!---------- structure for global physical and steering parameters
+
+    TYPE test_param
+      INTEGER                                             :: i_lognum
+      INTEGER                                             :: i_intnum
+      INTEGER                                             :: i_realnum
+      INTEGER                                             :: i_charnum
+      INTEGER, DIMENSION(:), POINTER                      :: i_intsizes
+      INTEGER, DIMENSION(:), POINTER                      :: i_realsizes
+      CHARACTER (len=i_comparlen), DIMENSION(:), POINTER  :: c_logkeywds
+      CHARACTER (len=i_comparlen), DIMENSION(:), POINTER  :: c_intkeywds
+      CHARACTER (len=i_comparlen), DIMENSION(:), POINTER  :: c_realkeywds
+      CHARACTER (len=i_comparlen), DIMENSION(:), POINTER  :: c_charkeywds
+      LOGICAL, DIMENSION(:), POINTER                      :: tst_log
+      CHARACTER (len=io_fillen), DIMENSION(:), POINTER    :: tst_char
+      INTEGER, DIMENSION(:,:), POINTER                    :: tst_int
+      REAL, DIMENSION(:,:), POINTER                       :: tst_real
+    END TYPE test_param
+
+!---------- global control structure
+
+	TYPE control_struct
+	  TYPE (num_param)          :: num
+	  TYPE (cmdline_param)      :: cmd
+	  TYPE (io_param)           :: io
+	  TYPE (test_param)         :: tst
+	END TYPE control_struct
+	TYPE (control_struct)       :: p_contr
+
+!---------- structure for runtime information
+
+	TYPE rt_info
+	  REAL               :: r_modeltime
+	  INTEGER            :: i_step
+	  INTEGER            :: i_adapit
+	  LOGICAL            :: l_saved
+	  LOGICAL            :: l_ploted
+	END TYPE rt_info
+	TYPE (rt_info)       :: p_timestepinfo
+
+!---------- convenience pointers to stacked layers
+
+    INTEGER (KIND = GRID_SI)   :: i_stctracer
+    INTEGER (KIND = GRID_SI)   :: i_stcnumlayers
+
+!---------- array for storing stacked layer pressure levels
+
+    REAL (KIND = GRID_SR), DIMENSION(:), POINTER :: r_stclayerpressure        
+
+!---------- array for storing stacked layer pressure levels
+
+    REAL (KIND = GRID_SR), PARAMETER             :: r_earthrad=6378134._GRID_SR
+    
+	END MODULE FLASH_parameters
diff --git a/flash2d/src/options-sphere/IO_vtu_stacked.F90 b/flash2d/src/options-sphere/IO_vtu_stacked.F90
new file mode 100644
index 0000000000000000000000000000000000000000..f2d0481aac47e8267a7dee53a174feaebea8a231
--- /dev/null
+++ b/flash2d/src/options-sphere/IO_vtu_stacked.F90
@@ -0,0 +1,585 @@
+!-----------------------------------------------------------------------
+!> \file IO_vtu.F90
+!> \brief Contains the module IO_vtu
+!-----------------------------------------------------------------------
+!> The MODULE IO_vtu create a vtu file, unstructered grid, readable by
+!!                     paraview
+!
+!> Actually, amatos' structure denies a unified handling for
+!! 2d, 3d and spherical case. Therefore the corresponding definition
+!! has to be uncommented
+!-----------------------------------------------------------------------
+
+!#define VTU_OUTPUT2D
+!#define VTU_OUTPUT3D
+!#define VTU_OUTPUTSPH
+#define VTU_OUTPUTSTC
+
+MODULE IO_vtu
+
+USE GRID_api
+
+PUBLIC :: plot_vtu, t_vtu_data
+
+#if defined VTU_OUTPUT2D || defined VTU_OUTPUTSPH
+  INTEGER(KIND=GRID_SI), PARAMETER         :: i_nodespercell = GRID_elementnodes
+  INTEGER(KIND=GRID_SI), PARAMETER         :: i_nodesperface = GRID_edgenodes
+
+  ! This defines a triangle in VTK format
+  INTEGER(KIND=GRID_SI), PARAMETER         :: i_vtucelltype = 5
+#elif defined VTU_OUTPUT3D
+  INTEGER(KIND=GRID_SI), PARAMETER         :: i_nodespercell = GRID_tetranodes
+  INTEGER(KIND=GRID_SI), PARAMETER         :: i_nodesperface = GRID_elementnodes
+
+  ! This defines a tetrahedron in VTK format
+  INTEGER(KIND=GRID_SI), PARAMETER         :: i_vtucelltype = 10
+#elif defined VTU_OUTPUTSTC
+  INTEGER(KIND=GRID_SI), PARAMETER         :: i_nodespercell = GRID_elementnodes*2
+  INTEGER(KIND=GRID_SI), PARAMETER         :: i_nodesperface = GRID_edgenodes
+
+  ! This defines a wedge/prism in VTK format
+  INTEGER(KIND=GRID_SI), PARAMETER         :: i_vtucelltype = 13
+#endif
+
+
+!> Structure for variable information
+TYPE t_vtu_data
+  CHARACTER(LEN=32)                              :: c_name  !< VTU variable name
+  INTEGER(KIND=GRID_SI)                          :: i_size  !< data dimension
+  REAL(KIND=GRID_SR),POINTER, DIMENSION(:,:)     :: p_vdata !< pointer to data
+END TYPE t_vtu_data
+
+!> Very small values can cause errors when read in paraview.
+!! This is the threshold for filtering.
+REAL(KIND = GRID_SR), PARAMETER                  :: r_vtueps = 1e-12
+CONTAINS
+
+!---------------------------------------------------------------------
+!> \brief Writes a VTU file
+!> Use this routine to plot continuous or discontinuous data.
+!> \param[in] p_mesh          The mesh
+!> \param[in] c_filename      The name of the file to write to
+!> \param[in] i_nodedata      Size of the array p_nodedata
+!> \param[in] p_nodedata      Array of type t_vtu_data for node
+!!                            data. For each node one entry has to exist in
+!!                            p_vdata.
+!> \param[in] i_celldata      Size of the array p_celldata
+!> \param[in] p_celldata      Array of type t_vtu_data for cell
+!!                            data. For each tetrahedron one entry has to
+!!                            exist in p_vdata.
+#ifdef VTU_OUTPUT2D
+!> \param[in] r_zcoordinate   The z-coordinate values
+!> \param[in] i_zcoordinate   Use the i_zcoordinate component of p_nodedata
+!!                            also as z-coordinate
+#endif
+!> \param[in] l_continuous    Write continuous node data.
+!!                            This needs less space than discontinuous.
+!!                            default: .true.
+!> \param[in] l_grid_info     Write grid numbering information
+!!                            default: .false.
+!---------------------------------------------------------------------
+SUBROUTINE plot_vtu(p_mesh, c_filename, &
+                    i_nodedata, p_nodedata, i_celldata, p_celldata, &
+#ifdef VTU_OUTPUT2D
+                    r_zcoordinate, i_zcoordinate, &
+#endif
+#ifdef VTU_OUTPUTSTC
+                    i_layers, r_height, &
+#endif
+                    l_continuous, l_grid_info)
+  IMPLICIT NONE
+
+  TYPE (grid_handle), INTENT(in)                 :: p_mesh
+  CHARACTER (len=*), INTENT(IN)                  :: c_filename
+  INTEGER(KIND=GRID_SI), INTENT(IN), OPTIONAL    :: i_nodedata
+  TYPE(t_vtu_data), INTENT(IN), DIMENSION(:), OPTIONAL &
+                                                 :: p_nodedata
+  INTEGER(KIND=GRID_SI), INTENT(IN), OPTIONAL    :: i_celldata
+  TYPE(t_vtu_data), INTENT(IN), DIMENSION(:), OPTIONAL &
+                                                 :: p_celldata
+#ifdef VTU_OUTPUT2D
+  REAL(KIND=GRID_SR), POINTER, DIMENSION(:,:), OPTIONAL &
+                                                 :: r_zcoordinate
+  INTEGER(KIND=GRID_SI), OPTIONAL, INTENT(IN)    :: i_zcoordinate
+#endif
+#ifdef VTU_OUTPUTSTC
+  REAL(KIND=GRID_SR), POINTER, DIMENSION(:), OPTIONAL &
+                                                 :: r_height
+  INTEGER(KIND=GRID_SI), OPTIONAL, INTENT(IN)    :: i_layers
+#endif
+  LOGICAL, INTENT(IN), OPTIONAL                  :: l_grid_info
+  LOGICAL, INTENT(IN), OPTIONAL                  :: l_continuous
+
+  INTEGER( KIND = GRID_SI)                       :: i_alct
+  INTEGER( KIND = GRID_SI)                       :: i_cnt
+  INTEGER( KIND = GRID_SI)                       :: i_fst
+  INTEGER( KIND = GRID_SI)                       :: i_ncnt
+  INTEGER( KIND = GRID_SI)                       :: i_lay
+  INTEGER( KIND = GRID_SI), PARAMETER            :: i_fhandle = 89
+
+  ! this variables result from different naming conventions in two and
+  ! three dimensions
+  INTEGER( KIND = GRID_SI)                       :: i_numberofcells
+  INTEGER( KIND = GRID_SI)                       :: i_numberoffaces
+  INTEGER( KIND = GRID_SI)                       :: i_numberofpoints
+
+  INTEGER (KIND = GRID_SI), DIMENSION(:,:), ALLOCATABLE     :: i_cellnodes
+  REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE        :: r_nodecoor
+  INTEGER (KIND = GRID_SI), DIMENSION(:), ALLOCATABLE       :: i_nodes
+
+  LOGICAL                                        :: l_write_grid_info
+  LOGICAL                                        :: l_continuous_data
+
+
+#ifdef VTU_OUTPUT2D
+  IF(PRESENT(i_zcoordinate) .AND. PRESENT(r_zcoordinate)) THEN
+    CALL GRID_error(c_error='[plot_vtu] z-coordinate is defined twice')
+  END IF
+#endif
+#ifdef VTU_OUTPUTSTC
+  IF(PRESENT(i_layers)) THEN
+    i_lay = i_layers
+  ELSE
+    i_lay = 2
+  END IF
+  IF (i_lay .LT. 2) THEN
+    CALL GRID_error(c_error='[plot_vtu] in stacked mode, you cannot plot less than one layer')
+  END IF
+  IF(.NOT. PRESENT(r_height)) THEN
+    CALL GRID_error(c_error='[plot_vtu] in stacked mode, a height array is needed')
+  END IF
+#endif
+
+  ! set the value of l_continuous. The default is .true.
+  IF(PRESENT(l_continuous)) THEN
+    l_continuous_data = l_continuous
+  ELSE
+    l_continuous_data = .TRUE.
+  END IF
+
+  ! set the value of l_grid_info. The default is .false..
+  IF(PRESENT(l_grid_info)) THEN
+    l_write_grid_info = l_grid_info
+  ELSE
+    l_write_grid_info = .FALSE.
+  END IF
+
+  ! Set dimension depending types
+#if defined VTU_OUTPUT2D || defined VTU_OUTPUTSPH
+  i_numberofcells = p_mesh%i_enumfine
+  i_numberoffaces = p_mesh%i_gnumfine
+#elif defined VTU_OUTPUT3D
+  i_numberofcells = p_mesh%i_tnumfine
+  i_numberoffaces = p_mesh%i_enumfine
+#elif defined VTU_OUTPUTSTC
+  i_numberofcells = p_mesh%i_enumfine* (i_lay-1)
+  i_numberoffaces = p_mesh%i_gnumfine* i_lay + p_mesh%i_nnumber* (i_lay-1)
+#endif
+
+  IF(l_continuous_data) THEN
+    i_numberofpoints = p_mesh%i_nnumber
+  ELSE
+    i_numberofpoints = i_numberofcells * i_nodespercell
+  END IF
+
+  ! We only need the node coordinates and the nodes per tetra
+  ! as additional information.
+  ALLOCATE(r_nodecoor(GRID_dimension, p_mesh%i_nnumber), &
+           i_cellnodes(i_nodespercell, i_numberofcells), &
+           stat = i_alct)
+
+  IF(i_alct /= 0) THEN
+    CALL grid_error(c_error='[write_vtu]: could not allocate data arrays')
+  END IF
+
+  CALL GRID_getinfo(p_mesh, r_nodecoordinates = r_nodecoor, &
+#if defined VTU_OUTPUT2D || defined VTU_OUTPUTSPH
+                   i_elementnodes = i_cellnodes)
+#elif defined VTU_OUTPUT3D
+                   i_tetranodes   = i_cellnodes)
+#endif
+
+  ! open the file and write header information
+  OPEN(i_fhandle, file = c_filename, iostat= i_fst)
+  IF(i_fst /= 0) THEN
+    RETURN
+  END IF
+
+  WRITE(i_fhandle, "(A)") '<?xml version="1.0"?>'
+  WRITE(i_fhandle, "(A)") '<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">'
+  WRITE(i_fhandle, *) '<UnstructuredGrid>'
+  WRITE(i_fhandle, "(A,I8,A,I8,A)") '<Piece NumberOfPoints="', &
+                        i_numberofpoints, &
+                        '" NumberOfCells="', &
+                        i_numberofcells, &
+                        '">'
+
+  ! write the node coordinates to VTU file
+  WRITE(i_fhandle, *) '<Points>'
+  WRITE(i_fhandle, "(A,I1,A)") '<DataArray type="Float32" NumberOfComponents="', &
+  3, '" format="ascii">'
+
+  ! Distunguish between continuous and discontinuous case
+  IF(l_continuous_data) THEN
+    !> The continuous case is represented by amatos' grid topology.
+    DO i_cnt = 1, p_mesh%i_nnumber
+#if defined VTU_OUTPUT3D || defined VTU_OUTPUTSPH
+      WRITE(i_fhandle, *) r_nodecoor(:, i_cnt)
+#elif defined  VTU_OUTPUT2D
+    IF(PRESENT(r_zcoordinate)) THEN
+      WRITE(i_fhandle, *) r_nodecoor(:, i_cnt), r_zcoordinate(1, i_cnt)
+    ELSE IF(PRESENT(i_zcoordinate)) THEN
+      WRITE(i_fhandle, *) r_nodecoor(:, i_cnt), &
+                          p_nodedata(i_zcoordinate)%p_vdata(1, i_cnt)
+    ELSE
+      WRITE(i_fhandle, *) r_nodecoor(:, i_cnt), 0.0
+    END IF
+#endif
+    END DO
+
+  ELSE
+    ! Write the node coordinates. In this discontinuous case one node in
+    ! paraview belongs only to one cell.
+    DO i_cnt = 1, i_numberofcells
+      DO i_ncnt = 1, i_nodespercell
+#if defined VTU_OUTPUT2D || defined VTU_OUTPUTSPH
+        WRITE(i_fhandle, *) r_nodecoor(:, i_cellnodes(i_ncnt, i_cnt))
+#elif defined VTU_OUTPUT2D
+        IF(PRESENT(r_zcoordinate)) THEN
+          WRITE(i_fhandle, *) r_nodecoor(:, i_cellnodes(i_ncnt, i_cnt)), &
+                              r_zcoordinate(1, i_cellnodes(i_ncnt, i_cnt))
+        ELSE IF(PRESENT(i_zcoordinate)) THEN
+          WRITE(i_fhandle, *) r_nodecoor(:, i_cellnodes(i_ncnt, i_cnt)), &
+              p_nodedata(i_zcoordinate)%p_vdata(1, i_cellnodes(i_ncnt, i_cnt))
+        ELSE
+          WRITE(i_fhandle, *) r_nodecoor(:, i_cellnodes(i_ncnt, i_cnt)), 0.0
+        END IF
+#endif
+      END DO
+    END DO
+  END IF
+
+  WRITE(i_fhandle, *) '</DataArray>'
+  WRITE(i_fhandle, *) '</Points>'
+
+  ! Write the node connectivity
+  WRITE(i_fhandle, *) '<Cells>'
+  WRITE(i_fhandle, *) '<DataArray type="Int32" Name="connectivity" format="ascii">'
+
+  ! check wether continuous data is written
+  IF(l_continuous_data) THEN
+    ! The indexing in paraview starts with 0. Therefore we subtract one from
+    ! the node connectivity information.
+#if defined VTU_OUTPUT2D || defined VTU_OUTPUTSPH
+    DO i_cnt = 1, p_mesh%i_enumfine
+#elif defined VTU_OUTPUT3D
+    DO i_cnt = 1, p_mesh%i_tnumfine
+#endif
+      WRITE(i_fhandle, *) i_cellnodes(:, i_cnt) - 1
+    END DO
+  ELSE
+    ! Write element nodes (indexing starts by 0!)
+    ! In the discontinuous case each tetrahedron has its own nodes
+    ALLOCATE(i_nodes(i_nodespercell), stat = i_alct)
+
+    IF(i_alct /= 0) THEN
+      CALL grid_error(c_error='[write_vtu]: could not allocate node array for VTU output')
+    END IF
+
+    DO i_cnt = 1, i_numberofcells * i_nodespercell, i_nodespercell
+
+      DO i_ncnt = 1, i_nodespercell
+        i_nodes(i_ncnt) = i_ncnt + i_cnt - 2
+      END DO
+
+      WRITE(i_fhandle, *) i_nodes
+    END DO
+
+    DEALLOCATE(i_nodes)
+  END IF
+
+  WRITE(i_fhandle, *) '</DataArray>'
+
+  ! write the cell type. Tetrahedra are represented by 10 and triangles by 5
+  WRITE(i_fhandle, *) '<DataArray type="UInt8" Name="types" format="ascii">'
+  DO i_cnt = 1, i_numberofcells
+    WRITE(i_fhandle, *) i_vtucelltype
+  END DO
+  WRITE(i_fhandle, *) '</DataArray>'
+  WRITE(i_fhandle, *) '<DataArray type="Int32" Name="offsets" format="ascii">'
+  DO i_cnt = 1, i_numberofcells
+    WRITE(i_fhandle, *) i_cnt * i_nodespercell
+  END DO
+  WRITE(i_fhandle, *) '</DataArray>'
+  WRITE(i_fhandle, *) '</Cells>'
+
+  ! Write the point data / node data
+  ! If the grid information is requested save the node numbering of amatos.
+  ! Since every node number in paraview is decreased by one, this option is
+  ! in continuous plotting not too useful.
+  WRITE(i_fhandle, *) '<PointData>'
+
+  IF(l_write_grid_info) THEN
+    WRITE(i_fhandle, *) '<DataArray type="Int32" Name="Nodenumber" format="ascii">'
+
+    DO i_cnt = 1, p_mesh%i_nnumber
+      WRITE(i_fhandle, *) i_cnt
+    END DO
+
+    WRITE(i_fhandle, *) '</DataArray>'
+  END IF
+
+  ! When variables for the node data are present, save them.
+  IF(PRESENT(i_nodedata) .AND. PRESENT(p_nodedata)) THEN
+    DO i_cnt = 1, i_nodedata
+      CALL write_vtu_data(i_fhandle, p_nodedata(i_cnt))
+    END DO
+  END IF
+
+  WRITE(i_fhandle, *) '</PointData>'
+
+
+
+  ! write the cell data.
+  WRITE(i_fhandle, *) '<CellData>'
+
+  ! Write the element numbers when requested.
+  IF(l_write_grid_info) THEN
+    WRITE(i_fhandle, *) '<DataArray type="Int32" Name="Elementnumber" format="ascii">'
+
+    DO i_cnt = 1, i_numberofcells
+      WRITE(i_fhandle, *) i_cnt
+    END DO
+
+    WRITE(i_fhandle, *) '</DataArray>'
+  END IF
+
+  ! Write the variable belonging to the tetradra.
+  IF(PRESENT(i_celldata) .AND. PRESENT(p_celldata)) THEN
+    DO i_cnt = 1, i_celldata
+      CALL write_vtu_data(i_fhandle, p_celldata(i_cnt))
+    END DO
+  END IF
+
+  ! write the end of cell data and the footer.
+  WRITE(i_fhandle, *) '</CellData>'
+  WRITE(i_fhandle, *) '</Piece>'
+  WRITE(i_fhandle, *) '</UnstructuredGrid>'
+  WRITE(i_fhandle, *) '</VTKFile>'
+
+  ! tidy up
+  CLOSE(i_fhandle)
+  DEALLOCATE(r_nodecoor, i_cellnodes)
+END SUBROUTINE plot_vtu
+
+
+#ifdef VTU_OUTPUT3D
+!---------------------------------------------------------------------
+!> Use this routine to plot the mesh consisting of face and
+!! continuous data on it.
+!> \param p_mesh      - the mesh
+!> \param c_filename    - the name of the file to write to
+!> \param i_nodedata    - (optional) size of the array p_nodedata
+!> \param p_nodedata    - (optional) array of type t_vtu_data for node
+!!                        data. For each node one entry has to exist in
+!!                        p_vdata.
+!> \param i_celldata    - (optional) size of the array p_celldata
+!> \param p_nodedata    - (optional) array of type t_vtu_data for cell
+!!                        data. For each face one entry has to
+!!                        exist in p_vdata.
+!> \param l_grid_info   - (optional) Write grid numbering information
+!!                        default: .false.
+!---------------------------------------------------------------------
+SUBROUTINE plot_vtu_elements(p_mesh, c_filename, i_nodedata, &
+                             p_nodedata, i_celldata, p_celldata, &
+                             l_grid_info)
+  IMPLICIT NONE
+
+  TYPE (grid_handle), INTENT(in)                 :: p_mesh
+  CHARACTER (len=*), INTENT(IN)                  :: c_filename
+  INTEGER(KIND=GRID_SI), INTENT(IN), OPTIONAL    :: i_nodedata
+  TYPE(t_vtu_data), INTENT(IN), DIMENSION(:), OPTIONAL &
+                                                 :: p_nodedata
+  INTEGER(KIND=GRID_SI), INTENT(IN), OPTIONAL    :: i_celldata
+  TYPE(t_vtu_data), INTENT(IN), DIMENSION(:), OPTIONAL &
+                                                 :: p_celldata
+
+  LOGICAL, INTENT(IN), OPTIONAL                  :: l_grid_info
+
+  LOGICAL                                        :: l_write_grid_info
+
+  INTEGER( KIND = GRID_SI)             :: i_alct, i_cnt, i_fst
+  INTEGER( KIND = GRID_SI)             :: i_fhandle = 89
+
+  INTEGER (KIND = GRID_SI), DIMENSION(:,:), ALLOCATABLE     :: i_enodes
+  REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE        :: r_nodecoor
+
+  !> set the optional data
+  IF(PRESENT(l_grid_info)) THEN
+    l_write_grid_info = l_grid_info
+  ELSE
+    l_write_grid_info = .FALSE.
+  END IF
+
+  ALLOCATE(r_nodecoor(GRID_dimension, p_mesh%i_nnumber), &
+           i_enodes(GRID_elementnodes, p_mesh%i_enumfine), &
+           stat = i_alct)
+
+  IF(i_alct /= 0) THEN
+    CALL grid_error(c_error='[write_vtu]: could not allocate data arrays')
+  END IF
+
+  CALL GRID_getinfo(p_mesh, r_nodecoordinates = r_nodecoor, &
+                   i_elementnodes = i_enodes)
+
+
+  OPEN(i_fhandle, file = c_filename, iostat= i_fst)
+  IF(i_fst /= 0) THEN
+    RETURN
+  END IF
+
+  !> Write the VTK header
+  WRITE(i_fhandle, "(A)") '<?xml version="1.0"?>'
+  WRITE(i_fhandle, "(A)") '<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">'
+  WRITE(i_fhandle, *) '<UnstructuredGrid>'
+  WRITE(i_fhandle, "(A,I8,A,I8,A)") '<Piece NumberOfPoints="', &
+                        p_mesh%i_nnumber, &
+                        '" NumberOfCells="', &
+                        p_mesh%i_enumfine, &
+                        '">'
+
+  !> Save the coordinates of all nodes
+  WRITE(i_fhandle, *) '<Points>'
+  WRITE(i_fhandle, "(A,I1,A)") '<DataArray type="Float32" NumberOfComponents="', &
+ 3 , '" format="ascii">'
+  DO i_cnt = 1, p_mesh%i_nnumber
+    WRITE(i_fhandle, *) r_nodecoor(:, i_cnt)
+  END DO
+  WRITE(i_fhandle, *) '</DataArray>'
+  WRITE(i_fhandle, *) '</Points>'
+
+  !> Write the cell (element) information
+  WRITE(i_fhandle, *) '<Cells>'
+
+  !> Save the node connectivity
+  WRITE(i_fhandle, *) '<DataArray type="Int32" Name="connectivity" format="ascii">'
+
+
+  !> write element nodes.  Write connectivity (indexing starts by 0!)
+  DO i_cnt = 1, p_mesh%i_enumfine
+    WRITE(i_fhandle, *) i_enodes(:, i_cnt) - 1
+  END DO
+  WRITE(i_fhandle, *) '</DataArray>'
+
+  !> Write the cell type (triangle = 5, tetrahedron = 10).
+  WRITE(i_fhandle, *) '<DataArray type="UInt8" Name="types" format="ascii">'
+  DO i_cnt = 1, p_mesh%i_enumfine
+    WRITE(i_fhandle, *) '5'
+  END DO
+  WRITE(i_fhandle, *) '</DataArray>'
+  WRITE(i_fhandle, *) '<DataArray type="Int32" Name="offsets" format="ascii">'
+  DO i_cnt = 1, p_mesh%i_enumfine
+    WRITE(i_fhandle, *) i_cnt * GRID_elementnodes
+  END DO
+  WRITE(i_fhandle, *) '</DataArray>'
+  WRITE(i_fhandle, *) '</Cells>'
+
+  !> write point data
+  WRITE(i_fhandle, *) '<PointData>'
+
+  !> Save the node numbers, when requested.
+  IF(l_write_grid_info) THEN
+    WRITE(i_fhandle, *) '<DataArray type="Int32" Name="Nodenumber" format="ascii">'
+
+    DO i_cnt = 1, p_mesh%i_nnumber
+      WRITE(i_fhandle, *) i_cnt
+    END DO
+
+    WRITE(i_fhandle, *) '</DataArray>'
+  END IF
+
+  !> Write the nodal variables, when present.
+  IF(PRESENT(i_nodedata) .AND. PRESENT(p_nodedata)) THEN
+    DO i_cnt = 1, i_nodedata
+      CALL write_vtu_data(i_fhandle, p_nodedata(i_cnt))
+    END DO
+  END IF
+
+  WRITE(i_fhandle, *) '</PointData>'
+
+
+
+  !> write cell data
+  WRITE(i_fhandle, *) '<CellData>'
+
+  !> save the element numbers, when requested.
+  IF(l_write_grid_info) THEN
+    WRITE(i_fhandle, *) '<DataArray type="Int32" Name="Elementnumber" format="ascii">'
+
+    DO i_cnt = 1, p_mesh%i_enumfine
+      WRITE(i_fhandle, *) i_cnt
+    END DO
+
+    WRITE(i_fhandle, *) '</DataArray>'
+  END IF
+
+  !> Write the cell variables (when present)
+  IF(PRESENT(i_celldata) .AND. PRESENT(p_celldata)) THEN
+    DO i_cnt = 1, i_celldata
+      CALL write_vtu_data(i_fhandle, p_celldata(i_cnt))
+    END DO
+  END IF
+
+  !> write the footer.
+  WRITE(i_fhandle, *) '</CellData>'
+  WRITE(i_fhandle, *) '</Piece>'
+  WRITE(i_fhandle, *) '</UnstructuredGrid>'
+  WRITE(i_fhandle, *) '</VTKFile>'
+
+  !> finally close the file and deallocate the data
+  CLOSE(i_fhandle)
+  DEALLOCATE(r_nodecoor, i_enodes)
+END SUBROUTINE plot_vtu_elements
+#endif !----3D output only
+
+!---------------------------------------------------------------------
+!> write_vtu_data writes a single variable (node or cell) to the
+!! VTK file.
+!> \param i_fhandle - the file handle
+!> \param p_data    - the variable
+!---------------------------------------------------------------------
+SUBROUTINE write_vtu_data(i_fhandle, p_data)
+  IMPLICIT NONE
+
+  INTEGER(KIND=GRID_SI), INTENT(IN)             :: i_fhandle
+  TYPE(t_vtu_data)                              :: p_data
+  INTEGER(KIND=GRID_SI)                         :: i_size
+  INTEGER(KIND=GRID_SI)                         :: i_cnt
+  INTEGER(KIND=GRID_SI)                         :: i_cnt2
+
+  !> Special treatment for vector valued data
+  IF(p_data%i_size > 1) THEN
+    WRITE(i_fhandle, "(A,A,A,I1, A)") &
+                '<DataArray type="Float32" Name="', &
+                TRIM(p_data%c_name), '" NumberOfComponents="', &
+                p_data%i_size, '" format="ascii">'
+  ELSE
+    WRITE(i_fhandle, "(A,A,A)") '<DataArray type="Float32" Name="', &
+                TRIM(p_data%c_name), '" format="ascii">'
+  END IF
+  i_size = SIZE(p_data%p_vdata, 2)
+
+  !> Write the data to file with respect to the threshold value
+  DO i_cnt = 1, i_size
+    DO i_cnt2 = 1, p_data%i_size
+      IF(ABS(p_data%p_vdata(i_cnt2, i_cnt)) < r_vtueps) &
+          p_data%p_vdata(i_cnt2, i_cnt) = 0
+    END DO
+
+    WRITE(i_fhandle, "(10e15.7)") p_data%p_vdata(1:p_data%i_size, i_cnt)
+  END DO
+  WRITE(i_fhandle, *) '</DataArray>'
+
+END SUBROUTINE write_vtu_data
+
+END MODULE IO_vtu
diff --git a/flash2d/src/options-sphere/IO_vtuplot_stacked.F90 b/flash2d/src/options-sphere/IO_vtuplot_stacked.F90
new file mode 100644
index 0000000000000000000000000000000000000000..aebd0d4b13537459da479355ab5f19b8f479e541
--- /dev/null
+++ b/flash2d/src/options-sphere/IO_vtuplot_stacked.F90
@@ -0,0 +1,185 @@
+!*****************************************************************
+!
+!> @file IO_vtuplot.F90
+!> @brief includes module IO_vtuplot
+!
+!*****************************************************************
+!
+! VERSION(S):
+!  1. original version                        j. behrens    04/2000
+!  2. amatos-1.0 and 2D compliant             j. behrens    11/2000
+!  3. adapted to flash2d                      j. behrens    12/2014
+!
+!*****************************************************************
+! MODULE DESCRIPTION:
+!> prints data in VTU compatible file format
+!
+MODULE IO_vtuplot
+  USE FLASH_parameters
+  USE MISC_outputdata
+  USE GRID_api
+  USE IO_vtu
+  PRIVATE
+  INTEGER, SAVE :: i_timecounter= 0
+  PUBLIC :: generate_vtu
+  CONTAINS
+
+!*****************************************************************
+! DESCRIPTION of [SUBROUTINE generate_vtu]:
+!> @brief creates output in GMV compatible file format
+!>
+!> @param[in]       p_handle      grid handle for the linked lists
+!> @param[in]       i_time        time step number
+!> @param[in]       i_newslevel   the time level
+!>
+!> @note ON OUTPUT: a number of VTU compatible ascii files for each plotted time step
+!
+  SUBROUTINE generate_vtu(p_handle, i_time, i_newslevel)
+
+    IMPLICIT NONE
+
+!---------- local declarations
+
+    TYPE (grid_handle), INTENT(in)                        :: p_handle
+    INTEGER (KIND = GRID_SI), OPTIONAL, INTENT(in)        :: i_time
+    INTEGER (KIND = GRID_SI), OPTIONAL, INTENT(in)        :: i_newslevel
+    INTEGER (KIND = GRID_SI)                              :: i_alct, i_nnum, i_tnum
+    INTEGER (KIND = GRID_SI)                              :: i_nwl, i_elen, i_tcnt
+    REAL (KIND = GRID_SR), DIMENSION(:,:), POINTER        :: r_val
+    REAL (KIND = GRID_SR), DIMENSION(:,:), POINTER        :: r_velo
+    REAL (KIND = GRID_SR), DIMENSION(:,:), POINTER        :: r_sta, r_lvl
+    INTEGER (KIND = GRID_SI), DIMENSION(:), ALLOCATABLE   :: i_ids, i_sta
+    CHARACTER (len=32)                                    :: c_mfile
+    CHARACTER (len=26)                                    :: c_tmp
+    LOGICAL                                               :: l_news
+    INTEGER, PARAMETER                                    :: i_vallen=5
+    INTEGER (KIND = GRID_SI), DIMENSION(:), ALLOCATABLE   :: i_valind
+    INTEGER (KIND = GRID_SI)                              :: i_trcvals, i_lay, i_nodnum
+
+    TYPE(t_vtu_data), DIMENSION(2)                        :: celldata
+    ! CAUTION: This is a fixed dimension, but will only work for max 16 layers...
+    TYPE(t_vtu_data), DIMENSION(20)                        :: nodedata
+    
+!---------- file handling (open)
+
+    IF(present(i_time)) THEN
+      i_tcnt= i_time
+      i_timecounter= i_timecounter+1
+    ELSE
+      i_tcnt= i_timecounter
+      i_timecounter= i_timecounter+1
+    END IF
+    write(c_tmp,*) trim(GRID_parameters%program_name(1:20))
+    write(c_mfile,10101) trim(c_tmp), '_', i_tcnt
+    c_tmp = adjustl(c_mfile)
+    write(c_mfile,*) TRIM(c_tmp), '.vtu'
+    c_mfile= adjustl(c_mfile)
+
+!---------- handle news level
+
+    IF(present(i_newslevel)) THEN
+      l_news=.TRUE.
+      i_nwl= i_newslevel
+    ELSE
+      l_news=.FALSE.
+    END IF
+
+!---------- the nodes
+
+    i_nnum = p_handle%i_nnumber
+    
+!---------- determine number of tracer values from layers and allocate accordingly
+
+    i_trcvals = i_vallen + i_stcnumlayers
+
+!---------- extract nodal grid data and nodal values
+
+	ALLOCATE(r_val(i_trcvals, i_nnum), i_valind(i_trcvals), stat=i_alct)
+	IF(i_alct /= 0) THEN
+	  CALL grid_error(c_error='[generate_vtu]: could not allocate values array')
+	END IF
+	i_valind= (/GRID_ucomp, GRID_vcomp, GRID_phi, GRID_zeta, GRID_tracer, &
+	           ((i_stctracer-1+i_lay), i_lay=1,i_stcnumlayers) /)
+	CALL grid_getinfo(p_handle, r_nodevalues= r_val, i_arraypoint=i_valind)
+
+!---------- assign nodal values, but before allocate aux. arrays
+
+    ALLOCATE(r_velo(2,i_nnum), stat=i_alct)
+	IF(i_alct /= 0) THEN
+	  CALL grid_error(c_error='[generate_vtu]: could not allocate aux. velo arrays')
+	END IF
+
+!---------- generate 2D velocity field
+
+    nodedata(1)%c_name = 'u-comp'
+    nodedata(1)%i_size = 1
+    nodedata(1)%p_vdata => r_val(1:1,:)
+
+    nodedata(2)%c_name = 'v-comp'
+    nodedata(2)%i_size = 1
+    nodedata(2)%p_vdata => r_val(2:2,:)
+
+    nodedata(3)%c_name = 'height'
+    nodedata(3)%i_size = 1
+    nodedata(3)%p_vdata => r_val(3:3,:)
+
+    nodedata(4)%c_name = 'vorticity'
+    nodedata(4)%i_size = 1
+    nodedata(4)%p_vdata => r_val(4:4,:)
+
+    nodedata(5)%c_name = 'tracer'
+    nodedata(5)%i_size = 1
+    nodedata(5)%p_vdata => r_val(5:5,:)
+
+!---------- loop over all layers and store them in separate tracer layers...
+
+    DO i_lay=1,i_stcnumlayers
+      write(c_tmp,*) 'layer',i_lay
+      nodedata(i_lay+5)%c_name = c_tmp
+      nodedata(i_lay+5)%i_size = 1
+      nodedata(i_lay+5)%p_vdata => r_val(i_lay+5:i_lay+5,:)
+    END DO
+    i_nodnum= i_stcnumlayers+ 4
+
+!---------- extract cells grid data
+
+	i_tnum= p_handle%i_enumfine
+	ALLOCATE(i_ids(i_tnum), i_sta(i_tnum), r_sta(1,i_tnum), r_lvl(1,i_tnum), stat=i_alct)
+	IF(i_alct /= 0) THEN
+	  CALL grid_error(c_error='[generate_vtu]: could not allocate cell value arrays')
+	END IF
+	IF(l_news) THEN
+	  CALL grid_getinfo(p_handle, i_newsdepth= i_nwl, i_elength= i_elen, &
+	    i_elementlevel= i_ids, i_elementstatus= i_sta)
+	  i_tnum= i_elen
+	ELSE
+	  CALL grid_getinfo(p_handle, i_elementlevel= i_ids, i_elementstatus= i_sta)
+	END IF
+
+    r_sta(1, :) = REAL(i_sta, GRID_SR)
+    r_lvl(1, :) = REAL(i_ids, GRID_SR)
+
+    ! Assign all values to driver
+    celldata(1)%c_name = 'status'
+    celldata(1)%i_size = 1
+    celldata(1)%p_vdata => r_sta
+
+    celldata(2)%c_name = 'level'
+    celldata(2)%i_size = 1
+    celldata(2)%p_vdata => r_lvl
+    
+    ! plot the vtu data
+    CALL plot_vtu(p_handle, c_mfile, i_nodedata = i_nodnum, p_nodedata = nodedata, &
+                  i_celldata = 2, p_celldata = celldata) !, i_zcoordinate = 4)
+
+    DEALLOCATE(i_ids, i_sta, r_sta, r_lvl, &
+               r_val, r_velo)
+
+    RETURN
+
+!---------- FORMAT
+ 10101    FORMAT(a19,a1,i6.6)
+
+  END SUBROUTINE generate_vtu
+
+END MODULE IO_vtuplot
diff --git a/flash2d/src/options-sphere/SLM_advanced_stacked.f90 b/flash2d/src/options-sphere/SLM_advanced_stacked.f90
new file mode 100644
index 0000000000000000000000000000000000000000..b0e7ae57923e9950c7d85c5f5027c75a780cf20d
--- /dev/null
+++ b/flash2d/src/options-sphere/SLM_advanced_stacked.f90
@@ -0,0 +1,525 @@
+!*****************************************************************
+!
+! MODULE NAME:
+!    SLM_advanced
+! FUNCTION:
+!    provide simple semi-Lagrangian routines
+! CONTAINS:
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_step
+! FUNCTION:
+!    one step of the basic SLM algorithm
+! SYNTAX:
+!    CALL slm_step(int, real.arr, real.arr)
+! ON INPUT:
+!    ...
+! ON OUTPUT:
+!    r_tracer: array with tracer values    real
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_displace
+! FUNCTION:
+!    extrapolate the alpha, values for the displacements of the upstream
+!    points from the gridpoints
+! SYNTAX:
+!    CALL slm_displace(int, real.arr, real.arr)
+! ON INPUT:
+!    i_arlen: array length for the real arrays    integer
+!    r_coord: real array of xy-coordinates        real
+! ON OUTPUT:
+!    r_alpha: displacement vectors to each point    real
+! CALLS:
+!    wind_field
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_update
+! FUNCTION:
+!    calculate the update to the velocity
+! SYNTAX:
+!    CALL slm_update(int, real.arr, real.arr)
+! ON INPUT:
+!    i_arlen: array length for the real arrays    integer
+!    r_rside: array with right hand side values    real
+! ON OUTPUT:
+!    r_udate: array with new (updated) gid values    real
+! CALLS:
+!
+! COMMENTS:
+!    this routine is trivial for linear advection
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_upstream
+! FUNCTION:
+!    calculate right hand side of the equation (upstream values)
+! SYNTAX:
+!    CALL slm_upstream(int, real.arr, real.arr)
+! ON INPUT:
+!    i_arlen: array length for the real arrays    integer
+!    r_alpha: displacement vectors to each point    real
+! ON OUTPUT:
+!    r_rside: array with right hand side values    real
+! CALLS:
+!
+! COMMENTS:
+!    this routine is just interpolation for linear advection
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_interpolate
+! FUNCTION:
+!    do the interpolation
+! SYNTAX:
+!    CALL slm_interpolate(grid, int, real, real.arr, real.arr, real.arr)
+! ON INPUT:
+!    p_ogrid: grid handle to old grid (with data)    TYPE (grid_handle)
+!    r_fac:   factor at which point to interpolate    REAL
+!    i_arlen: array length for the following arrays    INTEGER
+!    r_coord: coordinate array (new grid)        REAL
+!    r_alpha: displacement array (corr. to r_coord)    REAL
+!    r_value: values on the old grid (array)        REAL
+! ON OUTPUT:
+!    r_rside: right hand side (interpolated)        REAL
+! CALLS:
+!
+! COMMENTS:
+!    this one is plain bi-cubic spline interpolation
+!
+!-----------------------------------------------------------------
+!
+! PUBLIC:
+!    slm_step
+! COMMENTS:
+!
+! USES:
+!    FLASH_parameters, GRID_api, ADV_wind, ADV_rhs
+! LIBRARIES:
+!
+! REFERENCES:
+!
+! VERSION(S):
+!    1. original version        j. behrens    4/2002
+!    2. compliant to amatos 2.0    j. behrens    7/2003
+!
+!*****************************************************************
+    MODULE SLM_advanced
+      USE FLASH_parameters
+      USE MISC_timing
+      USE GRID_api
+      USE ADV_wind
+      USE ADV_rhs
+      PRIVATE
+      PUBLIC  :: slm_astep, slm_averticalstep
+      CONTAINS
+
+!*****************************************************************
+      SUBROUTINE slm_astep(p_ghand, p_param, p_time, r_modtime, i_size, &
+                           r_coord, r_tracer, i_newsdepth, i_layer)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps), INTENT(in) :: p_ghand
+      TYPE (control_struct), INTENT(in)                         :: p_param
+      TYPE (sw_info), INTENT(inout)                             :: p_time
+      REAL (KIND = GRID_SR), INTENT(in)                         :: r_modtime
+      INTEGER (KIND = GRID_SI), INTENT(in)                      :: i_size
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_size), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(i_size), INTENT(out)     :: r_tracer
+      INTEGER (KIND = GRID_SI), OPTIONAL, INTENT(in)            :: i_newsdepth
+      INTEGER (KIND = GRID_SI), OPTIONAL, INTENT(in)            :: i_layer
+      
+      REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE          :: r_newvl
+      REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE        :: r_alpha
+      INTEGER (KIND = GRID_SI)                                  :: i_alct, i_layerid
+
+!---------- evaluate layer information, if given
+
+      layer_info: IF(present(i_layer)) THEN
+        i_layerid = i_layer
+      ELSE layer_info
+        i_layerid = 1  ! Default is the lower layer (layer 1)
+      END IF layer_info
+
+!---------- check size!
+
+      IF(i_size <= 0) THEN
+        IF(GRID_parameters%iolog > 0) &
+          write(GRID_parameters%iolog,*) 'INFO [slm_step]: Zero step size, returning to calling routine'
+        RETURN
+      END IF
+
+!---------- allocate auxiliary arrays
+
+      allocate(r_newvl(i_size), r_alpha(GRID_dimension,i_size), stat=i_alct)
+      not_alloc: IF(i_alct /= 0) THEN
+        CALL grid_error(38)
+      END IF not_alloc
+
+!-SLM--------- calculate trajectory pieces (displacements)
+
+      CALL stop_watch('start',3,p_time)
+      CALL slm_displace(p_param, i_size, i_layerid, r_coord, r_alpha, r_time=r_modtime)
+      CALL stop_watch('stop ',3,p_time)
+
+!-SLM--------- calculate right hand side
+
+      CALL stop_watch('start',4,p_time)
+      CALL slm_upstream(p_ghand, i_size, i_layerid, r_coord, r_alpha, r_newvl)
+      CALL stop_watch('stop ',4,p_time)
+
+!-SLM--------- calculate new grid values
+
+      CALL stop_watch('start',5,p_time)
+      CALL slm_update(p_param, i_size, i_layerid, r_coord, r_newvl, r_tracer, r_time=r_modtime)
+      CALL stop_watch('stop ',5,p_time)
+
+!-SLM--------- put alpha values to u and v field entries
+
+!       r_alpha= -r_alpha
+!       IF(present(i_newsdepth)) THEN
+!         CALL grid_putinfo(p_ghand(i_timeplus), r_nodevalues=r_alpha, &
+!                     i_newsdepth=i_newsdepth, i_arraypoint=(/ GRID_ucomp, GRID_vcomp /))
+!       ELSE
+!         CALL grid_putinfo(p_ghand(i_timeplus), r_nodevalues=r_alpha, &
+!                     i_arraypoint=(/ GRID_ucomp, GRID_vcomp /))
+!       END IF
+
+!-SLM--------- deallocate work arrays
+
+      deallocate(r_alpha, r_newvl)
+
+      RETURN
+      END SUBROUTINE slm_astep
+
+!*****************************************************************
+      SUBROUTINE slm_averticalstep(p_ghand, p_param, p_time, r_modtime, i_size, &
+                           r_coord, r_tracer, i_newsdepth)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps), INTENT(in) :: p_ghand
+      TYPE (control_struct), INTENT(in)                         :: p_param
+      TYPE (sw_info), INTENT(inout)                             :: p_time
+      REAL (KIND = GRID_SR), INTENT(in)                         :: r_modtime
+      INTEGER (KIND = GRID_SI), INTENT(in)                      :: i_size
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_size), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(:,:), INTENT(inout)      :: r_tracer
+      INTEGER (KIND = GRID_SI), OPTIONAL, INTENT(in)            :: i_newsdepth
+      
+      REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE          :: r_newvl
+      REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE        :: r_alpha
+      INTEGER (KIND = GRID_SI)                                  :: i_alct, i_layerid
+
+      REAL (KIND = GRID_SR)                                     :: r_upstr, r_dd
+      INTEGER (KIND = GRID_SI)                                  :: i_cnt, i_lyr, &
+        i_lcnt
+
+!---------- allocate intermediate storage for the new tracer values
+
+      allocate(r_newvl(i_stcnumlayers), stat=i_alct)
+      not_alloc: IF(i_alct /= 0) THEN
+        CALL grid_error(c_error='[slm_verticalstep]: could not allocate r_newvl')
+      END IF not_alloc
+      
+!---------- outer loop over all coordinates
+      coord_loop: DO i_cnt=1,i_size
+
+!---------- inner loop over height levels
+        layer_loop: DO i_lyr=1,i_stcnumlayers
+
+!---------- an explicit Euler step for the upwind position
+          r_upstr = r_stclayerpressure(i_lyr) - p_param%num%r_deltatime* &
+                    slm_vertwind(r_coord(:,i_cnt),i_lyr)
+
+!---------- upstream value interpolation (linear)
+!           Step 1: check for boundary
+!                   upstream position is higher than highest layer
+          bound_check: IF(r_upstr <= r_stclayerpressure(i_stcnumlayers)) THEN
+            r_newvl(i_lyr) = 0._GRID_SR
+!                   upstream position is lower than ground layer
+          ELSE IF(r_upstr > r_stclayerpressure(1)) THEN bound_check
+            r_newvl(i_lyr) = 0._GRID_SR
+!                   upstream position is within vertical domain
+          ELSE bound_check
+!           Step 2: interpolate upstream position - use linear interpolation
+!                   find vertical box of upstream position
+            layer_search: DO i_lcnt=1,i_stcnumlayers-1
+              IF((r_upstr <= r_stclayerpressure(i_lcnt)) .AND. &
+                 (r_upstr >  r_stclayerpressure(i_lcnt+1))) THEN
+                i_layerid = i_lcnt
+                EXIT layer_search
+              END IF
+            END DO layer_search
+!                   now the linear interpolation
+            r_dd = (r_tracer(i_layerid+1, i_cnt)- r_tracer(i_layerid, i_cnt))/ &
+                   (r_stclayerpressure(i_layerid+1)- r_stclayerpressure(i_layerid))
+            r_newvl(i_lyr) = r_tracer(i_layerid,i_cnt) + r_dd* &
+                            (r_upstr - r_stclayerpressure(i_layerid))
+          END IF bound_check
+
+!---------- finally, the update with a possible right hand side
+          r_newvl(i_lyr) = r_newvl(i_lyr) + p_param%num%r_deltatime* &
+                           slm_verticalrhs(r_coord(:,i_cnt),i_lyr,r_modtime)
+        END DO layer_loop
+
+!---------- overwrite the tracer values with the newly computed advected values in this column
+        r_tracer(:,i_cnt) = r_newvl(:)
+
+      END DO coord_loop
+
+!---------- deallocate intermediate storage
+
+      deallocate(r_newvl)
+
+      RETURN
+      END SUBROUTINE slm_averticalstep
+
+!*****************************************************************
+      SUBROUTINE slm_displace(p_param, i_arlen, i_layerid, r_coord, r_alpha, r_time)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (control_struct), INTENT(in)                                     :: p_param
+      INTEGER (KIND = GRID_SI), INTENT(in)                                  :: i_arlen
+      INTEGER (KIND = GRID_SI), INTENT(in)                                  :: i_layerid
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in)  :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(out) :: r_alpha
+      REAL (KIND = GRID_SR), INTENT(in), OPTIONAL                           :: r_time
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)                      :: r_fac, r_caf, &
+        r_axy, r_xyc, r_sxy
+      REAL (KIND = GRID_SR)                                                 :: r_dt0, r_dt1, &
+        r_dt2, r_tim
+      INTEGER (KIND = GRID_SI)                                              :: i_cnt1, i_cnt2
+          
+!---------- set constants
+ 
+       r_dt0= p_param%num%r_deltatime
+      r_dt1= 0.5* p_param%num%r_deltatime
+      r_dt2= 1.5* p_param%num%r_deltatime
+      r_fac= 0.5
+      r_caf= 2.0
+      IF(present(r_time)) THEN
+        r_tim= r_time
+      ELSE
+        r_tim= 0.0
+      END IF
+
+!---------- calculate in an iteration process the displacements
+
+      unknown_loop: DO i_cnt1=1,i_arlen
+        r_axy= 0.0
+
+        iter_loop: DO i_cnt2=1, p_param%num%i_adviterations
+          r_xyc= r_coord(:,i_cnt1)- r_fac* r_axy
+          r_sxy= r_dt0* slm_windfield(r_xyc, i_layerid, r_time=r_tim)
+          r_axy= sphere_correct(r_coord(:,i_cnt1),r_sxy)
+        END DO iter_loop
+
+        r_alpha(:,i_cnt1)= r_axy
+      END DO unknown_loop
+
+      RETURN
+      END SUBROUTINE slm_displace
+
+!*****************************************************************
+      SUBROUTINE slm_update(p_param, i_arlen, i_layer, r_coord, r_rside, r_udate, r_time)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (control_struct), INTENT(in)                                    :: p_param
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_arlen
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_layer
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(i_arlen), INTENT(in)                :: r_rside
+      REAL (KIND = GRID_SR), DIMENSION(i_arlen), INTENT(out)               :: r_udate
+      REAL (KIND = GRID_SR), INTENT(in), OPTIONAL                          :: r_time
+
+      INTEGER (KIND = GRID_SI)                                             :: i_cnt
+      REAL (KIND = GRID_SR)                                                :: r_dt, r_tim
+
+!---------- in the linear advection case and with f90 this is just
+
+!      r_udate= r_rside
+
+!---------- including a non-zero right hand side, we have
+
+      r_dt= p_param%num%r_deltatime
+      IF(present(r_time)) THEN
+        r_tim= r_time
+      ELSE
+        r_tim= 0.0
+      END IF
+
+      main_loop: DO i_cnt=1, i_arlen
+        r_udate(i_cnt)= r_rside(i_cnt)+ r_dt* slm_righthand(r_coord(:,i_cnt), i_layer)
+      END DO main_loop
+
+      RETURN
+      END SUBROUTINE slm_update
+
+!*****************************************************************
+      SUBROUTINE slm_upstream(p_mesh, i_arlen, i_layer, r_coord, &
+                              r_alpha, r_rside)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps)                        :: p_mesh
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_arlen
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_layer
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_alpha
+      REAL (KIND = GRID_SR), DIMENSION(i_arlen), INTENT(out)               :: r_rside
+      
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)                     :: r_fac
+
+!---------- set factor (at which point of trajectory shall i interpolate)
+
+      r_fac= 1.0
+
+!---------- in the linear advection case this is just interpolation
+
+      CALL slm_interpolate(p_mesh, r_fac, i_arlen, i_layer, r_coord, &
+                           r_alpha, r_rside)
+
+      RETURN
+      END SUBROUTINE slm_upstream
+!*****************************************************************
+      SUBROUTINE slm_interpolate(p_mesh, r_fac, i_arlen, i_layer, &
+                                 r_coord, r_alpha, r_rside)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps)                        :: p_mesh
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension), INTENT(in)         :: r_fac
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_arlen
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_layer
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_alpha
+      REAL (KIND = GRID_SR), DIMENSION(i_arlen), INTENT(out)               :: r_rside
+
+      REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE                   :: r_upstr
+      REAL (KIND = GRID_SR)                                                :: r_eps
+      INTEGER (KIND = GRID_SI)                                             :: i_cnt, &
+        i_alct, i_val, i_out, i_stat
+
+!---------- initialize constant
+
+      i_val= i_stctracer-1+i_layer
+      r_eps= GRID_EPS
+
+!---------- allocate work array
+
+      ALLOCATE(r_upstr(GRID_dimension,i_arlen), stat=i_alct)
+      not_allocated: IF(i_alct /= 0) THEN
+        CALL grid_error(60)
+      END IF not_allocated
+
+!---------- calculate upstream coordinates
+
+      dim_loop: DO i_cnt=1, GRID_dimension
+        r_upstr(i_cnt,:) = r_coord(i_cnt,:)- r_fac(i_cnt)* r_alpha(i_cnt,:)
+      END DO dim_loop
+
+!---------- loop over nodes: find element containing upstream point
+
+      node_loop: DO i_cnt=1, i_arlen
+
+!---------- check if upstream value is outside of the domain
+
+        i_out= grid_domaincheck(p_mesh(i_time), r_upstr(:,i_cnt))
+
+!---------- take the intersection of the trajectory with the boundary as new upstream point
+
+        out_domain: IF(i_out /= 0) then
+          r_upstr(:,i_cnt)= grid_boundintersect(p_mesh(i_time), &
+                            r_coord(:,i_cnt), r_upstr(:,i_cnt), i_info=i_stat)
+          no_intersect: IF(i_stat /= 0) THEN
+            r_rside(i_cnt)= 0.0
+            CYCLE node_loop
+          END IF no_intersect
+        END IF out_domain
+
+!---------- interpolate
+
+        r_rside(i_cnt)= grid_coordvalue(p_mesh(i_time), r_upstr(:,i_cnt), &
+                        i_interpolorder=GRID_loworder, i_valpoint=i_val)
+        small_val: IF(abs(r_rside(i_cnt)) < r_eps) THEN
+          r_rside(i_cnt)= 0.0
+        END IF small_val
+
+      END DO node_loop
+
+!---------- deallocate work array
+
+      DEALLOCATE(r_upstr)
+
+      RETURN
+      END SUBROUTINE slm_interpolate
+
+!*****************************************************************
+      FUNCTION sphere_correct(r_coord, r_displ) RESULT (r_corct)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension) :: r_coord, r_displ
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension) :: r_corct
+
+      REAL (KIND = GRID_SR)                            :: r_e, r_rat
+      REAL (KIND = GRID_SR)                            :: r_c
+
+!---------- calculate Euklidean norm
+
+      r_e  = eukl_norm(r_displ)
+      r_rat= r_e/ GRID_RADIUS
+
+!---------- calculate correction
+
+      r_c  = tan(r_rat)/r_rat
+      r_corct= r_displ* r_c
+
+      RETURN
+      END FUNCTION sphere_correct
+
+!*****************************************************************
+      FUNCTION eukl_norm(r_vec) RESULT(r_rst)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension) :: r_vec
+      REAL (KIND = GRID_SR)                            :: r_rst, r_tmp
+
+!---------- calculate vector crossproduct, 3D only
+
+      r_tmp= dot_product(r_vec, r_vec)
+      r_rst= sqrt(r_tmp)
+
+      END FUNCTION eukl_norm
+
+    END MODULE SLM_advanced
diff --git a/flash2d/src/options-sphere/SLM_errorestimate_stacked.f90 b/flash2d/src/options-sphere/SLM_errorestimate_stacked.f90
new file mode 100644
index 0000000000000000000000000000000000000000..49740b135d819ca59f34ee42e35f903202969537
--- /dev/null
+++ b/flash2d/src/options-sphere/SLM_errorestimate_stacked.f90
@@ -0,0 +1,154 @@
+!*****************************************************************
+!
+! MODULE NAME:
+!	SLM_errorestimate
+! FUNCTION:
+!	provide an error estimator for the adaptive SLM scheme
+! CONTAINS:
+!-----------------------------------------------------------------
+!
+! NAME:
+!	slm_error
+! FUNCTION:
+!	estimate the error elementwise
+! SYNTAX:
+!	real= slm_error(real.arr)
+! ON INPUT:
+!	r_v:       values at element nodes	REAL
+! ON OUTPUT:
+!	r_esterr:  estimated error		REAL
+! CALLS:
+!
+! COMMENTS:
+!	this is only a simple estimator based on local gradients
+!-----------------------------------------------------------------
+!
+! NAME:
+!	slm_errorest
+! FUNCTION:
+!	this hides the loop structure from the advection part
+! SYNTAX:
+!	CALL slm_errorest(grid, int, real.arr)
+! ON INPUT:
+!	p_ghand: handle for the grid		TYPE (grid_handle)
+!	i_siz:   size of array for local errors	INTEGER
+! ON OUTPUT:
+!	i_siz:   size of array for local errors	INTEGER
+!	r_arr:   estimated error		REAL
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! PUBLIC:
+!	slm_errorest
+! COMMENTS:
+!
+! USES:
+!	MISC_globalparam, MISC_error, GRID_api
+! LIBRARIES:
+!
+! REFERENCES:
+!
+! VERSION(S):
+!	1. original version		j. behrens	11/96
+!	2. nodal values time depend.	j. behrens	1/97
+!	3. FEM_handle added		j. behrens	7/97
+!	4. version with hashing		j. behrens	7/97
+!	5. changed to use GRID_api	j. behrens	11/97
+!	6. compliant to amatos 1.0	j. behrens	12/2000
+!	7. compliant to amatos 1.2	j. behrens	3/2002
+!       8. compliant to amatos 2.0      f. klaschka     8/2006
+!
+!*****************************************************************
+	MODULE SLM_errorestimate
+	  USE FLASH_parameters
+	  USE GRID_api
+	  PRIVATE
+	  PUBLIC :: slm_errorest
+	  CONTAINS
+!*****************************************************************
+	  FUNCTION slm_error(r_v) RESULT (r_esterr)
+
+!---------- local declarations
+
+	  IMPLICIT NONE
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_elementnodes) :: r_v
+	  REAL (KIND = GRID_SR)                               :: r_esterr
+	  REAL (KIND = GRID_SR), PARAMETER                    :: r_1o3= (1.0/3.0)
+	  REAL (KIND = GRID_SR)                               :: r_d1, r_d2, r_d3
+
+!---------- calculate differences
+
+	  r_d1  =  abs(r_v(1)- r_v(2))
+	  r_d2  =  abs(r_v(2)- r_v(3))
+	  r_d3  =  abs(r_v(3)- r_v(1))
+
+!---------- this is the estimated error
+
+	  r_esterr= (r_d1+ r_d2+ r_d3)* r_1o3
+
+	  RETURN
+	  END FUNCTION slm_error
+
+!*****************************************************************
+	  SUBROUTINE slm_errorest(p_ghand, i_siz, r_arr)
+
+!---------- local declarations
+
+	  IMPLICIT NONE
+	  TYPE (grid_handle), INTENT(in)  :: p_ghand
+	  INTEGER, INTENT(in)             :: i_siz
+	  REAL (KIND = GRID_SR), DIMENSION(:), INTENT(out)    :: r_arr
+	  REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE  :: r_aux
+	  INTEGER, DIMENSION(:,:), ALLOCATABLE                :: i_enods
+	  INTEGER                         :: i_cnt, i_size, i_alct, i_nnum, i_lay, i_start
+	  INTEGER, DIMENSION(1)           :: i_valind
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_elementnodes) :: r_tmp
+
+!---------- allocate auxilliary array
+
+	  i_size= p_ghand%i_enumfine
+	  i_nnum= p_ghand%i_nnumber
+	  IF(i_siz /= i_size) THEN
+	    CALL grid_error(48)
+	  END IF
+
+	  ALLOCATE(r_aux(1,i_nnum), &
+	           i_enods(GRID_elementnodes,i_size), stat= i_alct)
+	  IF(i_alct /= 0) THEN
+	    CALL grid_error(49)
+	  END IF
+
+!---------- initialize r_arr, since we want to sum over all layers
+
+      r_arr= 0._GRID_SR
+
+!---------- loop over stacked layers
+
+      i_start = i_stctracer - 1
+      layer_loop: DO i_lay=1,i_stcnumlayers
+      
+!---------- get values
+
+	    i_valind= (/ i_start + i_lay /)
+	    CALL grid_getinfo(p_ghand, l_finelevel= .TRUE., i_arraypoint=i_valind, &
+	                      r_nodevalues= r_aux, i_elementnodes=i_enods)
+
+!---------- loop through all elements of finest loop
+
+	    elmt_loop: DO i_cnt=1,i_siz
+	      r_tmp(1:GRID_elementnodes)= r_aux(1,i_enods(1:GRID_elementnodes,i_cnt))
+	      r_arr(i_cnt)= r_arr(i_cnt) + slm_error(r_tmp)
+	    END DO elmt_loop
+	  END DO layer_loop
+
+!---------- deallocate and exit
+
+	  DEALLOCATE(r_aux, i_enods)
+
+	  RETURN
+	  END SUBROUTINE slm_errorest
+
+	END MODULE SLM_errorestimate
diff --git a/flash2d/src/options-sphere/SLM_initial_stacked.f90 b/flash2d/src/options-sphere/SLM_initial_stacked.f90
new file mode 100644
index 0000000000000000000000000000000000000000..566891c478d0c376e57a509f012daaca217486bb
--- /dev/null
+++ b/flash2d/src/options-sphere/SLM_initial_stacked.f90
@@ -0,0 +1,360 @@
+!*****************************************************************
+!
+! MODULE NAME:
+!	SLM_initial
+! FUNCTION:
+!	initialize slotted cylinder for semi-Lagrangian advection
+! CONTAINS:
+!-----------------------------------------------------------------
+!
+! NAME:
+!	slm_initialvalues
+! FUNCTION:
+!	initialize a grid with values
+! SYNTAX:
+!	CALL slm_initialvalues(grid)
+! ON INPUT:
+!	p_ghand: grid handle			TYPE (grid_handle)
+! ON OUTPUT:
+!	p_ghand: grid handle			TYPE (grid_handle)
+! CALLS:
+!
+! COMMENTS:
+!	the routine is made for two dimensions only
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!	slm_initslot
+! FUNCTION:
+!	initialize a grid with values of slotted cylinder test case
+! SYNTAX:
+!	CALL slm_initslot(grid)
+! ON INPUT:
+!	p_ghand: grid handle			TYPE (grid_handle)
+! ON OUTPUT:
+!	p_ghand: grid handle			TYPE (grid_handle)
+! CALLS:
+!
+! COMMENTS:
+!	the routine is made for two dimensions only
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!	slm_analyticsolution
+! FUNCTION:
+!	calculates the 'analytic solution' to compare with in diagnostics
+! SYNTAX:
+!	CALL slm_analyticsolution(grid, real, int, real.arr)
+! ON INPUT:
+!	p_ghand: grid handle			TYPE (grid_handle)
+!	r_time:  model time			REAL
+!	i_arlen: array length for values array	INTEGER
+! ON OUTPUT:
+!	r_array: values at gridpoints		REAL
+! CALLS:
+!
+! COMMENTS:
+!	the routine is made for two dimensions only
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!	slm_initcylndr
+! FUNCTION:
+!	initialize a grid with values of a cylinder test case
+! SYNTAX:
+!	CALL slm_initcylndr(grid)
+! ON INPUT:
+!	p_ghand: grid handle			TYPE (grid_handle)
+!	r_centr: coordinates of cyl. centre	REAL
+! ON OUTPUT:
+!	p_ghand: grid handle			TYPE (grid_handle)
+! CALLS:
+!
+! COMMENTS:
+!	the routine is made for two dimensions only
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!	in_side
+! FUNCTION:
+!	checks, if a given point (x,y) lies within a given triangle
+! SYNTAX:
+!	logical= in_side(real.arr, real.arr, real.arr, real.arr)
+! ON INPUT:
+!	r_coord: coordinate array		REAL
+!	r_node1: node1 of triangle		REAL
+!	r_node2: node2 of triangle		REAL
+!	r_node3: node3 of triangle		REAL
+! ON OUTPUT:
+!	l_in:    .true. if r_coord \in p_elem	logical
+! CALLS:
+!
+! COMMENTS:
+!	this routine decides whether a point lies in or out of a
+!	triangle. this is done with the following approach:
+!	calculate the area for the given triangle and for the 
+!	three triangles resulting from drawing lines from the given
+!	point to all three triangle nodes.
+!	if the sum of the areas of those three trianlges exceeds
+!	the area of the given trianlge, the the point lies outside
+!	of it.
+!	for calculation of the areas following formula is used:
+!	(Herons formula(?))
+!
+!	A = sqrt(s* (s- a)* (s- b)* (s- c)),
+!
+!	where s= 1/2* (a+ b+ c)
+!	      a, b, c sides.
+!
+!	in order to calculate the sidelengths |x-y|= sqrt(x**2-y**2)
+!	the complex absolute value intrinsic function is used.
+!	hopefully this fuction is faster than using sqrt and
+!	power-of-two instead.
+!
+!	internally double precision is used in this function, because
+!	machine precision is crucial when a coordinate pair appears
+!	near the edge or corner of an element.
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!	dc_area
+! FUNCTION:
+!	calculate area of a triangle (in a plain) in double precision
+! SYNTAX:
+!	real= dc_area(real.arr, real.arr, real.arr)
+! ON INPUT:
+!	r_coord1: node1 of triangle			REAL
+!	r_coord2: node2 of triangle			REAL
+!	r_coord3: node3 of triangle			REAL
+! ON OUTPUT:
+!	r_area:   area of triangle			REAL
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! PUBLIC:
+!	slm_initialvalues, slm_analyticsolution
+! COMMENTS:
+!
+! USES:
+!	MISC_globalparam, MISC_error, GRID_api
+! LIBRARIES:
+!
+! REFERENCES:
+!
+! VERSION(S):
+!	1. original version		j. behrens	7/97
+!	2. names changed		j. behrens	7/97
+!	3. changed to use GRID_api	j. behrens	11/97
+!	4. changed interfaces		j. behrens	12/97
+!	5. compliant to amatos 1.0	j. behrens	12/2000
+!	6. compliant to amatos 1.2	j. behrens	3/2002
+!       7. compliant to amatos 2.0      f. klaschka     8/2006
+!
+!*****************************************************************
+	MODULE SLM_initial
+	  USE FLASH_parameters
+	  USE GRID_api
+	  PRIVATE
+	  PUBLIC slm_initialvalues, slm_analyticsolution
+! 	  REAL, DIMENSION(GRID_dimension) :: r_cntr=(/ -0.25, 0.0 /)
+! 	  REAL                            :: r_hgt=4.0
+! 	  REAL                            :: r_srd=0.15
+! 	  REAL                            :: r_sln=0.22
+! 	  REAL                            :: r_swd=0.06
+	  CONTAINS
+!*****************************************************************
+	  SUBROUTINE slm_initialvalues(p_ghand)
+
+!---------- local declarations
+
+	  IMPLICIT NONE
+
+	  TYPE (grid_handle), INTENT(in)             :: p_ghand
+	  INTEGER                                    :: i_lev= 6
+
+!---------- initialize some constant for the slotted cylinder
+
+	  CALL slm_initcoshill(p_ghand)
+
+	  RETURN
+	  END SUBROUTINE slm_initialvalues
+!*****************************************************************
+	  SUBROUTINE slm_analyticsolution(p_ghand, r_time, i_arlen, r_array)
+
+!---------- local declarations
+
+	  IMPLICIT NONE
+
+	  TYPE (grid_handle), INTENT(in)              :: p_ghand
+	  REAL (KIND = GRID_SR), INTENT(in)                            :: r_time
+	  INTEGER, INTENT(in)                         :: i_arlen
+	  REAL (KIND = GRID_SR), DIMENSION(i_arlen), INTENT(out)       :: r_array
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)             :: r_centr
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimspherical)          :: r_sentr=(/ 0.0, 0.0 /)
+	  REAL (KIND = GRID_SR)                                        :: r_rds, r_dpt
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)             :: r_tmp
+	  INTEGER                                                      :: i_count, i_num, i_alct
+	  REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE           :: r_coo
+
+!---------- calculate center ! CAUTION: THIS IS NOT IMPLEMENTED YET !!!
+
+	  r_centr= grid_geokart(r_sentr)
+
+!---------- allocate workspace
+
+	  i_num= p_ghand%i_nnumber
+	  ALLOCATE(r_coo(GRID_dimension,i_num), stat= i_alct)
+	  IF(i_alct /= 0) THEN
+	    CALL grid_error(55)
+	  END IF
+
+!---------- get information
+
+	  CALL grid_getinfo(p_ghand, r_nodecoordinates= r_coo)
+
+!---------- check array length
+
+	  IF(i_arlen < i_num) THEN
+	    IF(GRID_parameters%iolog > 0) THEN
+	      write(GRID_parameters%iolog,*) '[slm_analyticsolution]: Array sizes did not match, adjusting to the smaller size!'
+	    END IF
+	    i_num= i_arlen
+	  END IF
+
+!---------- loop over the nodes
+
+	  node_loop: DO i_count= 1, i_num
+	    r_array(i_count)= coshill(r_coo(:,i_count),r_centr)
+	  END DO node_loop
+
+!---------- deallocate workspace
+
+	  DEALLOCATE(r_coo)
+
+	  RETURN
+	  END SUBROUTINE slm_analyticsolution
+
+!*****************************************************************
+	  SUBROUTINE slm_initcoshill(p_ghand)
+
+!---------- local declarations
+
+	  IMPLICIT NONE
+
+	  TYPE (grid_handle), INTENT(in)                      :: p_ghand
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)    :: r_centr
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimspherical) :: r_sentr=(/ 0.0, 0.0 /)
+	  REAL (KIND = GRID_SR)                               :: r_rds, r_dpt
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)    :: r_tmp
+	  INTEGER (KIND = GRID_SI)                            :: i_count, i_num, i_alct, &
+	    i_lay, i_ind
+	  REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE  :: r_aux
+	  REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE  :: r_coo
+	  INTEGER (KIND = GRID_SI), DIMENSION(1)              :: i_valind
+
+!---------- get center
+
+	  r_centr= grid_geokart(r_sentr)
+
+!---------- allocate workspace
+
+	  i_num= p_ghand%i_nnumber
+
+	  ALLOCATE(r_aux(1,i_num), r_coo(GRID_dimension,i_num), stat= i_alct)
+	  IF(i_alct /= 0) THEN
+	    CALL grid_error(55)
+	  END IF
+
+!---------- get information
+
+	  CALL grid_getinfo(p_ghand, r_nodecoordinates= r_coo)
+
+!---------- loop over layers
+
+      layer_loop: DO i_lay= 1, i_stcnumlayers
+      
+!---------- compute radii of initial ball-type cosine hill density...
+
+!         i_ind = max(4 - abs(floor(0.5*i_stcnumlayers)-i_lay),0)
+!         r_rds = (GRID_RADIUS/ 6.0)*i_ind/4
+
+        r_aux = 0.
+        IF ((i_lay .GE. 2) .AND. (i_lay .LE. i_stcnumlayers -2)) then
+!---------- loop over the nodes
+
+	    node_loop: DO i_count= 1, i_num
+	      r_aux(1,i_count)= coshill(r_coo(:,i_count),r_centr, r_radius=r_rds)
+	    END DO node_loop
+	    END IF
+
+!---------- update grid information
+
+	    i_valind= (/ i_stctracer-1+i_lay /)
+	    CALL grid_putinfo(p_ghand, i_arraypoint=i_valind, r_nodevalues= r_aux)
+	  END DO layer_loop
+
+!---------- deallocate workspace
+
+	  DEALLOCATE(r_aux, r_coo)
+
+	  RETURN
+	  END SUBROUTINE slm_initcoshill
+
+!*****************************************************************
+	  FUNCTION coshill(r_coor, r_centr, r_radius) RESULT (r_hill)
+
+!---------- local declarations
+
+	  IMPLICIT NONE
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)    :: r_coor
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)    :: r_centr
+	  REAL (KIND = GRID_SR), OPTIONAL                     :: r_radius
+	  REAL (KIND = GRID_SR)                               :: r_hill
+	  REAL (KIND = GRID_SR)                               :: r_maxheight=1.0
+	  REAL (KIND = GRID_SR)                               :: r_maxrad
+	  REAL (KIND = GRID_SR)                               :: r_dist, r_tmp
+	  REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)    :: r_xy
+
+!---------- watch out for optional argument
+
+      opt_arg: IF(present(r_radius)) THEN
+        r_maxrad = r_radius
+      ELSE opt_arg
+!---------- initialize maximal radius with default values
+        r_maxrad= GRID_RADIUS/ 6.0
+      END IF opt_arg
+
+!---------- initialize r_hill
+
+	  r_hill= 0.0
+
+!---------- calculate distance to center
+
+	  r_xy= r_centr- r_coor
+	  r_dist= DOT_PRODUCT(r_xy,r_xy)
+
+!---------- calculate inner values
+
+	  IF(r_dist < r_maxrad) THEN
+	    r_tmp = (GRID_PI* r_dist)/r_maxrad
+	    r_hill= r_maxheight *(1.0+ cos(r_tmp))
+	  END IF
+
+	  RETURN
+	  END FUNCTION coshill
+
+!*****************************************************************
+
+	END MODULE SLM_initial
+
+
+
+
diff --git a/flash2d/src/options-sphere/SLM_simple_stacked.f90 b/flash2d/src/options-sphere/SLM_simple_stacked.f90
new file mode 100644
index 0000000000000000000000000000000000000000..4c42f69631ed3fa20badd5039a04db16040c2413
--- /dev/null
+++ b/flash2d/src/options-sphere/SLM_simple_stacked.f90
@@ -0,0 +1,539 @@
+!*****************************************************************
+!
+! MODULE NAME:
+!    SLM_simple
+! FUNCTION:
+!    provide simple semi-Lagrangian routines
+! CONTAINS:
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_step
+! FUNCTION:
+!    one step of the basic SLM algorithm
+! SYNTAX:
+!    CALL slm_step(int, real.arr, real.arr)
+! ON INPUT:
+!    ...
+! ON OUTPUT:
+!    r_tracer: array with tracer values    real
+! CALLS:
+!
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_displace
+! FUNCTION:
+!    extrapolate the alpha, values for the displacements of the upstream
+!    points from the gridpoints
+! SYNTAX:
+!    CALL slm_displace(int, real.arr, real.arr)
+! ON INPUT:
+!    i_arlen: array length for the real arrays    integer
+!    r_coord: real array of xy-coordinates        real
+! ON OUTPUT:
+!    r_alpha: displacement vectors to each point    real
+! CALLS:
+!    wind_field
+! COMMENTS:
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_update
+! FUNCTION:
+!    calculate the update to the velocity
+! SYNTAX:
+!    CALL slm_update(int, real.arr, real.arr)
+! ON INPUT:
+!    i_arlen: array length for the real arrays    integer
+!    r_rside: array with right hand side values    real
+! ON OUTPUT:
+!    r_udate: array with new (updated) gid values    real
+! CALLS:
+!
+! COMMENTS:
+!    this routine is trivial for linear advection
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_upstream
+! FUNCTION:
+!    calculate right hand side of the equation (upstream values)
+! SYNTAX:
+!    CALL slm_upstream(int, real.arr, real.arr)
+! ON INPUT:
+!    i_arlen: array length for the real arrays    integer
+!    r_alpha: displacement vectors to each point    real
+! ON OUTPUT:
+!    r_rside: array with right hand side values    real
+! CALLS:
+!
+! COMMENTS:
+!    this routine is just interpolation for linear advection
+!
+!-----------------------------------------------------------------
+!
+! NAME:
+!    slm_interpolate
+! FUNCTION:
+!    do the interpolation
+! SYNTAX:
+!    CALL slm_interpolate(grid, int, real, real.arr, real.arr, real.arr)
+! ON INPUT:
+!    p_ogrid: grid handle to old grid (with data)    TYPE (grid_handle)
+!    r_fac:   factor at which point to interpolate    REAL
+!    i_arlen: array length for the following arrays    INTEGER
+!    r_coord: coordinate array (new grid)        REAL
+!    r_alpha: displacement array (corr. to r_coord)    REAL
+!    r_value: values on the old grid (array)        REAL
+! ON OUTPUT:
+!    r_rside: right hand side (interpolated)        REAL
+! CALLS:
+!
+! COMMENTS:
+!    this one is plain bi-cubic spline interpolation
+!
+!-----------------------------------------------------------------
+!
+! PUBLIC:
+!    slm_step
+! COMMENTS:
+!
+! USES:
+!    FLASH_parameters, GRID_api, ADV_wind, ADV_rhs
+! LIBRARIES:
+!
+! REFERENCES:
+!
+! VERSION(S):
+!    1. original version        j. behrens    4/2002
+!    2. compliant to amatos 2.0    j. behrens    7/2003
+!
+!*****************************************************************
+    MODULE SLM_simple
+      USE FLASH_parameters
+      USE MISC_timing
+      USE GRID_api
+      USE ADV_wind
+      USE ADV_rhs
+      PUBLIC :: slm_step, slm_verticalstep
+      PRIVATE
+      CONTAINS
+
+!*****************************************************************
+      SUBROUTINE slm_step(p_ghand, p_param, p_time, r_modtime, i_size, &
+                           r_coord, r_tracer, i_newsdepth, i_layer)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps), INTENT(in) :: p_ghand
+      TYPE (control_struct), INTENT(in)                         :: p_param
+      TYPE (sw_info), INTENT(inout)                             :: p_time
+      REAL (KIND = GRID_SR), INTENT(in)                         :: r_modtime
+      INTEGER (KIND = GRID_SI), INTENT(in)                      :: i_size
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_size), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(i_size), INTENT(out)     :: r_tracer
+      INTEGER (KIND = GRID_SI), OPTIONAL, INTENT(in)            :: i_newsdepth
+      INTEGER (KIND = GRID_SI), OPTIONAL, INTENT(in)            :: i_layer
+      
+      REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE          :: r_newvl
+      REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE        :: r_alpha
+      INTEGER (KIND = GRID_SI)                                  :: i_alct, i_layerid, i_nd
+
+!---------- evaluate layer information, if given
+
+      layer_info: IF(present(i_layer)) THEN
+        i_layerid = i_layer
+      ELSE layer_info
+        i_layerid = 1  ! Default is the lower layer (layer 1)
+      END IF layer_info
+
+       IF(present(i_newsdepth)) THEN
+         i_nd= i_newsdepth
+       ELSE
+         i_nd= 1_GRID_SI
+       END IF
+
+!---------- check size!
+
+      IF(i_size <= 0) THEN
+        IF(GRID_parameters%iolog > 0) &
+          write(GRID_parameters%iolog,*) 'INFO [slm_step]: Zero step size, returning to calling routine'
+        RETURN
+      END IF
+
+!---------- allocate auxiliary arrays
+
+      allocate(r_newvl(i_size), r_alpha(GRID_dimension,i_size), stat=i_alct)
+      not_alloc: IF(i_alct /= 0) THEN
+        CALL grid_error(38)
+      END IF not_alloc
+
+!-SLM--------- calculate trajectory pieces (displacements)
+
+      CALL stop_watch('start',3,p_time)
+      CALL slm_displace(p_param, i_size, i_layerid, r_coord, r_alpha, r_time=r_modtime)
+      CALL stop_watch('stop ',3,p_time)
+
+!-SLM--------- calculate right hand side
+
+      CALL stop_watch('start',4,p_time)
+      CALL slm_upstream(p_ghand, i_size, i_layerid, r_coord, r_alpha, r_newvl)
+      CALL stop_watch('stop ',4,p_time)
+
+!-SLM--------- calculate new grid values
+
+      CALL stop_watch('start',5,p_time)
+      CALL slm_update(p_param, i_size, i_layerid, r_coord, r_newvl, r_tracer, r_time=r_modtime)
+      CALL stop_watch('stop ',5,p_time)
+
+!-SLM--------- put alpha values to u and v field entries
+
+      IF(i_layerid == 1) THEN
+      r_alpha= -r_alpha
+      IF(present(i_newsdepth)) THEN
+        CALL grid_putinfo(p_ghand(i_timeplus), r_nodevalues=r_alpha(1:2,:), &
+                    i_newsdepth=i_newsdepth, i_arraypoint=(/ GRID_ucomp, GRID_vcomp /))
+      ELSE
+        CALL grid_putinfo(p_ghand(i_timeplus), r_nodevalues=r_alpha(1:2,:), &
+                    i_arraypoint=(/ GRID_ucomp, GRID_vcomp /))
+      END IF
+      END IF
+
+!-SLM--------- deallocate work arrays
+
+      deallocate(r_alpha, r_newvl)
+
+      RETURN
+      END SUBROUTINE slm_step
+
+!*****************************************************************
+      SUBROUTINE slm_verticalstep(p_ghand, p_param, p_time, r_modtime, i_size, &
+                           r_coord, r_tracer, i_newsdepth)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps), INTENT(in) :: p_ghand
+      TYPE (control_struct), INTENT(in)                         :: p_param
+      TYPE (sw_info), INTENT(inout)                             :: p_time
+      REAL (KIND = GRID_SR), INTENT(in)                         :: r_modtime
+      INTEGER (KIND = GRID_SI), INTENT(in)                      :: i_size
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_size), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(:,:), INTENT(inout)      :: r_tracer
+      INTEGER (KIND = GRID_SI), OPTIONAL, INTENT(in)            :: i_newsdepth
+      
+      REAL (KIND = GRID_SR), DIMENSION(:), ALLOCATABLE          :: r_newvl
+      REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE        :: r_alpha
+      INTEGER (KIND = GRID_SI)                                  :: i_alct, i_layerid
+
+      REAL (KIND = GRID_SR)                                     :: r_upstr, r_dd
+      INTEGER (KIND = GRID_SI)                                  :: i_cnt, i_lyr, &
+        i_lcnt, i_nd
+
+!---------- allocate intermediate storage for the new tracer values
+
+       IF(present(i_newsdepth)) THEN
+         i_nd= i_newsdepth
+       ELSE
+         i_nd= 1_GRID_SI
+       END IF
+
+      allocate(r_newvl(i_stcnumlayers), stat=i_alct)
+      not_alloc: IF(i_alct /= 0) THEN
+        CALL grid_error(c_error='[slm_verticalstep]: could not allocate r_newvl')
+      END IF not_alloc
+      
+!---------- outer loop over all coordinates
+      coord_loop: DO i_cnt=1,i_size
+
+!---------- inner loop over height levels
+        layer_loop: DO i_lyr=1,i_stcnumlayers
+
+!---------- an explicit Euler step for the upwind position
+          r_upstr = r_stclayerpressure(i_lyr) - p_param%num%r_deltatime* &
+                    slm_vertwind(r_coord(:,i_cnt),i_lyr)
+
+!---------- upstream value interpolation (linear)
+!           Step 1: check for boundary
+!                   upstream position is higher than highest layer
+          bound_check: IF(r_upstr <= r_stclayerpressure(i_stcnumlayers)) THEN
+            r_newvl(i_lyr) = 0._GRID_SR
+!                   upstream position is lower than ground layer
+          ELSE IF(r_upstr > r_stclayerpressure(1)) THEN bound_check
+            r_newvl(i_lyr) = 0._GRID_SR
+!                   upstream position is within vertical domain
+          ELSE bound_check
+!           Step 2: interpolate upstream position - use linear interpolation
+!                   find vertical box of upstream position
+            layer_search: DO i_lcnt=1,i_stcnumlayers-1
+              IF((r_upstr <= r_stclayerpressure(i_lcnt)) .AND. &
+                 (r_upstr >  r_stclayerpressure(i_lcnt+1))) THEN
+                i_layerid = i_lcnt
+                EXIT layer_search
+              END IF
+            END DO layer_search
+!                   now the linear interpolation
+            r_dd = (r_tracer(i_layerid+1, i_cnt)- r_tracer(i_layerid, i_cnt))/ &
+                   (r_stclayerpressure(i_layerid+1)- r_stclayerpressure(i_layerid))
+            r_newvl(i_lyr) = r_tracer(i_layerid,i_cnt) + r_dd* &
+                            (r_upstr - r_stclayerpressure(i_layerid))
+          END IF bound_check
+
+!---------- finally, the update with a possible right hand side
+          r_newvl(i_lyr) = r_newvl(i_lyr) + p_param%num%r_deltatime* &
+                           slm_verticalrhs(r_coord(:,i_cnt),i_lyr,r_modtime)
+        END DO layer_loop
+
+!---------- overwrite the tracer values with the newly computed advected values in this column
+        r_tracer(:,i_cnt) = r_newvl(:)
+
+      END DO coord_loop
+
+!---------- deallocate intermediate storage
+
+      deallocate(r_newvl)
+
+      RETURN
+      END SUBROUTINE slm_verticalstep
+
+!*****************************************************************
+      SUBROUTINE slm_displace(p_param, i_arlen, i_layerid, r_coord, r_alpha, r_time)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (control_struct), INTENT(in)                                     :: p_param
+      INTEGER (KIND = GRID_SI), INTENT(in)                                  :: i_arlen
+      INTEGER (KIND = GRID_SI), INTENT(in)                                  :: i_layerid
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in)  :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(out) :: r_alpha
+      REAL (KIND = GRID_SR), INTENT(in), OPTIONAL                           :: r_time
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)                      :: r_fac, r_caf, &
+        r_axy, r_xyc, r_sxy
+      REAL (KIND = GRID_SR)                                                 :: r_dt0, r_dt1, &
+        r_dt2, r_tim
+      INTEGER (KIND = GRID_SI)                                              :: i_cnt1, i_cnt2
+          
+!---------- set constants
+ 
+       r_dt0= p_param%num%r_deltatime
+      r_dt1= 0.5* p_param%num%r_deltatime
+      r_dt2= 1.5* p_param%num%r_deltatime
+      r_fac= 0.5
+      r_caf= 2.0
+      IF(present(r_time)) THEN
+        r_tim= r_time
+      ELSE
+        r_tim= 0.0
+      END IF
+
+!---------- calculate in an iteration process the displacements
+
+      unknown_loop: DO i_cnt1=1,i_arlen
+        r_axy= 0.0
+
+        iter_loop: DO i_cnt2=1, p_param%num%i_adviterations
+          r_xyc= r_coord(:,i_cnt1)- r_fac* r_axy
+          r_sxy= r_dt0* slm_windfield(r_xyc, i_layerid, r_time=r_tim)
+          r_axy= sphere_correct(r_coord(:,i_cnt1),r_sxy)
+        END DO iter_loop
+
+        r_alpha(:,i_cnt1)= r_axy
+      END DO unknown_loop
+
+      RETURN
+      END SUBROUTINE slm_displace
+
+!*****************************************************************
+      SUBROUTINE slm_update(p_param, i_arlen, i_layer, r_coord, r_rside, r_udate, r_time)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (control_struct), INTENT(in)                                    :: p_param
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_arlen
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_layer
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(i_arlen), INTENT(in)                :: r_rside
+      REAL (KIND = GRID_SR), DIMENSION(i_arlen), INTENT(out)               :: r_udate
+      REAL (KIND = GRID_SR), INTENT(in), OPTIONAL                          :: r_time
+
+      INTEGER (KIND = GRID_SI)                                             :: i_cnt
+      REAL (KIND = GRID_SR)                                                :: r_dt, r_tim
+
+!---------- in the linear advection case and with f90 this is just
+
+!      r_udate= r_rside
+
+!---------- including a non-zero right hand side, we have
+
+      r_dt= p_param%num%r_deltatime
+      IF(present(r_time)) THEN
+        r_tim= r_time
+      ELSE
+        r_tim= 0.0
+      END IF
+
+      main_loop: DO i_cnt=1, i_arlen
+        r_udate(i_cnt)= r_rside(i_cnt)+ r_dt* slm_righthand(r_coord(:,i_cnt), i_layer)
+      END DO main_loop
+
+      RETURN
+      END SUBROUTINE slm_update
+
+!*****************************************************************
+      SUBROUTINE slm_upstream(p_mesh, i_arlen, i_layer, r_coord, &
+                              r_alpha, r_rside)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps)                        :: p_mesh
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_arlen
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_layer
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_alpha
+      REAL (KIND = GRID_SR), DIMENSION(i_arlen), INTENT(out)               :: r_rside
+      
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension)                     :: r_fac
+
+!---------- set factor (at which point of trajectory shall i interpolate)
+
+      r_fac= 1.0
+
+!---------- in the linear advection case this is just interpolation
+
+      CALL slm_interpolate(p_mesh, r_fac, i_arlen, i_layer, r_coord, &
+                           r_alpha, r_rside)
+
+      RETURN
+      END SUBROUTINE slm_upstream
+!*****************************************************************
+      SUBROUTINE slm_interpolate(p_mesh, r_fac, i_arlen, i_layer, &
+                                 r_coord, r_alpha, r_rside)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      TYPE (grid_handle), DIMENSION(GRID_timesteps)                        :: p_mesh
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension), INTENT(in)         :: r_fac
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_arlen
+      INTEGER (KIND = GRID_SI), INTENT(in)                                 :: i_layer
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_coord
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension,i_arlen), INTENT(in) :: r_alpha
+      REAL (KIND = GRID_SR), DIMENSION(i_arlen), INTENT(out)               :: r_rside
+
+      REAL (KIND = GRID_SR), DIMENSION(:,:), ALLOCATABLE                   :: r_upstr
+      REAL (KIND = GRID_SR)                                                :: r_eps
+      INTEGER (KIND = GRID_SI)                                             :: i_cnt, &
+        i_alct, i_val, i_out, i_stat
+
+!---------- initialize constant
+
+      i_val= i_stctracer-1+i_layer
+      r_eps= GRID_EPS
+
+!---------- allocate work array
+
+      ALLOCATE(r_upstr(GRID_dimension,i_arlen), stat=i_alct)
+      not_allocated: IF(i_alct /= 0) THEN
+        CALL grid_error(60)
+      END IF not_allocated
+
+!---------- calculate upstream coordinates
+
+      dim_loop: DO i_cnt=1, GRID_dimension
+        r_upstr(i_cnt,:) = r_coord(i_cnt,:)- r_fac(i_cnt)* r_alpha(i_cnt,:)
+      END DO dim_loop
+
+!---------- loop over nodes: find element containing upstream point
+
+      node_loop: DO i_cnt=1, i_arlen
+
+!---------- check if upstream value is outside of the domain
+
+        i_out= grid_domaincheck(p_mesh(i_time), r_upstr(:,i_cnt))
+
+!---------- take the intersection of the trajectory with the boundary as new upstream point
+
+        out_domain: IF(i_out /= 0) then
+          r_upstr(:,i_cnt)= grid_boundintersect(p_mesh(i_time), &
+                            r_coord(:,i_cnt), r_upstr(:,i_cnt), i_info=i_stat)
+          no_intersect: IF(i_stat /= 0) THEN
+            r_rside(i_cnt)= 0.0
+            CYCLE node_loop
+          END IF no_intersect
+        END IF out_domain
+
+!---------- interpolate
+
+        r_rside(i_cnt)= grid_coordvalue(p_mesh(i_time), r_upstr(:,i_cnt), &
+                        i_interpolorder=GRID_loworder, i_valpoint=i_val)
+        small_val: IF(abs(r_rside(i_cnt)) < r_eps) THEN
+          r_rside(i_cnt)= 0.0
+        END IF small_val
+
+      END DO node_loop
+
+!---------- deallocate work array
+
+      DEALLOCATE(r_upstr)
+
+      RETURN
+      END SUBROUTINE slm_interpolate
+
+!*****************************************************************
+      FUNCTION sphere_correct(r_coord, r_displ) RESULT (r_corct)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension) :: r_coord, r_displ
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension) :: r_corct
+
+      REAL (KIND = GRID_SR)                            :: r_e, r_rat
+      REAL (KIND = GRID_SR)                            :: r_c
+
+!---------- calculate Euklidean norm
+
+      r_e  = eukl_norm(r_displ)
+      r_rat= r_e/ GRID_RADIUS
+
+!---------- calculate correction
+
+      r_c  = tan(r_rat)/r_rat
+      r_corct= r_displ* r_c
+
+      RETURN
+      END FUNCTION sphere_correct
+
+!*****************************************************************
+      FUNCTION eukl_norm(r_vec) RESULT(r_rst)
+
+!---------- local declarations
+
+      IMPLICIT NONE
+      REAL (KIND = GRID_SR), DIMENSION(GRID_dimension) :: r_vec
+      REAL (KIND = GRID_SR)                            :: r_rst, r_tmp
+
+!---------- calculate vector crossproduct, 3D only
+
+      r_tmp= dot_product(r_vec, r_vec)
+      r_rst= sqrt(r_tmp)
+
+      END FUNCTION eukl_norm
+
+    END MODULE SLM_simple