diff --git a/lib/walberla/experimental/sweep/Sweeper.hpp b/lib/walberla/experimental/sweep/Sweeper.hpp
index bfc7be2941ed3ef19fc5be047af3f23d612552bc..051c53107e5ad3e308647241929afa4316926cad 100644
--- a/lib/walberla/experimental/sweep/Sweeper.hpp
+++ b/lib/walberla/experimental/sweep/Sweeper.hpp
@@ -40,6 +40,14 @@ class SerialSweeper
             for (uint_t x = 0; x < blocks_->getNumberOfXCellsPerBlock(); ++x)
                func({ x, y, z });
    }
+
+   void forAllCells(const CellInterval& ci, std::function< void(Cell) > func)
+   {
+      for (uint_t z = ci.zMin(); z <= ci.zMax(); ++z)
+         for (uint_t y = ci.yMin(); y <= ci.yMax(); ++y)
+            for (uint_t x = ci.xMin(); x <= ci.xMax(); ++x)
+               func({ x, y, z });
+   }
 };
 
 } // namespace walberla::experimental::sweep
diff --git a/src/walberla/codegen/build_config.py b/src/walberla/codegen/build_config.py
index e9048cdfb5a3f38344601126fdb64d61c591a313..434512f8d413ce99c0881ac5e67125b8b3b20b7a 100644
--- a/src/walberla/codegen/build_config.py
+++ b/src/walberla/codegen/build_config.py
@@ -108,6 +108,20 @@ def get_build_config(sfg: SfgContext | SfgIComposer):
 class DEBUG_MOCK_CMAKE:
     BUILD_CONFIG: WalberlaBuildConfig | None = None
 
+    @staticmethod
+    def use_cpu_default():
+        DEBUG_MOCK_CMAKE.BUILD_CONFIG = WalberlaBuildConfig(
+            c_compiler_id="GNU",
+            cxx_compiler_id="GNU",
+            use_double_precision=True,
+            optimize_for_localhost=False,
+            mpi_enabled=False,
+            openmp_enabled=False,
+            hip_enabled=False,
+            cuda_enabled=False,
+            likwid_enabled=False,
+        )
+
     @staticmethod
     def use_hip_default():
         DEBUG_MOCK_CMAKE.BUILD_CONFIG = WalberlaBuildConfig(
diff --git a/src/walberla/codegen/sweep.py b/src/walberla/codegen/sweep.py
index 195218f5835525099164125583e59a7e7d00be3e..b445039adf734b265268260b1df4428ccf6d2ddb 100644
--- a/src/walberla/codegen/sweep.py
+++ b/src/walberla/codegen/sweep.py
@@ -1,6 +1,6 @@
 from __future__ import annotations
 
-from typing import Sequence, Iterable, cast
+from typing import Sequence, Iterable, cast, Callable
 from dataclasses import dataclass
 from itertools import chain
 from collections import defaultdict
@@ -167,12 +167,12 @@ class BlockforestParameters:
         self,
         property_cache: SweepClassProperties,
         block: IBlockPtr,
-        cell_interval: CellInterval | None = None,
     ):
         self._property_cache = property_cache
         self._block = block
-        self._ci = cell_interval
-        self._extractions: dict[SfgVar, AugExpr] = dict()
+        self._extractions: dict[
+            SfgVar, AugExpr | Callable[[CellInterval | None], AugExpr]
+        ] = dict()
 
         self._blockforest: StructuredBlockForest | None = None
 
@@ -214,8 +214,18 @@ class BlockforestParameters:
 
         params_filtered = set()
 
-        mappings: dict[str, AugExpr] = dict()
+        mappings: dict[str, AugExpr | Callable[[CellInterval | None], AugExpr]] = dict()
         for coord in range(3):
