diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 10ea70930d78ff4a0e630c72d59fd0b76bc9da7e..b40d9bf9ad662363df9a216e5889d75ba2505a13 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -43,28 +43,12 @@ testsuite-clang18:
     - cmake -G Ninja -S . -B build
     - cd build
     - cmake --build . --target SfgTests
+    - cmake --build . --target UserManualExamples
   script:
     - ctest
 
 # -------------------- User Manual ---------------------------------------------------------------------
 
-
-build-examples:
-  image: i10git.cs.fau.de:5005/walberla/buildenvs/clang-18:latest
-  tags:
-    - docker
-  stage: "Documentation"
-  needs: []
-  variables:
-    CXX: clang++
-    CC: clang
-  script:
-    - cd user_manual/examples
-    - cmake -G Ninja -S . -B build
-    - cd build
-    - cmake --build . --target Examples
-
-
 build-user-manual:
   image: i10git.cs.fau.de:5005/pycodegen/pycodegen/nox:alpine
   tags:
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index ce709453b068d38fd994f918daa68ade3083bafa..eb3cb86fe6b0bfe682d1bd9d3886d62cf42f1c64 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -27,4 +27,4 @@ include(CTest)
 add_custom_target( SfgTests )
 
 add_subdirectory( BasicLbmScenarios )
-add_subdirectory( SparseSpiral )
+add_subdirectory( ${CMAKE_SOURCE_DIR}/../user_manual/examples ${CMAKE_CURRENT_BINARY_DIR}/user-manual-examples )
diff --git a/tests/SparseSpiral/CMakeLists.txt b/tests/SparseSpiral/CMakeLists.txt
deleted file mode 100644
index 1e5977dd40907baa93070de9c36bb50406994e67..0000000000000000000000000000000000000000
--- a/tests/SparseSpiral/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-
-add_executable( SparseSpiral SparseSpiral.cpp )
-walberla_generate_sources( SparseSpiral SCRIPTS SpiralSweep.py )
-target_link_libraries( SparseSpiral PRIVATE walberla::core walberla::blockforest walberla::field walberla::vtk walberla::experimental )
-
-add_test( NAME SparseSpiral COMMAND SparseSpiral )
diff --git a/tests/SparseSpiral/SparseSpiral.cpp b/tests/SparseSpiral/SparseSpiral.cpp
deleted file mode 100644
index fe96364af00fd05478164004b1ec3a22d136c909..0000000000000000000000000000000000000000
--- a/tests/SparseSpiral/SparseSpiral.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-#include "core/all.h"
-#include "blockforest/all.h"
-#include "field/GhostLayerField.h"
-#include "field/AddToStorage.h"
-#include "field/vtk/all.h"
-#include "walberla/experimental/sweep/SparseIndexList.hpp"
-
-#include <array>
-
-#include "gen/SpiralSweep.hpp"
-
-namespace SparseSpiral
-{
-    using namespace walberla;
-    using namespace walberla::experimental;
-
-    using std::array;
-    using std::vector;
-
-    using PointField = field::GhostLayerField<real_t, 3>;
-
-    constexpr real_t radius { 15.0 };
-    constexpr Vector3< real_t > center { 20, 20, 0 };
-    constexpr real_t height { 120. };
-    constexpr real_t width { 4.0 };
-
-    Vector3<real_t> pointOnSpiral(real_t z)
-    {
-        real_t t{4.0 * math::pi * z / height};
-        return center + Vector3<real_t>{radius * cos(t), radius * sin(t), z};
-    }
-
-    void main(int argc, char **argv)
-    {
-        Environment env{ argc, argv };
-
-        AABB domainAabb{0., 0., 0., 40., 40., height };
-        array<uint_t, 3> gridSize{4, 4, 12};
-        array<uint_t, 3> cpb{10, 10, 10};
-
-        auto blocks = blockforest::createUniformBlockGrid(
-            domainAabb,
-            gridSize[0], gridSize[1], gridSize[2],
-            cpb[0], cpb[1], cpb[2]);
-
-        BlockDataID fID = field::addToStorage<PointField>(blocks, "f", real_c(0.0), field::fzyx);
-        sweep::SparseIndexList indexList{*blocks};
-
-        auto isOnSpiral = [&](Cell globalCell) -> bool
-        {
-            Vector3<real_t> globalPoint{blocks->getCellCenter(globalCell)};
-            Vector3<real_t> spiralPoint{pointOnSpiral(globalPoint[2])};
-            return (globalPoint - spiralPoint).sqrLength() < width;
-        };
-
-        CellInterval allCells{{0, 0, 0}, {cell_idx_c(cpb[0]), cell_idx_c(cpb[1]), cell_idx_c(cpb[2])}};
-
-        for (auto &b : *blocks)
-        {
-            auto & idxVec{indexList.getVector(b)};
-            for (Cell c : allCells)
-            {
-                Cell globalCell{c};
-                blocks->transformBlockLocalToGlobalCell(globalCell, b);
-                if (isOnSpiral(globalCell))
-                {
-                    idxVec.emplace_back(c);
-                }
-            }
-        }
-
-        gen::SpiralSweep sweep{blocks, fID, indexList};
-
-        for (auto &b : *blocks)
-        {
-            sweep(&b);
-        }
-
-        for (auto &b : *blocks)
-        {
-            PointField & f = *b.getData<PointField>(fID);
-            for (Cell c : allCells)
-            {
-                Cell globalCell{c};
-                blocks->transformBlockLocalToGlobalCell(globalCell, b);
-                if (isOnSpiral(c))
-                {
-                    Vector3< real_t > cellCenter { blocks->getCellCenter(globalCell) };
-                    WALBERLA_CHECK_FLOAT_EQUAL(f.get(c, 0), cellCenter[0]);
-                    WALBERLA_CHECK_FLOAT_EQUAL(f.get(c, 1), cellCenter[1]);
-                    WALBERLA_CHECK_FLOAT_EQUAL(f.get(c, 2), cellCenter[2]);
-                }
-            }
-        }
-
-        auto vtkWriter = field::createVTKOutput< PointField >(fID, *blocks, "f", 1, 0);
-        vtkWriter();
-    }
-}
-
-int main(int argc, char **argv)
-{
-    SparseSpiral::main(argc, argv);
-    return 0;
-}
diff --git a/tests/SparseSpiral/SpiralSweep.py b/tests/SparseSpiral/SpiralSweep.py
deleted file mode 100644
index 4fd59bd19a737b1b01e7473bc9343fa8e8022b16..0000000000000000000000000000000000000000
--- a/tests/SparseSpiral/SpiralSweep.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from pystencilssfg import SourceFileGenerator
-from walberla.codegen import Sweep
-from walberla.codegen.symbolic import cell
-from pystencils import fields, Assignment, CreateKernelConfig, Target
-
-with SourceFileGenerator() as sfg:
-    sfg.namespace("SparseSpiral::gen")
-    f = fields("f(3): double[3D]", layout="fzyx")
-
-    asms = [
-        Assignment(f.center(0), cell.x()),
-        Assignment(f.center(1), cell.y()),
-        Assignment(f.center(2), cell.z()),
-    ]
-
-    cfg = CreateKernelConfig(target=Target.GenericCPU)
-
-    sweep = Sweep("SpiralSweep", asms, cfg)
-    sweep.sparse = True
-
-    sfg.generate(sweep)
diff --git a/user_manual/Makefile b/user_manual/Makefile
index a25a0fb5753254bcfe5f61266a6b7655c85f6ce0..ec67ed3544df5866aae9e15474d3d17011b4dd64 100644
--- a/user_manual/Makefile
+++ b/user_manual/Makefile
@@ -9,7 +9,8 @@ SOURCEDIR     = .
 BUILDDIR      = _sphinx_build
 
 ZIPPED_EXAMPLES := zipped-examples
