diff --git a/apps/benchmarks/TurbulentChannel/TurbulentChannelCodeGen.py b/apps/benchmarks/TurbulentChannel/TurbulentChannelCodeGen.py
index 6dfa5f4de9eac3534db969e1e828a8f404ec1dac..001e5bdfbf1f44a8d70ad37b0c33276930a43348 100644
--- a/apps/benchmarks/TurbulentChannel/TurbulentChannelCodeGen.py
+++ b/apps/benchmarks/TurbulentChannel/TurbulentChannelCodeGen.py
@@ -1,8 +1,8 @@
 import pystencils as ps
-from lbmpy.boundaries import NoSlip
+
+from lbmpy import LBMConfig, LBMOptimisation, LBStencil, Method, Stencil
 from lbmpy.creationfunctions import create_lb_collision_rule
 from lbmpy.macroscopic_value_kernels import macroscopic_values_setter, macroscopic_values_getter
-from lbmpy.stencils import get_stencil
 
 from pystencils_walberla import CodeGeneration, generate_sweep
 from lbmpy_walberla import generate_lattice_model, RefinementScaling, generate_boundary
@@ -11,9 +11,11 @@ from lbmpy_walberla import generate_boundary, generate_lb_pack_info
 import sympy as sp
 
 with CodeGeneration() as ctx:
-    stencil = get_stencil("D3Q27")
-    q = len(stencil)
-    dim = len(stencil[0])
+    data_type = "float64" if ctx.double_accuracy else "float32"
+
+    stencil = LBStencil(Stencil.D3Q27)
+    q = stencil.Q
+    dim = stencil.D
 
     omega = sp.Symbol("omega")
     smago = sp.Symbol("smago")
@@ -21,25 +23,17 @@ with CodeGeneration() as ctx:
     # fzyx equals an SOA Data layout. Thus SIMD vectorisation is much more efficient usually. It is recommended.
     pdfs = ps.fields(f"pdfs({q}): double[{dim}D]", layout='fzyx')
 
-    velocity_field, density_field, force_field = ps.fields(f"velocity({dim}), density(1), force({dim}): double[{dim}D]",
-                                                           layout='fzyx')
-
-    openmp = False
-    optimization1 = {'cse_global': True, "cse_pdfs": False, 'split': False, 'double_precision': True}
-    cpu_vec = {'instruction_set': 'avx', 'nontemporal': True, 'assume_aligned': False}
+    velocity_field, force_field = ps.fields(f"velocity({dim}), force({dim}): {data_type}[{dim}D]", layout='fzyx')
+    density_field = ps.fields(f"density(1): {data_type}[{dim}D]", layout='fzyx')
 
     # galilean correction is only available for D3Q27 stencils.
-    # cumulants use an implicit force model which does not have to be stated directly.
-    # TODO the bulk viskosity is not consider here... we should think about that
-    method_params = {'method': 'cumulant',
-                     'stencil': 'D3Q27',
-                     'relaxation_rate': omega,
-                     'force': (force_field.center, 0.0, 0.0),
-                     'galilean_correction': True,
-                     'field_name': 'pdfs',
-                     'optimization': optimization1}
-
-    collision_rule = create_lb_collision_rule(**method_params)
+    # cumulants use an implicit force model which does not have to be stated directly
+    lbm_config = LBMConfig(method=Method.CUMULANT, stencil=stencil, relaxation_rate=omega,
+                           force=(force_field.center, 0, 0), galilean_correction=True, field_name='pdfs')
+
+    lbm_opt = LBMOptimisation(cse_global=True, cse_pdfs=False, split=False)
+
+    collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt)
     lb_method = collision_rule.method
 
     setter_assignments = macroscopic_values_setter(lb_method, velocity=velocity_field.center_vector,
@@ -52,9 +46,12 @@ with CodeGeneration() as ctx:
     scaling1.add_standard_relaxation_rate_scaling([omega])
     scaling1.add_force_scaling(force_field)
 
+    cpu_vec = None  # {'instruction_set': 'avx', 'nontemporal': True, 'assume_aligned': False}
+
     # generate components
     generate_lattice_model(ctx, 'TurbulentChannelLatticeModel', collision_rule, field_layout='fzyx',
-                           refinement_scaling=scaling1)
+                           refinement_scaling=scaling1, target=ps.Target.CPU, data_type=data_type,
+                           cpu_openmp=False, cpu_vectorize_info=cpu_vec)
 
     # TODO the initialisation of the PDF field is done via poiseuille and/or with random
     #  perturbation of the velocity field. Maybe the setter and getter from lbmpy can be used in the future.
@@ -62,4 +59,5 @@ with CodeGeneration() as ctx:
     # generate_sweep(ctx, 'TurbulentChannelMacroGetter', getter_assignments, target='cpu')
 
     # communication
-    generate_lb_pack_info(ctx, 'TurbulentChannel_PackInfo', stencil, pdfs, target='cpu')
+    generate_lb_pack_info(ctx, 'TurbulentChannel_PackInfo', stencil, pdfs, target=ps.Target.CPU,
+                          data_type=data_type, cpu_openmp=False)
diff --git a/apps/benchmarks/TurbulentChannel/sources/Checkpointing.h b/apps/benchmarks/TurbulentChannel/sources/Checkpointing.h
index 9d590a4a6967cca118fbffad70ff51d997c20d48..3f3e9ad8edd8a471ff92de2b0c3f3f0bc8c01552 100644
--- a/apps/benchmarks/TurbulentChannel/sources/Checkpointing.h
+++ b/apps/benchmarks/TurbulentChannel/sources/Checkpointing.h
@@ -66,9 +66,9 @@ void write()
 
    for (auto block = blockStorage_.begin(); block != blockStorage_.end(); ++block)
    {
-      const auto * pdfField = block->getData< PdfField_T >(pdfFieldID_);
-            auto * velField = block->getData< VectorField_T >(velocityFieldID_);
-            auto * rhoField = block->getData< ScalarField_T >(rhoFieldID_);
+      const auto * pdfField = block->template getData< PdfField_T >(pdfFieldID_);
+            auto * velField = block->template getData< VectorField_T >(velocityFieldID_);
+            auto * rhoField = block->template getData< ScalarField_T >(rhoFieldID_);
 
       const CellInterval xyz = velField->xyzSize();