diff --git a/apps/showcases/CMakeLists.txt b/apps/showcases/CMakeLists.txt
index 9aa74f6944d4663a8244ac85e79bf13e4413755f..8a5656bc85676e7b3cce7bc47bcb5e77d6f85e57 100644
--- a/apps/showcases/CMakeLists.txt
+++ b/apps/showcases/CMakeLists.txt
@@ -5,9 +5,11 @@ add_subdirectory( HeatConduction )
 add_subdirectory( LightRisingParticleInFluidAMR )
 add_subdirectory( Mixer )
 add_subdirectory( PegIntoSphereBed )
-if ( WALBERLA_BUILD_WITH_CODEGEN AND WALBERLA_BUILD_WITH_PYTHON )
-add_subdirectory( PhaseFieldAllenCahn )
-add_subdirectory( LeesEdwards )
+if ( WALBERLA_BUILD_WITH_CODEGEN )
+   if (WALBERLA_BUILD_WITH_PYTHON)
+      add_subdirectory( PhaseFieldAllenCahn )
+   endif()
+   add_subdirectory( LeesEdwards )
 endif()
 if ( WALBERLA_BUILD_WITH_CODEGEN AND NOT WALBERLA_BUILD_WITH_OPENMP)
    add_subdirectory( PorousMedia )
diff --git a/apps/showcases/LeesEdwards/LeesEdwards.cpp b/apps/showcases/LeesEdwards/LeesEdwards.cpp
index 0bbd6a94bc9ffeaabc996dd66b99424d4d55267a..169f17c0673bd2eea651642d218a2170d6ffa941 100644
--- a/apps/showcases/LeesEdwards/LeesEdwards.cpp
+++ b/apps/showcases/LeesEdwards/LeesEdwards.cpp
@@ -128,7 +128,7 @@ int main(int argc, char** argv)
       parameters.getParameter< double >("remainingTimeLoggerFrequency", 3.0); // in seconds
 
    // create fields
-   BlockDataID pdfFieldID     = field::addToStorage< PdfField_T >(blocks, "PDFs", real_t(1.0), field::fzyx);
+   BlockDataID pdfFieldID     = field::addToStorage< PdfField_T >(blocks, "PDFs", real_t(0.0), field::fzyx);
    BlockDataID velFieldID     = field::addToStorage< VectorField_T >(blocks, "velocity", real_t(0), field::fzyx);
    BlockDataID forceFieldID   = field::addToStorage< VectorField_T >(blocks, "force", real_t(0), field::fzyx);
    BlockDataID densityFieldID = field::addToStorage< ScalarField_T >(blocks, "density", real_t(1.0), field::fzyx);
@@ -149,9 +149,7 @@ int main(int argc, char** argv)
 
    // add LBM sweep and communication to time loop
    timeloop.add() << Sweep(CollisionSweep, "collision");
