diff --git a/src/pystencils_autodiff/CMakeLists.tmpl.txt b/src/pystencils_autodiff/CMakeLists.tmpl.txt
deleted file mode 100644
index 67e939afe9c75fcd4f7e34cf78d90e03e200bc22..0000000000000000000000000000000000000000
--- a/src/pystencils_autodiff/CMakeLists.tmpl.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-waLBerla_link_files_to_builddir( *.prm )
-waLBerla_add_executable ( NAME {{ cmake_target_name }}
-                          FILES {%- for f in files_to_compile %}
-                                {{ f }} 
-                                {%- endfor %}
-                          DEPENDS {{depends | join(' ')}})
-
-{% if 'walberla_openvdb' in depends -%}
-if (WALBERLA_BUILD_WITH_OPENVDB)
-target_link_libraries( {{ cmake_target_name }} tbb boundary openvdb Half IexMath Iex IlmThread Imath)
-endif(WALBERLA_BUILD_WITH_OPENVDB)
-{%- endif %}
diff --git a/src/pystencils_autodiff/framework_integration/texture_astnodes.py b/src/pystencils_autodiff/framework_integration/texture_astnodes.py
index c82fe23a0981a70c75054aad4211ac82043d5708..21e43f24510bf22ac0b9f03227ede1e17b566bc2 100644
--- a/src/pystencils_autodiff/framework_integration/texture_astnodes.py
+++ b/src/pystencils_autodiff/framework_integration/texture_astnodes.py
@@ -107,7 +107,8 @@ class NativeTextureBinding(pystencils.backends.cbackend.CustomCodeNode):
             float                       maxMipmapLevelClamp;
         };
     """  # noqa
-    CODE_TEMPLATE_LINEAR = jinja2.Template("""cudaResourceDesc {{resource_desc}}{};
+    CODE_TEMPLATE_LINEAR = jinja2.Template("""
+cudaResourceDesc {{resource_desc}}{};
 {{resource_desc}}.resType = cudaResourceTypeLinear;
 {{resource_desc}}.res.linear.devPtr = {{device_ptr}};
 {{resource_desc}}.res.linear.desc.f = {{cuda_channel_format}};
@@ -124,6 +125,7 @@ auto {{texture_object}}Destroyer = std::unique_ptr(nullptr, [&](){
     """)
     CODE_TEMPLATE_PITCHED2D = jinja2.Template(""" !!! TODO!!! """)
     CODE_TEMPLATE_CUDA_ARRAY = jinja2.Template("""
+#   pragma GCC diagnostic ignored "-Wconversion"
 auto channel_desc_{{texture_name}} = {{channel_desc}};
 {{ create_array }}
 {{ copy_array }}
@@ -139,7 +141,8 @@ std::shared_ptr<void> {{array}}Destroyer(nullptr, [&](...){
     cudaFreeArray({{array}});
     cudaUnbindTexture({{texture_namespace}}{{texture_name}});
 });
-    """)
+#   pragma GCC diagnostic pop
+""")
 
     def __init__(self, texture, device_data_ptr, use_texture_objects=True, texture_namespace=''):
         self._texture = texture
diff --git a/src/pystencils_autodiff/graph_datahandling.py b/src/pystencils_autodiff/graph_datahandling.py
index 7051943bc44df79131c133277fd36fbf6dadafd7..b0c6283f6dabce8d64ee19e3bdf1cb160624035c 100644
--- a/src/pystencils_autodiff/graph_datahandling.py
+++ b/src/pystencils_autodiff/graph_datahandling.py
@@ -176,7 +176,8 @@ class GraphDataHandling(pystencils.datahandling.SerialDataHandling):
                   cpu=True,
                   gpu=None,
                   alignment=False,
-                  field_type=FieldType.GENERIC):
+                  field_type=FieldType.GENERIC,
+                  shape=None):
         if layout is None:
             layout = self.default_layout
 
@@ -197,13 +198,22 @@ class GraphDataHandling(pystencils.datahandling.SerialDataHandling):
         if len(values_per_cell) == 1 and values_per_cell[0] == 1:
             values_per_cell = ()
 
-        rtn = self._fields[name] = pystencils.Field.create_generic(name,
-                                                                   self.dim,
-                                                                   dtype,
-                                                                   index_dimensions=len(values_per_cell),
-                                                                   layout=layout,
-                                                                   index_shape=values_per_cell,
-                                                                   field_type=field_type)
+        if shape:
+            rtn = self._fields[name] = pystencils.Field.create_fixed_size(name,
+                                                                          shape,
+                                                                          index_dimensions=len(values_per_cell),
+                                                                          layout=layout,
+                                                                          dtype=dtype,
+                                                                          field_type=field_type)
+        else:
+            rtn = self._fields[name] = pystencils.Field.create_generic(name,
+                                                                       self.dim,
+                                                                       dtype,
+                                                                       index_dimensions=len(values_per_cell),
+                                                                       layout=layout,
+                                                                       index_shape=values_per_cell,
+                                                                       field_type=field_type)
+
         rtn.latex_name = latex_name
 
         if cpu:
diff --git a/src/pystencils_autodiff/simulation.py b/src/pystencils_autodiff/simulation.py
deleted file mode 100644
index 9b176ef29364b47c9698457df0c1b5a0a84af654..0000000000000000000000000000000000000000
--- a/src/pystencils_autodiff/simulation.py
+++ /dev/null
@@ -1,270 +0,0 @@
-#
-# Copyright © 2020 Stephan Seitz <stephan.seitz@fau.de>
-#
-# Distributed under terms of the GPLv3 license.
-
-"""
-
-"""
-
-import itertools
-from typing import Dict
-
-from stringcase import camelcase, pascalcase
-
-import lbmpy_walberla
-import pystencils
-import pystencils_walberla.codegen
-from pystencils.astnodes import Block, EmptyLine
-from pystencils.cpu.cpujit import get_headers
-from pystencils_autodiff.walberla import (
-    AllocateAllFields, CMakeLists, Communication, DefineKernelObjects, DefinitionsHeader,
-    FieldCopy, InitBoundaryHandling, LbCommunicationSetup, ResolveUndefinedSymbols, SwapFields,
-    SweepCreation, SweepOverAllBlocks, TimeLoopNode, UniformBlockforestFromConfig, WalberlaMain,
-    WalberlaModule, WriteVdb)
-
-WALBERLA_MODULES = ["blockforest",
-                    "boundary",
-                    "communication",
-                    "core",
-                    "cuda",
-                    "domain_decomposition",
-                    "executiontree",
-                    "fft",
-                    "field",
-                    "gather",
-                    "geometry",
-                    "gui",
-                    "lbm",
-                    "mesa_pd",
-                    "mesh",
-                    "pde",
-                    "pe",
-                    "pe_coupling",
-                    "postprocessing",
-                    "python_coupling",
-                    "simd",
-                    "sqlite",
-                    "stencil",
-                    "timeloop",
-                    "vtk",
-                    "walberla_openvdb"]
-
-
-class Simulation():
-    def _get_sweep_class_name(prefix='Kernel'):
-        ctr = 0
-        while True:
-            yield f'{prefix}{ctr}'
-            ctr += 1
-
-    def __init__(self,
-                 graph_data_handling,
-                 codegen_context,
-                 boundary_handling: pystencils.boundaries.BoundaryHandling = None,
-                 lb_rule=None,
-                 refinement_scaling=None,
-                 boundary_handling_target='gpu',
-                 cmake_target_name='autogen_app',
-                 write_out_stuff=True):
-        self._data_handling = graph_data_handling
-        self._lb_rule = lb_rule
-        self._refinement_scaling = refinement_scaling
-        self._block_forest = UniformBlockforestFromConfig()
-        self.parameter_config_block = 'parameters'
-        self._codegen_context = codegen_context
-        self._boundary_handling = boundary_handling
-        self._lb_model_name = 'GeneratedLatticeModel'
-        self._flag_field_dtype = 'uint32_t'
-        self._kernel_class_generator = Simulation._get_sweep_class_name()
-        self._with_gui = False
-        self._with_gui_default = False
-        self._boundary_kernels = {}
-        self._boundary_handling_target = boundary_handling_target
-        self._data_handling.merge_swaps_with_kernel_calls()
-        self._packinfo_class = 'PackInfo'
-        self.cmake_target_name = cmake_target_name
-        self._write_out_stuff = write_out_stuff
-        self._fluid_uid = None
-        self._debug = None
-
-    def _create_helper_files(self) -> Dict[str, str]:
-
-        if self._lb_rule:
-            pystencils_walberla.codegen.generate_pack_info_for_field(
-                self._codegen_context,
-                'PackInfo',
-                pystencils.Field.create_generic(self._data_handling.fields['ldc_pdf'].name,
-                                                self._data_handling.fields['ldc_pdf'].spatial_dimensions,
-                                                self._data_handling.fields['ldc_pdf'].dtype.numpy_dtype,
-                                                self._data_handling.fields['ldc_pdf'].index_dimensions,
-                                                index_shape=self._data_handling.fields['ldc_pdf'].index_shape,),
-                target=self._boundary_handling_target)
-            lbmpy_walberla.generate_lattice_model(self._codegen_context, self._lb_model_name,
-                                                  self._lb_rule,
-                                                  refinement_scaling=self._refinement_scaling)
-            if self._boundary_handling:
-                for bc in self.boundary_conditions:
-                    self._boundary_kernels.update({bc.name: lbmpy_walberla.generate_boundary(
-                        self._codegen_context,
-                        pascalcase(bc.name),
-                        bc,
-                        self._lb_rule.method,
-                        target=self._boundary_handling_target)},
-                    )
-                    self._bh_cycler = itertools.cycle(self._boundary_kernels.keys())
-
-    def _create_module(self):
-        if self._lb_rule:
-            lb_shape = (len(self._lb_rule.method.stencil),)
-        else:
-            lb_shape = (-1,)
-
-        self._field_allocations = field_allocations = AllocateAllFields(self._block_forest.blocks,
-                                                                        self._data_handling,
-                                                                        lb_shape,
-                                                                        self._lb_model_name)
-
-        if self._boundary_handling:
-            flag_field_id = field_allocations._cpu_allocations[
-                self._boundary_handling.flag_interface.flag_field_name].symbol
-
-        if self._lb_rule:
-            pdf_field_id = field_allocations._gpu_allocations.get(
-                'ldc_pdf', field_allocations._cpu_allocations['ldc_pdf']).symbol
-        else:
-            pdf_field_id = None
-
-        call_nodes = filter(lambda x: x, [self._graph_to_sweep(c) for c in self._data_handling.call_queue])
-
-        init_boundary_handling = (InitBoundaryHandling(self._block_forest.blocks,
-                                                       flag_field_id,
-                                                       pdf_field_id,
-                                                       self.boundary_conditions,
-                                                       self._boundary_kernels,
-                                                       self._field_allocations)
-                                  if self._boundary_handling
-                                  else EmptyLine())
-        if hasattr(init_boundary_handling, 'fluid'):
-            self._fluid_uid = init_boundary_handling.fluid
-
-        module = WalberlaModule(WalberlaMain(Block([
-            self._block_forest,
-            ResolveUndefinedSymbols(
-                Block([
-                    field_allocations,
-                    init_boundary_handling,
-                    LbCommunicationSetup(self._lb_model_name,
-                                         pdf_field_id,
-                                         self._packinfo_class,
-                                         self._boundary_handling_target)
-                    if self._lb_rule else EmptyLine(),
-                    DefineKernelObjects(
-                        Block([*call_nodes])
-                    )
-                ]), self.parameter_config_block
-            )
-        ])))
-
-        if self._debug:
-            from pystencils_autodiff.framework_integration.printer import DebugFrameworkPrinter
-            module.printer = DebugFrameworkPrinter()
-        self._codegen_context.write_file("main.cpp", str(module))
-        return module
-
-    def _create_defintions_header(self):
-        self._codegen_context.write_file("UserDefinitions.h",
-                                         str(DefinitionsHeader(self._lb_model_name if self._lb_rule else None,
-                                                               self._flag_field_dtype)))
-
-    def _create_cmake_file(self, extra_dependencis=[]):
-        walberla_dependencies = []
-        import re
-        regex = re.compile(r'^["<](\w*)/.*[>$"]')
-        headers = get_headers(self._module)
-        for h in headers:
-            match = regex.match(h)
-            if match:
-                module = match[1]
-                if module in WALBERLA_MODULES:
-                    walberla_dependencies.append(module)
-
-        dependencies = walberla_dependencies + extra_dependencis
-
-        try:
-            self._codegen_context.write_file("CMakeLists.txt",
-                                             str(CMakeLists(self.cmake_target_name,
-                                                            [f for f in self._codegen_context.files_written()
-                                                             if f.endswith('.cpp') or f.endswith('.cu')],
-                                                            depends=dependencies)))
-        except AttributeError:
-            self._codegen_context.write_file("CMakeLists.txt",
-                                             str(CMakeLists(self.cmake_target_name,
-                                                            [f for f in self._codegen_context.files.keys()
-                                                             if f.endswith('.cpp') or f.endswith('.cu')],
-                                                            depends=dependencies)))
-
-    def write_files(self):
-        self._create_helper_files()
-        self._module = self._create_module()
-        self._create_defintions_header()
-        self._create_cmake_file()  # has to be called last
-
-    @property
-    def boundary_conditions(self):
-        return self._boundary_handling._boundary_object_to_boundary_info.keys()
-
-    def _graph_to_sweep(self, c):
-        from pystencils_autodiff.graph_datahandling import (
-            KernelCall, TimeloopRun, DataTransferKind, DataTransfer, FieldOutput)
-
-        if isinstance(c, KernelCall):
-
-            if 'indexField' in [f.name for f in c.kernel.ast.fields_accessed]:
-                bh = next(self._bh_cycler)
-                return f'sweep(blocks, {camelcase(bh)});'
-
-            sweep_class_name = next(self._kernel_class_generator)
-            fields_accessed = [f.name for f in c.kernel.ast.fields_accessed]
-            c.tmp_field_swaps = list(filter(
-                lambda x: x[0].name in fields_accessed and x[1].name in fields_accessed, c.tmp_field_swaps))
-            pystencils_walberla.codegen.generate_sweep(
-                self._codegen_context, sweep_class_name, c.kernel.ast, field_swaps=c.tmp_field_swaps)
-            rtn = SweepOverAllBlocks(SweepCreation(sweep_class_name,
-                                                   self._field_allocations,
-                                                   c.kernel.ast,
-                                                   parameters_to_ignore=[s[1].name for s in c.tmp_field_swaps]),
-                                     self._block_forest.blocks)
-
-        elif isinstance(c, TimeloopRun):
-            sweeps = [self._graph_to_sweep(s) for s in c.timeloop._single_step_asts]
-            rtn = TimeLoopNode(0, c.time_steps, sweeps)
-
-        elif isinstance(c, DataTransfer):
-            if c.kind == DataTransferKind.HOST_SWAP:
-                src = self._field_allocations._cpu_allocations[c.field.name].symbol
-                dst = self._field_allocations._cpu_allocations[c.destination.name].symbol
-                rtn = SwapFields(src, dst)
-            elif c.kind == DataTransferKind.DEVICE_SWAP:
-                src = self._field_allocations._gpu_allocations[c.field.name].symbol
-                dst = self._field_allocations._gpu_allocations[c.destination.name].symbol
-                rtn = SwapFields(src, dst)
-            elif c.kind == DataTransferKind.HOST_TO_DEVICE:
-                src = self._field_allocations._cpu_allocations[c.field.name].symbol
-                dst = self._field_allocations._gpu_allocations[c.field.name].symbol
-                rtn = FieldCopy(self._block_forest.blocks, src, c.field, False, dst, c.field, True)
-            elif c.kind == DataTransferKind.DEVICE_TO_HOST:
-                src = self._field_allocations._gpu_allocations[c.field.name].symbol
-                dst = self._field_allocations._cpu_allocations[c.field.name].symbol
-                rtn = FieldCopy(self._block_forest.blocks, src, c.field, True, dst, c.field, False)
-            elif c.kind in (DataTransferKind.DEVICE_COMMUNICATION, DataTransferKind.HOST_COMMUNICATION):
-                rtn = Communication(self._boundary_handling_target == 'gpu')
-            else:
-                rtn = None
-        elif isinstance(c, FieldOutput):
-            rtn = WriteVdb(self._block_forest, c.output_path, c.fields, c.flag_field, self._fluid_uid)
-        else:
-            rtn = None
-
-        return rtn
-        return rtn
diff --git a/src/pystencils_autodiff/walberla.py b/src/pystencils_autodiff/walberla.py
deleted file mode 100644
index 914a65296dfdac9108cbd930a4630503e2fcde07..0000000000000000000000000000000000000000
--- a/src/pystencils_autodiff/walberla.py
+++ /dev/null
@@ -1,1025 +0,0 @@
-#
-# Copyright © 2020 Stephan Seitz <stephan.seitz@fau.de>
-#
-# Distributed under terms of the GPLv3 license.
-
-"""
-
-"""
-
-
-from abc import ABC
-from os.path import dirname, join
-
-import jinja2
-import numpy as np
-import sympy as sp
-from stringcase import camelcase, pascalcase
-from sympy.core.cache import cacheit
-
-import pystencils
-from pystencils.astnodes import SympyAssignment
-from pystencils.data_types import TypedSymbol, create_type
-from pystencils_autodiff._file_io import read_template_from_file
-from pystencils_autodiff.framework_integration.astnodes import JinjaCppFile
-
-
-def _make_field_type(field, on_gpu):
-    from pystencils_walberla.jinja_filters import make_field_type, get_field_fsize
-    f_size = get_field_fsize(field)
-
-    return make_field_type(pystencils.data_types.get_base_type(field.dtype), f_size, on_gpu)
-
-
-class BlockDataID(TypedSymbol):
-    """
-    Local cell interval in global index coordinates
-    """
-    def __new__(cls, *args, **kwds):
-        obj = BlockDataID.__xnew_cached_(cls, *args, **kwds)
-        return obj
-
-    def __new_stage2__(cls, field, on_gpu, *args, **kwargs):
-        name = field.name + ('_data_gpu' if on_gpu else '_data')
-        obj = super(BlockDataID, cls).__xnew__(cls,
-                                               name,
-                                               'BlockDataID',
-                                               *args,
-                                               **kwargs)
-        obj.field = field
-        obj.on_gpu = on_gpu
-        return obj
-
-    __xnew__ = staticmethod(__new_stage2__)
-    __xnew_cached_ = staticmethod(cacheit(__new_stage2__))
-
-    def _hashable_content(self):
-        return super()._hashable_content(), self.on_gpu
-
-    def __getnewargs__(self):
-        return self.name, self.on_gpu
-
-    @property
-    def walberla_field_type(self):
-        return _make_field_type(self.field, self.on_gpu)
-
-
-class FieldType(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("{{ field_type }}")
-
-    def __init__(self, field: pystencils.Field, on_gpu: bool):
-
-        field_type = _make_field_type(field, on_gpu)
-
-        ast_dict = {'on_gpu': on_gpu,
-                    'field_type': field_type
-                    }
-        JinjaCppFile.__init__(self, ast_dict)
-
-    @property
-    def headers(self):
-        if self.ast_dict.on_gpu:
-            return ['"field/GhostLayerField.h"']
-        else:
-            return ['"cuda/GPUField.h"']
-
-
-class WalberlaModule(JinjaCppFile):
-    TEMPLATE = read_template_from_file(join(dirname(__file__), 'walberla_main.tmpl.cpp'))
-
-    def __init__(self, main):
-        ast_dict = {'main': main}
-        JinjaCppFile.__init__(self, ast_dict)
-
-
-class CMakeLists(JinjaCppFile):
-    TEMPLATE = read_template_from_file(join(dirname(__file__), 'CMakeLists.tmpl.txt'))
-
-    def __init__(self, cmake_target_name, files_to_compile, depends):
-        ast_dict = {'files_to_compile': files_to_compile,  # we try to avoid evil globbing
-                    'cmake_target_name': cmake_target_name,
-                    'depends': depends}
-        JinjaCppFile.__init__(self, ast_dict)
-
-
-class WalberlaMain(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""
-int main( int argc, char ** argv )
-{
-   using namespace walberla;
-   using namespace walberla_user;
-   using namespace walberla::pystencils;
-
-   Environment {{ walberl_env }}( argc, argv );
-
-   {{ body | indent(3) }}
-
-   return EXIT_SUCCESS;
-}
-    """)
-
-    headers = ['"core/Environment.h"',
-               '<cstdlib>',
-               '"UserDefinitions.h"']
-
-    def __init__(self, body, walberl_env="walberlaEnv"):
-
-        ast_dict = {
-            'body': body,
-            'walberl_env': TypedSymbol(walberl_env, "Environment")
-        }
-
-        super().__init__(ast_dict)
-
-    @property
-    def symbols_defined(self):
-        return {self.ast_dict.walberl_env}
-
-
-class BlockForestCreation(JinjaCppFile):
-    TEMPLATE = jinja2.Template("""auto {{ blocks }} = walberla_user::createBlockForest(walberlaEnv);""")
-    def __init__(self, block_forest_name):
-
-        ast_dict = {
-            'blocks': TypedSymbol(block_forest_name, "auto")
-        }
-
-        super().__init__(ast_dict)
-
-    @property
-    def symbols_defined(self):
-        return {self.ast_dict.blocks}
-
-
-class UniformBlockforestFromConfig(BlockForestCreation):
-    TEMPLATE = jinja2.Template(
-        """auto {{ blocks }} = blockforest::createUniformBlockGridFromConfig( walberlaEnv.config() );""")
-    headers = ['"blockforest/Initialization.h"']
-
-    def __init__(self):
-        super().__init__('blocks')
-
-    @property
-    def config_required(self):
-        return {"DomainSetup": {"blocks": [1, 1, 1], "cellsPerBlock": [100, 100, 100]}}
-
-    @property
-    def blocks(self):
-        return self.ast_dict.blocks
-
-
-class DefinitionsHeader(JinjaCppFile):
-    TEMPLATE = read_template_from_file(join(dirname(__file__), 'walberla_user_defintions.tmpl.hpp'))
-
-    def __init__(self, lb_model_name, flag_field_type):
-        self.headers = ['<cstdint>',  '"field/FlagField.h"']
-        if lb_model_name:
-            self.headers.append(f'"{lb_model_name}.h"')
-        super().__init__({'lb_model_name': lb_model_name, 'flag_field_type': flag_field_type})
-
-
-class Using(JinjaCppFile):
-    TEMPLATE = jinja2.Template("using {{ new_type }} = {{ definition }};\n")
-
-    def __init__(self, new_type, definition):
-        ast_dict = {
-            'new_type': new_type,
-            'definition': definition,
-        }
-        super().__init__(ast_dict)
-
-    @property
-    def symbols_defined(self):
-        return {self.ast_dict.new_type}
-
-
-class GetParameter(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template(
-        'walberlaEnv.config()->getOneBlock("{{ block }}").getParameter<{{ key.dtype }}>("{{ key }}"{% if default %}, static_cast<{{ key.dtype }}>({{ default }}){% endif %})'  # noqa
-        )
-
-    def __init__(self, block: str, key, default_value=None):
-        ast_dict = {
-            'key': key,
-            'block': block,
-            'default': default_value
-        }
-        super().__init__(ast_dict)
-
-    @property
-    def config_required(self):
-        return {self.ast_dict.block: {self.ast_dict.symbol: self.ast_dict.default_value}}
-
-    def __sympy__(self):
-        return TypedSymbol(self.ast_dict.key.name + "Config", str(self.ast_dict.key.dtype))
-
-    def __getattr__(self, name):
-        return getattr(self.__sympy__(), name)
-
-
-class FieldAllocation(JinjaCppFile):
-    """
-    .. code:: cpp
-
-        BlockDataID addToStorage(const shared_ptr < BlockStorage_T > & blocks,
-                                  const std:: string & identifier,
-                                  const typename GhostLayerField_T:: value_type & initValue = typename GhostLayerField_T: : value_type(),
-                                  const Layout layout=zyxf,
-                                  const uint_t nrOfGhostLayers=uint_t(1),
-                                  const bool alwaysInitialize=false,
-                                  const std:: function < void (GhostLayerField_T * field, IBlock * const block ) > & initFunction =
-                                     std: : function < void (GhostLayerField_T * field, IBlock * const block ) > (),
-                                  const Set < SUID > & requiredSelectors = Set < SUID > : : emptySet(),
-                                  const Set < SUID > & incompatibleSelectors = Set < SUID > : : emptySet() )
-
-    """  # noqa
-
-    TEMPLATE = jinja2.Template("""
-{%- if on_gpu -%}
-BlockDataID {{ field_name }}_data_gpu = cuda::addGPUFieldToStorage<{{ field_type }}>({{ block_forest }},
-                                    "{{ field_name }}",
-                                    {{ f_size }},
-                                    {{ layout }},
-                                    {{ num_ghost_layers }},
-                                    {{ usePitchedMem }} );
-{%- else -%}
-BlockDataID {{ field_name }}_data = field::addToStorage<{{ field_type }}>( {{ block_forest }},
-                                    "{{ field_name }}"
-     {%- if init_value -%}      , {{ init_value }}{% endif %}
-     {%- if layout -%}      , {{ layout }}{% endif %}
-     {%- if num_ghost_layers -%}, {{ num_ghost_layers }} {% endif %}
-     {%- if always_initialize -%}, {{ always_initialize }} {% endif %});
-{%- endif %}
-""")  # noqa
-
-    def __init__(self, block_forest, field, on_gpu=False, usePitchedMem=True, num_ghost_layers=1, ):
-        self._symbol = BlockDataID(field, on_gpu)
-        ast_dict = {
-            'block_forest': block_forest,
-            'field_name': field.name,
-            # f'GhostLayerField< {field.dtype}, {field.index_shape[0] if field.index_shape else 1} >'
-            'field_type': FieldType(field, on_gpu),
-            'on_gpu': on_gpu,
-            'f_size': field.index_shape[0] if field.index_shape else 1,
-            'init_value': f'{field.dtype}{{}}',
-            'num_ghost_layers': num_ghost_layers,
-            'layout': 'field::zyxf',
-            'usePitchedMem': 'true' if usePitchedMem else 'false',
-        }
-        super().__init__(ast_dict)
-
-    @property
-    def symbol(self):
-        return self._symbol
-
-    @property
-    def symbols_defined(self):
-        return {self.symbol}
-
-    @property
-    def headers(self):
-        return (['"cuda/AddGPUFieldToStorage.h"', '"field/GhostLayerField.h"']
-                if self.ast_dict.on_gpu
-                else ['"field/AddToStorage.h"'])
-
-
-class FlagFieldAllocation(FieldAllocation):
-    """We need this special class to pass waLBerla's runtime type checks"""
-    TEMPLATE = jinja2.Template("""BlockDataID {{ field_name }}_data = field::addFlagFieldToStorage<FlagField_T>({{ block_forest }},
-                                    "{{ field_name }}");
-""")  # noqa
-
-
-class WalberlaVector(JinjaCppFile):
-    TEMPLATE = jinja2.Template("""math::Vector{{ndim}}<{{dtype}}>({{offset | join(', ')}})""")
-
-    def __init__(self, offset, dtype='real_t'):
-        ast_dict = {
-            'offset': offset,
-            'dtype': dtype,
-            'ndim': len(offset),
-        }
-        super().__init__(ast_dict)
-
-    def __sympy__(self):
-        return sp.Matrix(self.ast_dict.offset)
-
-
-class FlagUidDefinition(JinjaCppFile):
-    TEMPLATE = jinja2.Template('const FlagUID {{ name }}FlagUID("{{ name }}");')
-
-    def __init__(self, name):
-        self._symbol = TypedSymbol(name + 'FlagUID', 'FlagUID')
-        ast_dict = {
-            'name': name,
-        }
-        super().__init__(ast_dict)
-
-    headers = ['"field/FlagUID.h"']
-
-    @property
-    def symbol(self):
-        return self._symbol
-
-    @property
-    def symbols_defined(self):
-        return {self.symbol}
-
-
-class BoundaryHandling(ABC):
-    pass
-
-
-class BoundaryHandlingFromConfig(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""auto {{  boundaries_config }} = walberlaEnv.config()->getOneBlock( "Boundaries" );
-geometry::initBoundaryHandling<FlagField_T>(*{{ block_forest }}, {{ flag_field_id }}, {{ boundaries_config }});
-geometry::setNonBoundaryCellsToDomain<FlagField_T>(*{{ block_forest }}, {{ flag_field_id }}, {{ fluid_uid }});""")
-
-    def __init__(self, block_forest, flag_field_id, fluid_uid):
-        self._symbol = boundaries_config = TypedSymbol('boundariesConfig', 'auto')
-        ast_dict = {
-            'flag_field_id': flag_field_id,
-            'block_forest': block_forest,
-            'fluid_uid': fluid_uid,
-            'boundaries_config': boundaries_config,
-        }
-        super().__init__(ast_dict)
-
-    @property
-    def symbol(self):
-        return self._symbol
-
-    @property
-    def symbols_defined(self):
-        return {self.symbol}
-
-
-class FillFromFlagField(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""
-    {{ boundary_condition }}.fillFromFlagField<{{ flag_field_type }}>( {{ block_forest }}, {{ flag_field_id }}, FlagUID("{{ boundary_name }}"), {{ flag_field_id }});
-    """)  # noqa
-
-    def __init__(self, flag_field_id, fluid_uid):
-        self._symbol = boundaries_config = TypedSymbol('boundariesConfig', 'auto')
-        ast_dict = {
-            'flag_field_id': flag_field_id,
-            'fluid_uid': fluid_uid,
-            'boundaries_config': boundaries_config,
-        }
-        super().__init__(ast_dict)
-
-    @property
-    def symbol(self):
-        return self._symbol
-
-    @property
-    def symbols_defined(self):
-        return {self.symbol}
-
-
-class LbCommunicationSetup(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""
-{{CommonicationScheme}}<lbm::{{ lb_model_type }}::CommunicationStencil> {{ communication }}( blocks );
-{{ communication }}.addPackInfo( make_shared< {{ packinfo_class }} >( {{ pdf_id }} ) );
- """)  # noqa
-
-    def __init__(self, lb_model_type, pdf_id, packinfo_class, gpu):
-        self._symbol = TypedSymbol('communication', 'auto')
-        self.gpu = gpu
-
-        ast_dict = {
-            'lb_model_type': lb_model_type,
-            'pdf_id': pdf_id,
-            'communication': self._symbol,
-            'packinfo_class': packinfo_class,
-            'CommonicationScheme': ('cuda::communication::UniformGPUScheme'
-                                    if gpu else 'blockforest::communication::UniformBufferedScheme')
-        }
-        super().__init__(ast_dict)
-
-    @property
-    def symbol(self):
-        return self._symbol
-
-    @property
-    def symbols_defined(self):
-        return {self.symbol}
-
-    @property
-    def headers(self):
-        if self.gpu:
-            return ['"cuda/communication/UniformGPUScheme.h"', '"lbm/communication/PdfFieldPackInfo.h"', '"PackInfo.h"']
-        else:
-            return ['"blockforest/communication/UniformBufferedScheme.h"',
-                    '"lbm/communication/PdfFieldPackInfo.h"',
-                    '"PackInfo.h"']
-
-
-class BeforeFunction(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""BeforeFunction( {{ f }}, "{{ f }}" )""")  # noqa
-
-    def __init__(self, function):
-        ast_dict = {
-            'f': function,
-        }
-        super().__init__(ast_dict)
-
-
-class AfterFunction(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""AfterFunction( {{ f }}, "{{ f }}" )""")  # noqa
-
-    def __init__(self, function):
-        ast_dict = {
-            'f': function,
-        }
-        super().__init__(ast_dict)
-
-
-class Sweep(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""Sweep( {{ f }}, "{{ f }}" )""")  # noqa
-
-    def __init__(self, function):
-        ast_dict = {
-            'f': function,
-        }
-        super().__init__(ast_dict)
-
-
-class TimeLoop(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""
-{{ timeloop_definition }}
-
-{% for f in before_functions -%}
-{{timeloop_name}}.add() << {{ f }};
-{% endfor %}
-{% for s in sweeps -%}
-{{timeloop_name}}.add() << {{ s }};
-{% endfor %}
-{% for f in after_functions -%}
-{{timeloop_name}}.add() << {{ f }};
-{% endfor %}
-    """)  # noqa
-
-    def __init__(self, block_forest, before_functions, sweeps, after_functions, timesteps, timeloop_name='timeloop'):
-        self._symbol = TypedSymbol(timeloop_name, 'SweepTimeloop')
-        ast_dict = {
-            'timeloop_definition': CppObjectConstruction(self._symbol,
-                                                         [f'{block_forest}->getBlockStorage()',
-                                                          timesteps]),
-            'before_functions': [BeforeFunction(f) for f in before_functions],
-            'sweeps': [Sweep(f) for f in sweeps],
-            'after_functions': [AfterFunction(f) for f in after_functions],
-            'timeloop_name': timeloop_name
-        }
-        super().__init__(ast_dict)
-
-    @property
-    def symbol(self):
-        return self._symbol
-
-    @property
-    def symbols_defined(self):
-        return {self.symbol}
-
-    headers = ['"timeloop/all.h"']
-
-
-class ForLoop(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""
-for( {{loop_symbol.dtype}} {{loop_symbol}} = {{loop_start}}; {{loop_symbol}} < {{loop_end}}; {{loop_symbol}} += {{loop_increment}} ) {
-   {%- for c in children %}
-   {{ c | indent(3) -}}
-   {% endfor %}
-}
-""")  # noqa
-
-    def __init__(self,
-                 loop_start,
-                 loop_end,
-                 children,
-                 loop_symbol=TypedSymbol('t_', create_type('int64')),
-                 loop_increment=1):
-        ast_dict = {
-            'loop_symbol': loop_symbol,
-            'loop_start': loop_start,
-            'loop_end': loop_end,
-            'children': children,
-            'loop_increment': loop_increment
-        }
-        super().__init__(ast_dict)
-
-    @property
-    def loop_symbol(self):
-        return self.ast_dict.loop_symbol
-
-    @property
-    def symbols_defined(self):
-        return {self.loop_symbol}
-
-
-class U_Rho_Adaptor(JinjaCppFile):
-    """Docstring for U_Rho_Adaptor. """
-
-    TEMPLATE = jinja2.Template("""
-field::addFieldAdaptor<lbm::Adaptor<lbm::{{ lb_model_type }}>::Density>       ( {{ block_forest }}, {{ pdf_id }}, "{{ density_name }}" );
-field::addFieldAdaptor<lbm::Adaptor<lbm::{{ lb_model_type }}>::VelocityVector>( {{ block_forest }}, {{ pdf_id }}, "{{ velocity_name }}" );
-    """)  # noqa
-
-    def __init__(self, block_forest, lb_model_type, pdf_id):
-        self.density_name = "DensityAdaptor"
-        self.velocity_name = "VelocityAdaptor"
-        ast_dict = {
-            'lb_model_type': lb_model_type,
-            'pdf_id': pdf_id,
-            'block_forest': block_forest,
-            'density_name': self.density_name,
-            'velocity_name': self.velocity_name,
-        }
-        super().__init__(ast_dict)
-
-    headers = ['"timeloop/all.h"']
-
-
-class RunTimeLoop(JinjaCppFile):
-    TEMPLATE = jinja2.Template("""{%- if with_gui == 'true' %}
-if( parameters.getParameter<bool>( "useGui", {{ use_gui_default }}) )
-{
-   GUI gui ( {{ timeloop }}, {{ block_forest }}, argc, argv );
-   lbm::connectToGui<LatticeModel_T> ( gui );
-   gui.run();
-}
-else {
-   {{ timeloop }}.run();
-}
-{%- else %}
-timeloop.run();
-{%- endif %}""")  # noqa
-
-    def __init__(self, block_forest, timeloop, with_gui=False, use_gui_default='false'):
-        self.density_name = "DensityAdaptor"
-        self.velocity_name = "VelocityAdaptor"
-        ast_dict = {
-            'block_forest': block_forest,
-            'timeloop': timeloop.symbol,
-            'with_gui': with_gui,
-            'use_gui_default': use_gui_default,
-        }
-        super().__init__(ast_dict)
-
-    @property
-    def headers(self):
-        if self.ast_dict.with_gui:
-            return [
-                "gui/all.h",
-                "lbm/gui/Connection.h"
-            ]
-        else:
-            return []
-
-
-class CppObjectConstruction(JinjaCppFile, pystencils.astnodes.SympyAssignment):
-
-    TEMPLATE = jinja2.Template("""{{  symbol.dtype  }} {{ symbol }}({{ args | join(', ') }});""")  # noqa
-
-    def __init__(self, symbol, args):
-        JinjaCppFile.__init__(self, {})
-        self.ast_dict.update({
-            'symbol': symbol,
-            'args': args,
-        })
-        pystencils.astnodes.SympyAssignment.__init__(self, symbol, 1)
-
-    @property
-    def symbol(self):
-        return self.lhs
-
-    def __sympy__(self):
-        return self.symbol
-
-    @property
-    def symbols_defined(self):
-        return {self.symbol}
-
-
-class ResolveUndefinedSymbols(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""
-{% for p in parameters %}
-{{ p }}
-{% endfor %}
-{{ block  }}
-""")  # noqa
-
-    def __init__(self, block, config_block):
-        self.block = block
-        JinjaCppFile.__init__(self, {})
-        self.ast_dict.update({
-            'block': block,
-            'config_block': config_block,
-            'parameters': self.parameter_definitions
-        })
-
-    @property
-    def symbols_defined(self):
-        return self.block.undefined_symbols
-
-    def __repr__(self):
-        self.ast_dict.parameters = self.parameter_definitions
-        return super().__repr__()
-
-    def __str__(self):
-        self.ast_dict.parameters = self.parameter_definitions
-        return super().__str__()
-
-    @property
-    def parameter_definitions(self):
-        parameter_definitions = [SympyAssignment(s, GetParameter(self.ast_dict.config_block, s))
-                                 for s in self.block.undefined_symbols]
-        return parameter_definitions
-
-    @property
-    def config_required(self):
-        return {self.ast_dict.config_block, {s.name: None for s in self.symbols_defined}}
-
-
-class FieldCopyFunctor(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""cuda::fieldCpyFunctor<{{from_type}}, {{ to_type }} >({{from_id}}, {{to_id}})""")  # noqa
-
-    def __init__(self, from_id, from_type, to_id, to_type):
-        ast_dict = {'from_id': from_id,
-                    'from_type': from_type,
-                    'to_id': to_id,
-                    'to_type': to_type
-                    }
-        super().__init__(ast_dict)
-
-    headers = ['"cuda/FieldCopy.h"']
-
-
-class DefineKernelObjects(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""
-// Kernels
-{% for k in kernels -%}
-{{ k }}
-{% endfor %}
-// Execution
-{{ block  }}
-""")  # noqa
-
-    def __init__(self, block):
-        self.sweeps = block.atoms(SweepOverAllBlocks)
-        self.kernels = sorted({k.ast_dict.functor if isinstance(k.ast_dict.functor, SympyAssignment)
-                               else SympyAssignment(k.ast_dict.functor.symbol, k.ast_dict.functor,
-                                                    is_const=False, use_auto=True)
-                               for k in self.sweeps}, key=str)
-        ast_dict = {'block': block,
-                    'kernels': self.kernels,
-                    }
-        JinjaCppFile.__init__(self, ast_dict)
-
-
-def _allocate_field(block_forest, field, on_gpu):
-    # TODO: hack!
-    if np.issubdtype(field.dtype.numpy_dtype, np.integer) and 'flag' in field.name.lower():
-        assert on_gpu is False
-        return FlagFieldAllocation(block_forest, field)
-    else:
-        return FieldAllocation(block_forest, field, on_gpu=on_gpu)
-
-
-class AllocateAllFields(JinjaCppFile):
-
-    TEMPLATE = jinja2.Template("""
-// CPU Arrays
-{% for c in cpu_arrays %}
-{{- c }}
-{% endfor %}
-{%- if gpu_arrays -%}
-// GPU Arrays
-{% for g in gpu_arrays %}
-{{- g }}
-{% endfor %}
-{%- endif %}
-{{ block  }}
-""")  # noqa
-
-    def __init__(self, block_forest, data_handling, lb_index_shape=(-1,), lb_model_name=None):
-        self.data_handling = data_handling
-        self.block_forest = block_forest
-        self.lb_index_shape = lb_index_shape
-        self.lb_model_name = lb_model_name
-        JinjaCppFile.__init__(self, {})
-        self._update()
-
-    def __repr__(self):
-        self._update()
-        return super().__repr__()
-
-    def __str__(self):
-        self._update()
-        return super().__str__()
-
-    def _update(self):
-        self.ast_dict.update({
-            'cpu_arrays': self._cpu_allocations.values(),
-            'gpu_arrays': self._gpu_allocations.values()
-        })
-
-    @property
-    def _cpu_allocations(self):
-        return {s: _allocate_field(self.block_forest, self.data_handling.fields[s], on_gpu=False)
-                for s in self.data_handling.cpu_arrays.keys()}
-        # if not (self.data_handling.fields[s].index_shape == self.lb_index_shape)}
-
-    @property
-    def _gpu_allocations(self):
-        return {s: _allocate_field(self.block_forest, self.data_handling.fields[s], on_gpu=True)
-                for s in self.data_handling.gpu_arrays.keys()}
-        # if not (self.data_handling.fields[s].index_shape == self.lb_index_shape)}
-
-
-class InitBoundaryHandling(JinjaCppFile):
-    TEMPLATE = jinja2.Template("""
-// This is my fluid 🏊. It's special... 🤔 but for the computer just a 0
-{{ fluid_uid_definition }}
-
-// Initialize geometry 🎲
-{{ geometry_initialization }}
-
-// Here are the generated boundaries. They are not so special... 👎
-{%- for b in generated_boundaries %}
-{{ b }}
-{% endfor %}
-""")  # noqa
-
-    def __init__(self,
-                 block_forest,
-                 flag_field_id,
-                 pdf_field_id,
-                 boundary_conditions,
-                 boundary_kernel: dict,
-                 field_allocations):
-        self.fluid = FlagUidDefinition("fluid")
-        ast_dict = {'fluid_uid_definition': self.fluid,
-                    'geometry_initialization': BoundaryHandlingFromConfig(block_forest,
-                                                                          flag_field_id,
-                                                                          self.fluid.symbol),
-                    'generated_boundaries': [GeneratedBoundaryInitialization(block_forest,
-                                                                             b,
-                                                                             pdf_field_id,
-                                                                             flag_field_id,
-                                                                             self.fluid.symbol,
-                                                                             boundary_kernel[b.name],
-                                                                             field_allocations)
-                                             for b in boundary_conditions]
-                    }
-        super().__init__(ast_dict)
-
-    headers = ['"cuda/FieldCopy.h"', '"geometry/InitBoundaryHandling.h"']
-    @property
-    def undefined_symbols(self):
-        rtn = super().undefined_symbols
-        for b in self.ast_dict.generated_boundaries:
-            rtn = rtn | b.undefined_symbols
-        return rtn
-
-
-class GeneratedBoundaryInitialization(JinjaCppFile):
-    TEMPLATE = jinja2.Template("""lbm::{{ boundary_condition }} {{ identifier }}( {{ block_forest }}, {{ parameter_ids | join(', ') }} );
-{{ identifier }}.fillFromFlagField<FlagField_T>( {{ block_forest }}, {{ flag_field_id }}, FlagUID("{{ boundary_condition }}"), {{ fluid_uid }} );
-""")  # noqa
-
-    def __init__(self,
-                 block_forest,
-                 boundary_condition,
-                 pdf_field_id,
-                 flag_field_id,
-                 fluid_uid,
-                 kernel,
-                 field_allocations):
-        def resolve_parameter(p):
-            if kernel.target == 'cpu':
-                dict = field_allocations._cpu_allocations
-            else:
-                dict = field_allocations._gpu_allocations
-
-            return dict.get(p.symbol.name.replace('_data_', ''), p).symbol
-        parameters = kernel.get_parameters()
-        parameter_ids = [resolve_parameter(p)
-                         for p in parameters
-                         if (p.is_field_pointer or not p.is_field_parameter) and
-                         p.symbol.name not in ('_data_indexVector', '_data_pdfs', 'indexVectorSize',)]
-
-        self.fluid = FlagUidDefinition("fluid")
-        ast_dict = {'block_forest': block_forest,
-                    'boundary_condition': pascalcase(boundary_condition.name),
-                    'identifier': camelcase(boundary_condition.name),
-                    'pdf_field_id': pdf_field_id,
-                    'fluid_uid': fluid_uid,
-                    'flag_field_id': flag_field_id,
-                    'parameter_ids': [pdf_field_id] + parameter_ids,
-                    }
-        super().__init__(ast_dict)
-
-    @property
-    def headers(self):
-        return [f'"{pascalcase(self.ast_dict.boundary_condition)}.h"']
-
-    @property
-    def symbols_defined(self):
-        # Could also be defined
-        # TypedSymbol(self.ast_dict.identifier, 'FlagUID'),
-        return {TypedSymbol(self.ast_dict.identifier, f'lbm::{self.ast_dict.boundary_condition}')}
-
-    @property
-    def undefined_symbols(self):
-        return super().undefined_symbols | set(self.ast_dict.parameter_ids)
-
-
-class SweepCreation(JinjaCppFile):
-    TEMPLATE = jinja2.Template("""{{ sweep_class_name }}( {{ parameter_ids | join(', ') }} )""")  # noqa
-
-    def __init__(self,
-                 sweep_class_name: str,
-                 field_allocation: AllocateAllFields,
-                 ast,
-                 parameters_to_ignore=[]):
-
-        import pystencils_walberla.jinja_filters
-        parameters_to_ignore += pystencils_walberla.jinja_filters.SPECIAL_SYMBOL_NAMES
-
-        def resolve_parameter(p):
-            if ast.target == 'cpu':
-                dict = field_allocation._cpu_allocations
-            else:
-                dict = field_allocation._gpu_allocations
-
-            return dict.get(p.symbol.name.replace('_data_', ''), p).symbol
-
-        parameters = ast.get_parameters()
-        parameter_ids = [resolve_parameter(p)
-                         for p in parameters
-                         if (p.is_field_pointer and p.symbol.field_name not in parameters_to_ignore)
-                         or not p.is_field_parameter and p.symbol.name not in parameters_to_ignore]
-
-        ast_dict = {'sweep_class_name': sweep_class_name,
-                    'parameter_ids': parameter_ids,
-                    }
-        super().__init__(ast_dict)
-        self.symbol = TypedSymbol(self.ast_dict.sweep_class_name.lower(), self.ast_dict.sweep_class_name)
-
-    @property
-    def headers(self):
-        return [f'"{self.ast_dict.sweep_class_name}.h"']
-
-    @property
-    def undefined_symbols(self):
-        return set(self.ast_dict.parameter_ids)
-
-    free_symbols = undefined_symbols
-
-    @property
-    def symbols_defined(self):
-        return {self.symbol}
-
-    def __sympy__(self):
-        return self.symbol
-
-
-class SweepOverAllBlocks(JinjaCppFile):
-    # TEMPLATE = jinja2.Template("""std::for_each({{block_forest}}->begin(), {{block_forest}}->end(), {{functor}});""")  # noqa
-    TEMPLATE = jinja2.Template("""sweep({{block_forest}}, {{sweep_class_name | lower() }});""")
-
-    def __init__(self, functor: SweepCreation, block_forest):
-        ast_dict = {'functor': functor,
-                    'sweep_class_name': functor.ast_dict.sweep_class_name,
-                    'block_forest': block_forest}
-        super().__init__(ast_dict)
-
-    @property
-    def undefined_symbols(self):
-        return {self.ast_dict.functor.symbol}
-
-    @property
-    def required_global_declarations(self):
-        return ["""template < class BlockStorage_T, class Functor_T >
-static inline auto sweep(walberla::shared_ptr<BlockStorage_T> blocks, Functor_T functor) -> void {
-   for ( auto& block : *blocks ) {
-      functor(&block);
-   }
-}
-"""]
-
-
-class FieldCopy(JinjaCppFile):
-    TEMPLATE = jinja2.Template("""cuda::fieldCpy< {{src_type }}, {{dst_type }} > ({{block_forest }}, {{src_id }}, {{dst_id }}); """)  # noqa
-
-    def __init__(self, block_forest, src_id, dst_id,):
-        ast_dict = {'src_id': src_id,
-                    'dst_id': dst_id,
-                    'src_type': src_id.walberla_field_type,
-                    'dst_type': dst_id.walberla_field_type,
-                    'block_forest': block_forest}
-        super().__init__(ast_dict)
-
-    headers = ['"cuda/FieldCopy.h"']
-
-
-class SwapFields(JinjaCppFile):
-    """
-     .. warn::
-
-         Prefer temporary fields in sweeps over this class! Two full fields have higher memory usage.
-
-    """
-    TEMPLATE = jinja2.Template("""std::swap({{field_id0}}, {{field_id1}});""")
-
-    def __init__(self, field_id0, field_id1):
-        ast_dict = {'field_id0': field_id0,
-                    'field_id1': field_id1}
-        super().__init__(ast_dict)
-
-    headers = ["<algorithm>"]
-
-
-class Communication(JinjaCppFile):
-    """
-     .. warn::
-
-         Prefer temporary fields in sweeps over this class! Two full fields have higher memory usage.
-
-    """
-    TEMPLATE = jinja2.Template("""communication();""")
-
-    def __init__(self, gpu):
-        ast_dict = {'gpu': gpu}
-        super().__init__(ast_dict)
-
-    headers = ["<algorithm>"]
-
-
-class VdbWriter(CppObjectConstruction):
-    def __init__(self, block_forest):
-        symbol = TypedSymbol('vdb', 'walberla_openvdb::OpenVdbFieldWriter')
-        super().__init__(symbol, [block_forest.blocks])
-
-    headers = ['"walberla_openvdb/OpenVdbFieldWriter.h"']
-
-    @property
-    def dtype(self):
-        return self.symbol.dtype
-
-    @property
-    def free_symbols(self):
-        return {}
-
-
-class WriteVdb(SweepOverAllBlocks):
-    TEMPLATE = jinja2.Template(
-        """{{vdb_writer}}.beginFile("{{output_path}}"{% if time %}, optional<float>({{time}}){% endif %});
-{% for f in fields  %}
-{%- if flag_field_id -%}
-{{ vdb_writer }}.addFieldFiltered<{{ f.walberla_field_type }}, VdbGrid_T<float>, FlagField_T>( {{f}}, "{{f}}", {{ flag_field_id }}, {{ fluid_uid }});
-{%- else -%}
-{{ vdb_writer }}.addField<{{ f.walberla_field_type }}, VdbGrid_T<float>>( {{f}}, "{{f}}");
-{%- endif -%}
-{% endfor %}
-{{vdb_writer}}.writeFile();""")  # noqa
-
-    def __init__(self, block_forest, output_path, fields_to_write, flag_field_id, fluid_uid, time=None):
-        functor = VdbWriter(block_forest)
-        ast_dict = {'fields': [BlockDataID(f, on_gpu=False) for f in fields_to_write],
-                    'output_path': output_path,
-                    'vdb_writer': functor.symbol,
-                    'flag_field_id': flag_field_id,
-                    'fluid_uid': fluid_uid,
-                    'functor': functor,
-                    'block_forest': block_forest,
-                    'time': time}
-        JinjaCppFile.__init__(self, ast_dict)
-
-    required_global_declarations = ["""template < typename T >
-using VdbGrid_T = openvdb::Grid < typename openvdb::tree::Tree4 < T, 5, 4, 3 >::Type >;"""]
-
-    @property
-    def undefined_symbols(self):
-        return {self.ast_dict.vdb_writer}
-
-
-class TimeLoopNode(ForLoop):
-    @property
-    def time(self):
-        return self.loop_symbol
diff --git a/src/pystencils_autodiff/walberla_main.tmpl.cpp b/src/pystencils_autodiff/walberla_main.tmpl.cpp
deleted file mode 100644
index 83968b619b3c20fcb40e794c4cc0d54c709f4b89..0000000000000000000000000000000000000000
--- a/src/pystencils_autodiff/walberla_main.tmpl.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-/* 
- * Automatically generated waLBerla main
- *
- */
-
-{% for header in headers -%}
-#include {{ header }}
-{% endfor %}
-{% for global in globals -%}
-{{ global }}
-{% endfor %}
-
-{{ main }}
diff --git a/src/pystencils_autodiff/walberla_user_defintions.tmpl.hpp b/src/pystencils_autodiff/walberla_user_defintions.tmpl.hpp
deleted file mode 100644
index 278e8fef9f1d5ce2fdc0361dafe15737c8cd1361..0000000000000000000000000000000000000000
--- a/src/pystencils_autodiff/walberla_user_defintions.tmpl.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * walberla_user_defintions.tmpl.hpp
- * Copyright (C) 2020 Stephan Seitz <stephan.seitz@fau.de>
- *
- * Distributed under terms of the GPLv3 license.
- */
-
-#pragma once
-
-
-{% for header in headers -%}
-#include {{ header }}
-{% endfor %}
-
-namespace walberla_user {
-using namespace walberla;
-{% if with_lbm %}
-using LatticeModel_T = lbm::{{ lb_model_name }};
-using Stencil_T = LatticeModel_T::Stencil;
-using CommunicationStencil_T = LatticeModel_T::CommunicationStencil;
-{% endif %}
-using flag_t = {{ flag_field_type }};
-using FlagField_T = FlagField<flag_t>;
-
-} // namespace walberla_user
diff --git a/tests/test_walberla.py b/tests/test_walberla.py
deleted file mode 100644
index 74e19b759fb02f92b6d6c70799eecb514ec1d11b..0000000000000000000000000000000000000000
--- a/tests/test_walberla.py
+++ /dev/null
@@ -1,188 +0,0 @@
-#
-# Copyright © 2020 Stephan Seitz <stephan.seitz@fau.de>
-#
-# Distributed under terms of the GPLv3 license.
-
-"""
-
-"""
-import os
-import sys
-from os.path import dirname, expanduser, join
-
-import numpy as np
-import sympy as sp
-
-import pystencils
-from pystencils.astnodes import Block, EmptyLine, SympyAssignment
-from pystencils.data_types import TypedSymbol, create_type
-from pystencils_autodiff._file_io import write_file
-from pystencils_autodiff.graph_datahandling import GraphDataHandling
-from pystencils_autodiff.simulation import Simulation
-from pystencils_autodiff.walberla import (
-    DefinitionsHeader, FieldAllocation, FlagFieldAllocation, GetParameter, ResolveUndefinedSymbols,
-    UniformBlockforestFromConfig, WalberlaMain, WalberlaModule)
-from pystencils_walberla.cmake_integration import ManualCodeGenerationContext
-
-
-def test_walberla():
-    x, y = pystencils.fields('x, y:  float32[3d]')
-    flags = pystencils.fields('flag_field:  float32[3d]')
-
-    foo_symbol = TypedSymbol('foo', np.bool)
-    number_symbol = TypedSymbol('number', np.float32)
-    crazy_plus_one = TypedSymbol('crazy', np.float32)
-
-    block_forest = UniformBlockforestFromConfig()
-
-    block = Block([
-        block_forest,
-        SympyAssignment(foo_symbol, GetParameter('parameters', foo_symbol)),
-        SympyAssignment(number_symbol, GetParameter('parameters', number_symbol, 1.2)),
-        SympyAssignment(crazy_plus_one, number_symbol + 1),
-        EmptyLine(),
-        FieldAllocation(block_forest.blocks, x, on_gpu=False),
-        FlagFieldAllocation(block_forest.blocks, flags)
-    ])
-
-    module = WalberlaModule(WalberlaMain(block))
-    code = str(module)
-    print(code)
-
-    write_file('/localhome/seitz_local/projects/walberla/apps/autogen/main.cpp', code)
-
-    definitions = DefinitionsHeader(module, 'uint8_t')
-    write_file('/localhome/seitz_local/projects/walberla/apps/autogen/UserDefinitions.h', str(definitions))
-
-
-def test_wald_wiesen_simulation():
-    with ManualCodeGenerationContext() as ctx:
-        dh = GraphDataHandling((30, 30),
-                               periodicity=False,
-                               default_ghost_layers=1,
-                               default_target='cpu')
-        dh.add_arrays('x, y')
-        dh.add_arrays('w, z', gpu=True)
-
-        sim = Simulation(dh, ctx)
-        print(sim._create_module())
-
-
-def test_wald_wiesen_lbm():
-    import pytest
-    pytest.importorskip('lbmpy')
-    from lbmpy.creationfunctions import create_lb_collision_rule
-    sys.path.append(dirname(__file__))
-    with ManualCodeGenerationContext() as ctx:
-        from test_graph_datahandling import ldc_setup
-        opt_params = {'target': 'gpu'}
-        import sympy as sp
-        lid_velocity = sp.symbols('lid_velocity')
-        lbm_step = ldc_setup(domain_size=(30, 30), optimization=opt_params,
-                             fixed_loop_sizes=False, lid_velocity=lid_velocity)
-
-        del lbm_step.data_handling.gpu_arrays.ldc_pdf_tmp
-
-        sim = Simulation(lbm_step.data_handling,
-                         ctx,
-                         lbm_step.boundary_handling,
-                         create_lb_collision_rule(lbm_step.method, optimization=opt_params),
-                         cmake_target_name='autogen')
-        sim.write_files()
-
-        dir = '/localhome/seitz_local/projects/walberla/apps/autogen/'
-        os.makedirs(dir, exist_ok=True)
-        for k, v in ctx.files.items():
-            with open(join(dir, k), 'w') as file:
-                file.write(v)
-
-
-def test_projection():
-    volume = pystencils.fields('volume: float32[3d]')
-    projections = pystencils.fields('projection: float32[2d]')
-    spacing, foo = sp.symbols('spacing, foo')
-
-    from pystencils_walberla.special_symbols import aabb_min_vector, dx_vector, global_coord
-    import pystencils_reco.projection
-
-    from sympy.matrices.dense import matrix_multiply_elementwise
-    volume.coordinate_transform = lambda x: aabb_min_vector + matrix_multiply_elementwise(x, dx_vector)
-    projections.set_coordinate_origin_to_field_center()
-    projections.coordinate_transform *= spacing
-
-    from pystencils.interpolation_astnodes import TextureDeclaration
-    TextureDeclaration.headers = []
-    projection_matrix = pystencils_reco.matrix_symbols('T', pystencils.data_types.create_type('float32'), 3, 4)
-    from pystencils.kernelparameters import FieldPointerSymbol, FieldStrideSymbol
-
-    assignments = pystencils_reco.projection.forward_projection(volume, projections, projection_matrix)
-    assignments.main_assignments.append(pystencils.Assignment(foo, FieldPointerSymbol(
-        volume.name, volume.dtype, const=True) + FieldStrideSymbol(volume.name, 0) + FieldStrideSymbol(volume.name, 1)))
-    assignments.subs({a: b for a, b in zip(pystencils.x_vector(3), global_coord)})
-    assignments.kwargs = {}
-    print(assignments)
-    kernel = assignments.compile('gpu')
-    pystencils.show_code(kernel)
-
-    with ManualCodeGenerationContext() as ctx:
-
-        dh = GraphDataHandling((300, 300, 300))
-        volume, projections = dh.add_arrays('volume, projection', gpu=True)
-
-        dh.run_kernel(kernel, simulate_only=True)
-
-        sim = Simulation(dh, ctx, cmake_target_name='projection')
-        sim._debug = False
-        sim.write_files()
-
-        dir = '/localhome/seitz_local/projects/walberla/apps/projection/'
-        os.makedirs(dir, exist_ok=True)
-        for k, v in ctx.files.items():
-            with open(join(dir, k), 'w') as file:
-                file.write(v)
-
-
-def test_global_idx():
-    with ManualCodeGenerationContext() as ctx:
-        from pystencils_walberla.special_symbols import aabb_min_vector, global_coord
-
-        dh = GraphDataHandling((20, 30, 40))
-        my_array = dh.add_array('my_array')
-
-        ast = pystencils.create_kernel([pystencils.Assignment(
-            my_array.center, sum(aabb_min_vector))]).compile()
-        dh.run_kernel(ast, simulate_only=True)
-        dh.save_fields('my_array', expanduser('~/foo'))
-        ast = pystencils.create_kernel([pystencils.Assignment(
-            my_array.center, sum(global_coord))]).compile()
-        dh.run_kernel(ast, simulate_only=True)
-        dh.save_fields('my_array', expanduser('~/foo2'))
-        # ast = pystencils.create_kernel([pystencils.Assignment(my_array.center, sum(current_global_idx))]).compile()
-        # dh.run_kernel(ast, simulate_only=True)
-
-        sim = Simulation(dh, ctx, cmake_target_name='foo')
-        sim._debug = False
-        sim.write_files()
-
-        dir = '/localhome/seitz_local/projects/walberla/apps/foo/'
-        os.makedirs(dir, exist_ok=True)
-        for k, v in ctx.files.items():
-            with open(join(dir, k), 'w') as file:
-                file.write(v)
-
-
-def test_resolve_parameters():
-    sym = TypedSymbol('s', create_type('double'))
-    sym2 = TypedSymbol('t', create_type('double'))
-
-    block_forest = UniformBlockforestFromConfig()
-
-    module = WalberlaModule(WalberlaMain(Block([
-        block_forest,
-        ResolveUndefinedSymbols(
-            Block([
-                SympyAssignment(sym, 1 + sym2),
-            ]), 'parameters')
-    ])))
-
-    print(module)