+
+            #   Need to capture coord explicitly
+            #   See https://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture
+
+            def ci_min(ci: CellInterval | None, c=coord) -> AugExpr:
+                return AugExpr.format("0") if ci is None else ci.min()[c]
+
+            def ci_max(ci: CellInterval | None, c=coord) -> AugExpr:
+                return AugExpr.format("0") if ci is None else ci.max()[c]
+
             mappings.update(
                 {
                     domain.aabb_min[coord].name: (
@@ -240,16 +250,8 @@ class BlockforestParameters:
                     ),
                     block.aabb_min[coord].name: (self._block.getAABB().min()[coord]),
                     block.aabb_max[coord].name: (self._block.getAABB().max()[coord]),
-                    block.ci_min[coord].name: (
-                        AugExpr.format("0")
-                        if self._ci is None
-                        else self._ci.min()[coord]
-                    ),
-                    block.ci_max[coord].name: (
-                        AugExpr.format("0")
-                        if self._ci is None
-                        else self._ci.max()[coord]
-                    ),
+                    block.ci_min[coord].name: ci_min,
+                    block.ci_max[coord].name: ci_max,
                     block_cell_bb.cell_bb_min[coord].name: (
                         self.blockforest()
                         .getBlockCellBB(self._block.deref())
@@ -276,8 +278,11 @@ class BlockforestParameters:
 
         return params_filtered
 
-    def render_extractions(self, sfg: SfgComposer):
-        return (sfg.init(p)(expr) for p, expr in self._extractions.items())
+    def render_extractions(self, sfg: SfgComposer, ci: CellInterval | None):
+        return (
+            sfg.init(p)(expr if isinstance(expr, AugExpr) else expr(ci))
+            for p, expr in self._extractions.items()
+        )
 
 
 @dataclass
@@ -650,7 +655,7 @@ class Sweep(CustomGenerator):
 
         parameters = khandle.scalar_parameters | ker_call_site_params
 
-        blockforest_params = BlockforestParameters(props, block, None)
+        blockforest_params = BlockforestParameters(props, block)
         parameters = blockforest_params.filter_params(parameters)
 
         vector_groups = combine_vectors(parameters)
@@ -692,7 +697,7 @@ class Sweep(CustomGenerator):
                     for vector, components in vector_groups.items()
                 ),
                 #   Extract geometry information
-                *(blockforest_params.render_extractions(sfg)),
+                *(blockforest_params.render_extractions(sfg, ci)),
                 #   Invoke the kernel
                 ker_invocation,
                 #   Perform field swaps
diff --git a/tests/CodegenFeatures/CMakeLists.txt b/tests/CodegenFeatures/CMakeLists.txt
index 6a4f622036ebd9595ba589565a8e1948197ec88f..a559c85b0627e587702914df41406b86528be1b0 100644
--- a/tests/CodegenFeatures/CMakeLists.txt
+++ b/tests/CodegenFeatures/CMakeLists.txt
@@ -3,4 +3,6 @@ add_executable( TestBlockforestGeometry TestBlockforestGeometry.cpp )
 walberla_generate_sources( TestBlockforestGeometry SCRIPTS GeometryKernels.py )
 target_link_libraries( TestBlockforestGeometry PRIVATE walberla::core walberla::blockforest walberla::field walberla::experimental )
 
+add_dependencies( SfgTests TestBlockforestGeometry )
+
 add_test( NAME TestBlockforestGeometry COMMAND TestBlockforestGeometry )
diff --git a/tests/CodegenFeatures/GeometryKernels.py b/tests/CodegenFeatures/GeometryKernels.py
index 98078d81547d952f85df2d91f4cc4b8115a0fe9f..3bd67068fc0039c3b4e465cdb7d2aea60601c271 100644
--- a/tests/CodegenFeatures/GeometryKernels.py
+++ b/tests/CodegenFeatures/GeometryKernels.py
@@ -1,8 +1,10 @@
 import pystencils as ps
 from pystencilssfg import SourceFileGenerator
 from walberla.codegen import Sweep, get_build_config
+from walberla.codegen.build_config import DEBUG_MOCK_CMAKE
 from walberla.codegen.symbolic import cell, cell_index
 
+DEBUG_MOCK_CMAKE.use_cpu_default()
 
 with SourceFileGenerator() as sfg:
     get_build_config(sfg).override.target = ps.Target.GenericCPU
@@ -53,4 +55,3 @@ with SourceFileGenerator() as sfg:
 
     sweep = Sweep("CellIndicesGlobal", asms)
     sfg.generate(sweep)
-
diff --git a/tests/CodegenFeatures/TestBlockforestGeometry.cpp b/tests/CodegenFeatures/TestBlockforestGeometry.cpp
index 610c588ce09dd196cd46e1888eb67c38e37bc75e..410648b094301cb4fd97ee2c99163f42fbf25347 100644
--- a/tests/CodegenFeatures/TestBlockforestGeometry.cpp
+++ b/tests/CodegenFeatures/TestBlockforestGeometry.cpp
@@ -88,5 +88,73 @@ int main(int argc, char** argv)
       });
    }
 
