diff --git a/tests/BasicLbmScenarios/SimDomain.hpp b/tests/BasicLbmScenarios/SimDomain.hpp
index 6d28c5f4c184d48b27c639df5e0486e20c4e2c3a..228a89de594aa256f306017211e399a4f702638e 100644
--- a/tests/BasicLbmScenarios/SimDomain.hpp
+++ b/tests/BasicLbmScenarios/SimDomain.hpp
@@ -7,6 +7,10 @@
 #include "field/all.h"
 #include "field/communication/StencilRestrictedPackInfo.h"
 
+#include "walberla/experimental/Sweep.hpp"
+
+#include "stencil/Directions.h"
+
 #include <memory>
 
 #include "gen/LbmAlgorithms.hpp"
@@ -26,6 +30,7 @@ namespace BasicLbmScenarios
 {
 
 using namespace walberla;
+using namespace walberla::experimental;
 
 using PdfField_T    = field::GhostLayerField< real_t, gen::LbStencil::Q >;
 using ScalarField_T = field::GhostLayerField< real_t, 1 >;
@@ -96,6 +101,16 @@ struct SimDomain
       return { gpuFields.pdfsId, gpuFields.rhoId, gpuFields.uId, force, omega };
    }
 
+   auto
+   freeSlipBottom() {
+      return sweep::BorderSweep< stencil::Direction::B, gen::bc_grid_aligned::FreeSlipBottom > { blocks, gen::bc_grid_aligned::FreeSlipBottom { gpuFields.pdfsId }, 0 };
+   }
+
+   auto
+   noSlipTop() {
+      return sweep::BorderSweep< stencil::Direction::T, gen::bc_grid_aligned::NoSlipTop > { blocks, gen::bc_grid_aligned::NoSlipTop { gpuFields.pdfsId }, -1 };
+   }
+
    void wait() { WALBERLA_GPU_CHECK(gpuDeviceSynchronize()); }
 
    void syncGhostLayers()
diff --git a/tests/BasicLbmScenarios/TestBasicLbmScenarios.cpp b/tests/BasicLbmScenarios/TestBasicLbmScenarios.cpp
index afc303b7f446459a13a062d221761c5a469b1178..656df20763f1d8116b444a8be47b39d38202df0a 100644
--- a/tests/BasicLbmScenarios/TestBasicLbmScenarios.cpp
+++ b/tests/BasicLbmScenarios/TestBasicLbmScenarios.cpp
@@ -59,14 +59,17 @@ void fullyPeriodic(Environment& env)
 void mirroredHalfChannel(Environment& env)
 {
    size_t zCells { 64 };
+   /**
+    * Need one more cell in z-direction for the free-slip boundary to be on the inner layer
+    */
    SimDomain dom{ SimDomainBuilder{
-      .blocks = { 1, 1, 1 }, .cellsPerBlock = { 4, 4, zCells }, .periodic = { true, true, false } }
+      .blocks = { 1, 1, 1 }, .cellsPerBlock = { 4, 4, zCells + 1 }, .periodic = { true, true, false } }
                      .build() };
 
    /* Hagen-Poiseuille-law in lattice units */
    const real_t u_max{ 0.025 };
    const real_t reynolds{ 10.0 };
-   const real_t L_z{ 2 * zCells };
+   const real_t L_z{ real_c( 2 * zCells ) };
    const real_t radius { L_z / 2.0 };
    const real_t r_squared { radius * radius };
    const real_t lattice_viscosity{ L_z * u_max / reynolds };
@@ -99,9 +102,36 @@ void mirroredHalfChannel(Environment& env)
    dom.fields2device();
    dom.initFromFields(force);
 
-   // TODO: Get collision and boundary sweeps
-   // Set up boundary sweeps on the lower and upper ghost layers
-   // Run 10 time steps and make sure the flow stays in steady-state
+   auto streamCollide = dom.streamCollideSweep(omega, force);
+   auto noSlipTop = dom.noSlipTop();
+   auto freeSlipBottom = dom.freeSlipBottom();
+
+   for (uint_t t = 0; t < 10; ++t)
+   {
+      dom.forAllBlocks([&](IBlock& b) { streamCollide(&b); });
+      dom.syncGhostLayers();
+
+      dom.fields2host();
+
+      dom.forAllBlocks([&](auto& block) {
+         const VectorField_T& velField = *block.template getData< VectorField_T >(dom.cpuFields.uId);
+
+         dom.forAllCells([&](Cell c) {
+            Cell globalCell{ c };
+            dom.blocks->transformBlockLocalToGlobalCell(globalCell, block);
+            Vector3< real_t > cellCenter{ dom.blocks->getCellCenter(globalCell) };
+
+            real_t expected{ velocityProfile(cellCenter[2]) };
+            real_t actual{ velField.get(c, 0) };
+            WALBERLA_CHECK_FLOAT_EQUAL(expected, actual);
+         });
+      });
+
+      dom.forAllBlocks([&](IBlock& b) {
+         noSlipTop(&b);
+         freeSlipBottom(&b);
+      });
+   }
 }
 
 /**
@@ -217,6 +247,7 @@ int main(int argc, char** argv)
 {
    walberla::Environment env{ argc, argv };
    BasicLbmScenarios::fullyPeriodic(env);
+   BasicLbmScenarios::mirroredHalfChannel(env);
 #if !defined(LBM_SCENARIOS_GPU_BUILD)
    BasicLbmScenarios::freeSlipPipe(env);
 #endif
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e821381298cce90bc9d1afb7160be741af57d367..0c98d01393c421c02262dd50034b065ada593d16 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -6,6 +6,9 @@ set(WALBERLA_BUILD_BENCHMARKS OFF CACHE BOOL "")
 set(WALBERLA_BUILD_SHOWCASES OFF CACHE BOOL "")
 set(WALBERLA_BUILD_TUTORIALS OFF CACHE BOOL "")
 
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED)
+
 include(FetchContent)
 
 FetchContent_Declare(