-EXAMPLES_DIR := examples
+ZIPPED_EXAMPLES_ABS := $(shell realpath $(ZIPPED_EXAMPLES))
+EXAMPLES_DIR := $(shell realpath examples)
 
 include examples.mk
 
@@ -32,9 +33,9 @@ clean:
 	@rm -rf $(ZIPPED_EXAMPLES)
 	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
-ZipExamples: $(foreach example, $(EXAMPLES), $(ZIPPED_EXAMPLES)/$(example).zip)
+ZipExamples: $(foreach example, $(EXAMPLES), $(ZIPPED_EXAMPLES_ABS)/$(example).zip)
 
-$(ZIPPED_EXAMPLES)/%.zip: $(EXAMPLES_DIR)/%/*
+$(ZIPPED_EXAMPLES_ABS)/%.zip: $(EXAMPLES_DIR)/%/*
 	@$(dir_guard)
 	@echo Zipping $(<D)
-	@zip -r $@ $(<D)
+	@cd $(EXAMPLES_DIR); zip -r $@ $(notdir $(<D))
diff --git a/user_manual/examples.mk b/user_manual/examples.mk
index 4ab97ae0510e8b4cebe7a5b73de8313a6a88447b..cdefaef69bbb6f843d952d303d74e12a8b646e45 100644
--- a/user_manual/examples.mk
+++ b/user_manual/examples.mk
@@ -1 +1 @@
-EXAMPLES = GeneratorScriptBasics SparseSpiral ForceDrivenChannel
+EXAMPLES = GeneratorScriptBasics ForceDrivenChannel SparseSpiral
diff --git a/user_manual/examples/CMakeLists.txt b/user_manual/examples/CMakeLists.txt
index 2f19f387483abcbec59bd001091250c3932ff1dc..79972aaf20c471ad55fa0fb7c1fa3ab0a4a8b4cc 100644
--- a/user_manual/examples/CMakeLists.txt
+++ b/user_manual/examples/CMakeLists.txt
@@ -1,29 +1,11 @@
-cmake_minimum_required( VERSION 3.24 )
-project( walberla-codegen-examples )
-
-set(CMAKE_CXX_STANDARD 20)
-set(CMAKE_CXX_STANDARD_REQUIRED)
-
-include(FetchContent)
-
-FetchContent_Declare(
-    walberla
-    GIT_REPOSITORY https://i10git.cs.fau.de/walberla/walberla.git
-)
-
-message( STATUS "Fetching waLBerla sources (this might take a while)..." )
-FetchContent_MakeAvailable(walberla)
-
-add_subdirectory(${CMAKE_SOURCE_DIR}/../.. ${CMAKE_BINARY_DIR}/sfg-walberla)
-
 add_subdirectory( GeneratorScriptBasics )
 add_subdirectory( ForceDrivenChannel )
 add_subdirectory( SparseSpiral )
 add_subdirectory( FreeSlipBubble )
 
-add_custom_target( Examples )
+add_custom_target( UserManualExamples )
 add_dependencies( 
-    Examples
+    UserManualExamples
     Ex_GeneratorScriptBasics
     Ex_ForceDrivenChannel
     SparseSpiral
diff --git a/user_manual/examples/SparseSpiral/CMakeLists.txt b/user_manual/examples/SparseSpiral/CMakeLists.txt
index e5698a1b3448ea13c2dcc8a640952489147c0a95..1e5977dd40907baa93070de9c36bb50406994e67 100644
--- a/user_manual/examples/SparseSpiral/CMakeLists.txt
+++ b/user_manual/examples/SparseSpiral/CMakeLists.txt
@@ -3,3 +3,4 @@ add_executable( SparseSpiral SparseSpiral.cpp )
 walberla_generate_sources( SparseSpiral SCRIPTS SpiralSweep.py )
 target_link_libraries( SparseSpiral PRIVATE walberla::core walberla::blockforest walberla::field walberla::vtk walberla::experimental )
 
+add_test( NAME SparseSpiral COMMAND SparseSpiral )
diff --git a/user_manual/examples/SparseSpiral/SparseSpiral.cpp b/user_manual/examples/SparseSpiral/SparseSpiral.cpp
index 7f3704e7cff1bed9e2d4d87eb9a9d9ddb9a0ee00..fe96364af00fd05478164004b1ec3a22d136c909 100644
--- a/user_manual/examples/SparseSpiral/SparseSpiral.cpp
+++ b/user_manual/examples/SparseSpiral/SparseSpiral.cpp
@@ -57,7 +57,7 @@ namespace SparseSpiral
 
         for (auto &b : *blocks)
         {
-            auto & idxVec{indexList.get(b)};
+            auto & idxVec{indexList.getVector(b)};
             for (Cell c : allCells)
             {
                 Cell globalCell{c};
diff --git a/user_manual/examples/SparseSpiral/SpiralSweep.py b/user_manual/examples/SparseSpiral/SpiralSweep.py
index 41747b4207ca98ed59d99bb704e3b55bf2ce5575..4fd59bd19a737b1b01e7473bc9343fa8e8022b16 100644
--- a/user_manual/examples/SparseSpiral/SpiralSweep.py
+++ b/user_manual/examples/SparseSpiral/SpiralSweep.py
@@ -1,7 +1,7 @@
 from pystencilssfg import SourceFileGenerator
 from walberla.codegen import Sweep
 from walberla.codegen.symbolic import cell
-from pystencils import fields, Assignment
+from pystencils import fields, Assignment, CreateKernelConfig, Target
 
 with SourceFileGenerator() as sfg:
     sfg.namespace("SparseSpiral::gen")
@@ -13,8 +13,9 @@ with SourceFileGenerator() as sfg:
         Assignment(f.center(2), cell.z()),
     ]
 
-    sweep = Sweep("SpiralSweep", asms)
+    cfg = CreateKernelConfig(target=Target.GenericCPU)
+
+    sweep = Sweep("SpiralSweep", asms, cfg)
     sweep.sparse = True
 
     sfg.generate(sweep)
-
diff --git a/user_manual/guides/SparseSweeps.md b/user_manual/guides/SparseSweeps.md
index f3188d538119efba844d3480d61c29b9755dff50..f0de79f777d87a5692f3136186158e45aee4e7b7 100644
--- a/user_manual/guides/SparseSweeps.md
+++ b/user_manual/guides/SparseSweeps.md
@@ -29,9 +29,9 @@ WaLBerla provides the `SparseIndexList` class for this.
 The following code sample creates and populates an index list, using a predicate here called `isOnSpiral`.
 The index list's internal block data ID must then be passed to the sweep's constructor.
 
-:::{literalinclude} ../examples/SparseSpiral/SparseSpiral.cpp
+```{literalinclude} ../examples/SparseSpiral/SparseSpiral.cpp
 :caption: SparseSpiral.cpp
 :lines: 46,56-72
 :dedent: 8
 :language: C++
-:::
+```