+   /* The same with cell intervals */
+
+   CellInterval ci { Cell {1, 2, 1}, Cell (3, 3, 2) };
+
+   {
+      CellCentersGlobal cellCenters{ blocks, realFieldId };
+      sweeper.sweep([&](IBlock * b){ cellCenters.runOnCellInterval(b, ci); });
+
+      sweeper.sweep([&](IBlock& block) {
+         RealField& outp = *block.getData< RealField >(realFieldId);
+         sweeper.forAllCells(ci, [&](Cell c) {
+            Vector3< real_t > desired = blocks->getBlockLocalCellCenter(block, c);
+
+            WALBERLA_CHECK_FLOAT_EQUAL(outp.get(c, 0), desired[0]);
+            WALBERLA_CHECK_FLOAT_EQUAL(outp.get(c, 1), desired[1]);
+            WALBERLA_CHECK_FLOAT_EQUAL(outp.get(c, 2), desired[2]);
+         });
+      });
+   }
+
+   {
+      CellCentersLocal cellCenters{ blocks, realFieldId };
+      sweeper.sweep([&](IBlock * b){ cellCenters.runOnCellInterval(b, ci); });
+
+      sweeper.sweep([&](IBlock& block) {
+         RealField& outp = *block.getData< RealField >(realFieldId);
+         AABB blockAbb = block.getAABB();
+         sweeper.forAllCells(ci, [&](Cell c) {
+            Vector3< real_t > desired = blocks->getBlockLocalCellCenter(block, c) - blockAbb.min();
+
+            WALBERLA_CHECK_FLOAT_EQUAL(outp.get(c, 0), desired[0]);
+            WALBERLA_CHECK_FLOAT_EQUAL(outp.get(c, 1), desired[1]);
+            WALBERLA_CHECK_FLOAT_EQUAL(outp.get(c, 2), desired[2]);
+         });
+      });
+   }
+
+   {
+    CellIndicesLocal localIndices{ blocks, intFieldId };
+      sweeper.sweep([&](IBlock * b){ localIndices.runOnCellInterval(b, ci); });
+
+      sweeper.sweep([&](IBlock& block) {
+         Int64Field& outp = *block.getData< Int64Field >(intFieldId);
+         sweeper.forAllCells(ci, [&](Cell c) {
+            WALBERLA_CHECK_EQUAL(outp.get(c, 0), c[0]);
+            WALBERLA_CHECK_EQUAL(outp.get(c, 1), c[1]);
+            WALBERLA_CHECK_EQUAL(outp.get(c, 2), c[2]);
+         });
+      });
+   }
+
+   {
+    CellIndicesGlobal glocalIndices{ blocks, intFieldId };
+    sweeper.sweep([&](IBlock * b){ glocalIndices.runOnCellInterval(b, ci); });
+
+      sweeper.sweep([&](IBlock& block) {
+         Int64Field& outp = *block.getData< Int64Field >(intFieldId);
+         sweeper.forAllCells(ci, [&](Cell c) {
+            Cell globalCell{ c };
+            blocks->transformBlockLocalToGlobalCell(globalCell, block);
+
+            WALBERLA_CHECK_EQUAL(outp.get(c, 0), globalCell[0]);
+            WALBERLA_CHECK_EQUAL(outp.get(c, 1), globalCell[1]);
+            WALBERLA_CHECK_EQUAL(outp.get(c, 2), globalCell[2]);
+         });
+      });
+   }
+
    return EXIT_SUCCESS;
 }
\ No newline at end of file