-   timeloop.add() << BeforeFunction(communication, "communication")
-                  << Sweep(LeesEdwardsUpdate(blocks, pdfFieldID, offset), "Lees Edwards");
-   timeloop.add() << Sweep(StreamSweep, "stream");
+   timeloop.add() << Sweep(StreamSweep, "stream") << AfterFunction(communication, "communication");
 
    // log remaining time
    timeloop.addFuncAfterTimeStep(timing::RemainingTimeLogger(timeloop.getNrOfTimeSteps(), remainingTimeLoggerFrequency),
diff --git a/apps/showcases/LeesEdwards/LeesEdwards.py b/apps/showcases/LeesEdwards/LeesEdwards.py
index ba62ac9fc02ec29ebbf27edf22f19c72abde3936..feedeea2279a90970d146e929e3cdfe7094de1a0 100644
--- a/apps/showcases/LeesEdwards/LeesEdwards.py
+++ b/apps/showcases/LeesEdwards/LeesEdwards.py
@@ -3,8 +3,9 @@ from pystencils.field import fields
 from pystencils.data_types import type_all_numbers
 from pystencils import Assignment
 
+from lbmpy import LBMConfig, LBStencil, LBMOptimisation, Stencil, Method, ForceModel
+from lbmpy.advanced_streaming.utility import get_accessor, Timestep
 from lbmpy.creationfunctions import create_lb_update_rule
-from lbmpy.stencils import get_stencil
 from lbmpy.updatekernels import create_stream_pull_with_output_kernel
 from lbmpy.macroscopic_value_kernels import macroscopic_values_setter
 from pystencils_walberla import CodeGeneration, generate_sweep, generate_info_header
@@ -12,14 +13,21 @@ from lbmpy_walberla import RefinementScaling, generate_boundary, generate_lb_pac
 
 import sympy as sp
 
+
+# For advanced streaming patterns (AA, EsoTwist) the timestep is seperated into Odd and Even steps. In each of these
+# steps a different streaming is executed. For more common two population methods this is not the case.
+# In lbmpy we indicate this with Timestep.BOTH
+streaming_pattern = "push"
+accessor = get_accessor(streaming_pattern, Timestep.BOTH)
+
 omega = 1.0  # relaxation rate of first component
 shear_velocity = 0.5  # shear velocity
 shear_dir = 0  # direction of shear flow
 shear_dir_normal = 1  # direction normal to shear plane, for interpolation
 
-stencil = get_stencil("D2Q9")
-q = len(stencil)
-dim = len(stencil[0])
+stencil = LBStencil(Stencil.D2Q9)
+q = stencil.Q
+dim = stencil.D
 
 pdfs, pdfs_tmp = fields(f"pdfs({q}), pdfs_tmp({q}): double[{dim}D]", layout='fzyx')
 velocity_field, force_field, density_field = fields(f"velocity({dim}), force({dim}), density(1) : double[{dim}D]",
@@ -33,15 +41,13 @@ u_p = sp.Piecewise((1, sp.And(type_all_numbers(counters[1] <= 0, 'int'), points_
                    (-1, sp.And(type_all_numbers(counters[1] >= 63, 'int'), points_up)),
                    (0, True)) * shear_velocity
 
-collision = create_lb_update_rule(stencil=stencil,
-                                  relaxation_rate=omega,
-                                  compressible=True,
-                                  velocity_input=velocity_field.center_vector + sp.Matrix([u_p, 0]),
-                                  density_input=density_field,
-                                  force_model='luo',
-                                  force=force_field.center_vector,
-                                  kernel_type='collide_only',
-                                  optimization={'symbolic_field': pdfs})
+lb_config = LBMConfig(stencil=stencil, method=Method.SRT, relaxation_rate=omega, compressible=True,
+                      velocity_input=velocity_field.center_vector + sp.Matrix([u_p, 0]),
+                      density_input=density_field, force_model=ForceModel.GUO,
+                      force=force_field.center_vector, kernel_type='collide_only')
+lbm_opt = LBMOptimisation(symbolic_field=pdfs)
+
+collision = create_lb_update_rule(lbm_config=lb_config, lbm_optimisation=lbm_opt)
 
 to_insert = [s.lhs for s in collision.subexpressions
              if collision.method.first_order_equilibrium_moment_symbols[shear_dir]
@@ -62,10 +68,12 @@ for a, c in zip(collision.main_assignments, collision.method.stencil):
 collision.main_assignments = ma
 
 stream = create_stream_pull_with_output_kernel(collision.method, pdfs, pdfs_tmp,
-                                               {'density': density_field, 'velocity': velocity_field})
+                                               {'density': density_field, 'velocity': velocity_field},
+                                               accessor=accessor)
 
 init = macroscopic_values_setter(collision.method, velocity=(0, 0),
-                                 pdfs=pdfs.center_vector, density=density_field.center)
+                                 pdfs=pdfs, density=density_field.center,
+                                 streaming_pattern=streaming_pattern)
 
 stencil_typedefs = {'Stencil_T': stencil}
 field_typedefs = {'PdfField_T': pdfs,
@@ -79,7 +87,7 @@ with CodeGeneration() as ctx:
     generate_sweep(ctx, 'LeesEdwards_Setter', init)
 
     # communication
-    generate_lb_pack_info(ctx, 'LeesEdwards_PackInfo', stencil, pdfs)
+    generate_lb_pack_info(ctx, 'LeesEdwards_PackInfo', stencil, pdfs, streaming_pattern=streaming_pattern)
 
     # Info header containing correct template definitions for stencil and field
     generate_info_header(ctx, 'LeesEdwards_InfoHeader',