diff --git a/createmethodfromdict.py b/creationfunctions.py
similarity index 100%
rename from createmethodfromdict.py
rename to creationfunctions.py
diff --git a/macroscopicValueKernels.py b/macroscopicValueKernels.py
new file mode 100644
index 0000000000000000000000000000000000000000..679f36843f62868070e291a5581349d21427d09c
--- /dev/null
+++ b/macroscopicValueKernels.py
@@ -0,0 +1,230 @@
+import sympy as sp
+
+from pystencils.field import Field
+import pystencils.cpu as cpu
+import pystencils.gpucuda as gpu
+
+
+def compileMacroscopicValuesGetter(lbMethod, outputQuantities, pdfArr=None, fieldLayout='numpy', target='cpu'):
+    """
+
+    :param lbMethod:
+    :param outputQuantities:
+    :param pdfArr:
+    :param fieldLayout: layout for output field, also used for pdf field if pdfArr is not given
+    :param target:
+    :return: a function to compute macroscopic values:
+        - pdfArray, can be omitted if pdf array was already passed while compiling
+        - densityOut, if not None, density is written to that array
+        - velocityOut, if not None, velocity is written to that array
+    """
+    cqc = lbMethod.conservedQuantityComputation
+    unknownQuantities = [oq for oq in outputQuantities if oq not in cqc.conservedQuantities]
+    if unknownQuantities:
+        raise ValueError("No such conserved quantity: %s, conserved quantities are %s" %
+                         (str(unknownQuantities), str(cqc.conservedQuantities.keys())))
+
+    if pdfArr is None:
+        pdfField = Field.createGeneric('pdfs', lbMethod.dim, indexDimensions=1, layout=fieldLayout)
+    else:
+        pdfField = Field.createFromNumpyArray('pdfs', pdfArr, indexDimensions=1)
+
+    outputMapping = {}
+    for outputQuantity in outputQuantities:
+        numberOfElements = cqc.conservedQuantityComputation[outputQuantity]
+        assert numberOfElements >= 1
+        outputField = Field.createGeneric(outputQuantity, lbMethod.dim, layout=fieldLayout,
+                                          indexDimensions=0 if numberOfElements <= 1 else 1)
+
+        outputMapping[outputQuantity] = [outputField(i) for i in range(numberOfElements)]
+        if len(outputMapping[outputQuantity]) == 1:
+            outputMapping[outputQuantity] = outputMapping[outputQuantity][0]
+
+    stencil = lbMethod.stencil
+    pdfSymbols = [pdfField(i) for i in range(len(stencil))]
+    eqs = cqc.outputEquationsFromPdfs(pdfSymbols, outputMapping)
+
+    if target == 'cpu':
+        kernel = cpu.makePythonFunction(cpu.createKernel(eqs))
+    elif target == 'gpu':
+        kernel = gpu.makePythonFunction(gpu.createCUDAKernel(eqs))
+    else:
+        raise ValueError("Unknown target '%s'. Possible targets are 'cpu' and 'gpu'" % (target,))
+
+    def getter(pdfs=None, **kwargs):
+        if pdfArr is not None:
+            assert pdfs.shape == pdfArr.shape and pdfs.strides == pdfArr.strides, \
+                "Pdf array not matching blueprint which was used to compile" + str(pdfs.shape) + str(pdfArr.shape)
+            if not set(kwargs.keys()).issubset(set(outputQuantities)):
+                raise ValueError("You have to specify the output field for each of the following quantities: %s"
+                                 % (str(outputQuantities),))
+            kernel(pdfs=pdfs, **kwargs)
+
+    return getter
+
+
+def compileMacroscopicValuesGetter(lbMethod, pdfArr=None, macroscopicFieldLayout='numpy'):
+    """
+    Creates a function that computes density and/or velocity and stores it into given arrays
+    :param lbMethod: lattice model (to get information about stencil, force velocity shift and compressibility)
+    :param pdfArr: array to set can already be specified here, or later when the returned function is called
+    :param macroscopicFieldLayout: layout specification for Field.createGeneric
+    :return: a function, which has three parameters:
+        - pdfArray, can be omitted if pdf array was already passed while compiling
+        - densityOut, if not None, density is written to that array
+        - velocityOut, if not None, velocity is written to that array
+    """
+    if pdfArr is None:
+        pdfField = Field.createGeneric('pdfs', lbMethod.dim, indexDimensions=1)
+    else:
+        pdfField = Field.createFromNumpyArray('pdfs', pdfArr, indexDimensions=1)
+
+    rhoField = Field.createGeneric('rho', lbMethod.dim, indexDimensions=0, layout=macroscopicFieldLayout)
+    velField = Field.createGeneric('vel', lbMethod.dim, indexDimensions=1, layout=macroscopicFieldLayout)
+
+    lm = lbMethod
+    Q = len(lm.stencil)
+    symPdfs = [pdfField(i) for i in range(Q)]
+    subexpressions, rho, velSubexpressions, u = getDensityVelocityExpressions(lm.stencil, symPdfs, lm.compressible)
+
+    uRhs = [u_i.rhs for u_i in u]
+    uLhs = [u_i.lhs for u_i in u]
+    if hasattr(lm.forceModel, "macroscopicVelocity"):
+        correctedVel = lm.forceModel.macroscopicVelocity(lm, uRhs, rho.lhs)
+        u = [sp.Eq(a, b) for a, b in zip(uLhs, correctedVel)]
+
+    eqsRhoKernel = subexpressions + [sp.Eq(rhoField(0), rho.rhs)]
+    eqsVelKernel = subexpressions + [rho] + velSubexpressions + [sp.Eq(velField(i), u[i].rhs) for i in range(lm.dim)]
+    eqsRhoAndVelKernel = eqsVelKernel + [sp.Eq(rhoField(0), rho.lhs)]
+
+    stencil = lbMethod.stencil
+    cqc = lbMethod.conservedQuantityComputation
+    pdfSymbols = [pdfField(i) for i in range(len(stencil))]
+    eqsDensity  = cqc.outputEquationsFromPdfs(pdfSymbols, {'density': rhoField(0)})
+    eqsVelocity = cqc.outputEquationsFromPdfs(pdfSymbols, {'velocity': [velField(i) for i in range(lbMethod.dim)]})
+
+    kernelRho = makePythonFunction(createKernel(eqsRhoKernel))
+    kernelVel = makePythonFunction(createKernel(eqsVelKernel))
+    kernelRhoAndVel = makePythonFunction(createKernel(eqsRhoAndVelKernel))
+
+    def getter(pdfs=None, densityOut=None, velocityOut=None):
+        if pdfs is not None and pdfArr is not None:
+            assert pdfs.shape == pdfArr.shape and pdfs.strides == pdfArr.strides, \
+                "Pdf array not matching blueprint which was used to compile" + str(pdfs.shape) + str(pdfArr.shape)
+        if pdfs is None:
+            assert pdfArr is not None, "Pdf array has to be passed either when compiling or when calling."
+            pdfs = pdfArr
+
+        assert not (densityOut is None and velocityOut is None), \
+            "Specify either densityOut or velocityOut parameter or both"
+
+        if densityOut is not None and velocityOut is None:
+            kernelRho(pdfs=pdfs, rho=densityOut)
+        elif densityOut is None and velocityOut is not None:
+            kernelVel(pdfs=pdfs, vel=velocityOut)
+        else:
+            kernelRhoAndVel(pdfs=pdfs, rho=densityOut, vel=velocityOut)
+
+    return getter
+
+
+def compileAdvancedVelocitySetter(collisionRule, velocityArray, pdfArr=None):
+    """
+    Advanced initialization of velocity field through iteration procedure according to
+    Mei, Luo, Lallemand and Humieres: Consistent initial conditions for LBM simulations, 2005
+
+    Important: this procedure only works if a non-zero relaxation rate was used for the velocity moments!
+
+    :param collisionRule: unsimplified collision rule
+    :param velocityArray: array with velocity field
+    :param pdfArr: optional array, to compile kernel with fixed layout and shape
+    :return: function, that has to be called multiple times, with a pdf field (src/dst) until convergence
+             similar to the normal streamCollide step, also with boundary handling
+    """
+    velocityField = Field.createFromNumpyArray('vel', velocityArray, indexDimensions=1)
+
+    # create normal LBM kernel and replace velocity by expressions of velocity field
+    from lbmpy_old.simplifications import sympyCSE
+    latticeModel = collisionRule.latticeModel
+    collisionRule = sympyCSE(collisionRule)
+    collisionRule = streamPullWithSourceAndDestinationFields(collisionRule, pdfArr)
+
+    replacements = {u_i: sp.Eq(u_i, velocityField(i)) for i, u_i in enumerate(latticeModel.symbolicVelocity)}
+
+    newSubExpressions = [replacements[eq.lhs] if eq.lhs in replacements else eq for eq in collisionRule.subexpressions]
+    newCollisionRule = LbmCollisionRule(collisionRule.updateEquations, newSubExpressions,
+                                        latticeModel, collisionRule.updateEquationDirections)
+    kernelAst = createKernel(newCollisionRule.equations)
+    return makePythonFunction(kernelAst, {'vel': velocityArray})
+
+
+def compileMacroscopicValuesSetter(latticeModel, density=1, velocity=0, equilibriumOrder=2, pdfArr=None):
+    """
+    Creates a function that sets a pdf field to specified macroscopic quantities
+    The returned function can be called with the pdf field to set as single argument
+
+    :param latticeModel: lattice model (to get information about stencil, force velocity shift and compressibility)
+    :param density: density used for equilibrium. Can either be scalar (all cells are set to same density) or array
+    :param velocity: velocity for equilibrium. Can either be scalar (e.g. 0, sets all cells to (0,0,0) velocity)
+                    or a tuple with D (2 or 3) entries to set same velocity in  the complete domain, or an array
+                    specifying the velocity for each cell
+    :param equilibriumOrder: approximation order of equilibrium
+    :param pdfArr: array to set can already be specified here, or later when the returned function is called
+    """
+    if pdfArr is not None:
+        pdfField = Field.createFromNumpyArray('pdfs', pdfArr, indexDimensions=1)
+    else:
+        pdfField = Field.createGeneric('pdfs', latticeModel.dim, indexDimensions=1)
+
+    noOffset = tuple([0] * latticeModel.dim)
+    kernelArguments = {}
+
+    if hasattr(density, 'shape'):
+        densityValue = Field.createFromNumpyArray('rho', density, indexDimensions=0)[noOffset]
+        kernelArguments['rho'] = density
+    else:
+        densityValue = density
+
+    if hasattr(velocity, 'shape'):
+        assert velocity.shape[-1] == latticeModel.dim, "Wrong shape of velocity array"
+        velocityValue = [Field.createFromNumpyArray('vel', velocity, indexDimensions=1)[noOffset](i)
+                         for i in range(latticeModel.dim)]
+        kernelArguments['vel'] = velocity
+    else:
+        if not hasattr(velocity, "__len__"):
+            velocity = [velocity] * latticeModel.dim
+        velocityValue = tuple(velocity)
+
+    # force shift
+    if latticeModel.forceModel and hasattr(latticeModel.forceModel, "macroscopicVelocity"):
+        # force model knows only about one direction - use sympy to solve the shift equations to get backward
+        fm = latticeModel.forceModel
+        unshiftedVel = [sp.Symbol("v_unshifted_%d" % (i,)) for i in range(latticeModel.dim)]
+        shiftedVel = fm.macroscopicVelocity(latticeModel, unshiftedVel, densityValue)
+        velShiftEqs = [sp.Eq(a, b) for a, b in zip(velocityValue, shiftedVel)]
+        solveRes = sp.solve(velShiftEqs, unshiftedVel)
+        assert len(solveRes) == latticeModel.dim
+        velocityValue = [solveRes[unshiftedVel_i] for unshiftedVel_i in unshiftedVel]
+
+    eq = standardDiscreteEquilibrium(latticeModel.stencil, densityValue, velocityValue, equilibriumOrder,
+                                     c_s_sq=sp.Rational(1, 3), compressible=latticeModel.compressible)
+    updateEquations = [sp.Eq(pdfField(i), eq[i]) for i in range(len(latticeModel.stencil))]
+    f = makePythonFunction(createKernel(updateEquations), kernelArguments)
+
+    def setter(pdfs=None, **kwargs):
+        if pdfs is not None and pdfArr is not None:
+            assert pdfs.shape == pdfArr.shape and pdfs.strides == pdfArr.strides, \
+                "Pdf array not matching blueprint which was used to compile"
+
+        if pdfs is None:
+            assert pdfArr is not None, "Pdf array has to be passed either when compiling or when calling."
+            pdfs = pdfArr
+        assert pdfs.shape[-1] == len(latticeModel.stencil), "Wrong shape of pdf array"
+        assert len(pdfs.shape) == latticeModel.dim + 1, "Wrong shape of pdf array"
+        if hasattr(density, 'shape'):
+            assert pdfs.shape[:-1] == density.shape, "Density array shape does not match pdf array shape"
+        if hasattr(velocity, 'shape'):
+            assert pdfs.shape[:-1] == velocity.shape[:-1], "Velocity array shape does not match pdf array shape"
+        f(pdfs=pdfs, **kwargs)  # kwargs passed here, since force model might need additional fields
+
+    return setter
diff --git a/methods/__init__.py b/methods/__init__.py
index 230ec443b76472993d249870a6d9332e43228ef0..e187d0ab43733ea92530fd0504937c1fe639a0ee 100644
--- a/methods/__init__.py
+++ b/methods/__init__.py
@@ -1,5 +1,5 @@
-from lbmpy.methods.abstractlbmmethod import AbstractLbmMethod
-from lbmpy.methods.momentbased import MomentBasedLbmMethod, RelaxationInfo
+from lbmpy.methods.abstractlbmmethod import AbstractLbMethod
+from lbmpy.methods.momentbased import MomentBasedLbMethod, RelaxationInfo
 from lbmpy.methods.momentbased import createSRT, createTRT, createTRTWithMagicNumber, createOrthogonalMRT, \
     createWithContinuousMaxwellianEqMoments, createWithDiscreteMaxwellianEqMoments
 from lbmpy.methods.conservedquantitycomputation import AbstractConservedQuantityComputation, DensityVelocityComputation
diff --git a/methods/abstractlbmmethod.py b/methods/abstractlbmethod.py
similarity index 97%
rename from methods/abstractlbmmethod.py
rename to methods/abstractlbmethod.py
index 8cd720ab08d3fb92e4575a71020b4b126a07b3e6..201ab0547a44c4b9b8f60c0410a5476c36dd56b7 100644
--- a/methods/abstractlbmmethod.py
+++ b/methods/abstractlbmethod.py
@@ -9,7 +9,7 @@ class LbmCollisionRule(EquationCollection):
         self.method = lbmMethod
 
 
-class AbstractLbmMethod(metaclass=abc.ABCMeta):
+class AbstractLbMethod(metaclass=abc.ABCMeta):
     """
     Abstract base class for all LBM methods
     """
diff --git a/methods/conservedquantitycomputation.py b/methods/conservedquantitycomputation.py
index a65d2a46804c73f6c5e444be135db7935f94172a..5e07c2aa91d74420bcc90a01ed9e6e9696213e0e 100644
--- a/methods/conservedquantitycomputation.py
+++ b/methods/conservedquantitycomputation.py
@@ -53,14 +53,14 @@ class AbstractConservedQuantityComputation(metaclass=abc.ABCMeta):
         """
 
     @abc.abstractmethod
-    def outputEquationsFromPdfs(self, pdfs, outputQuantityNames):
+    def outputEquationsFromPdfs(self, pdfs, outputQuantityNamesToSymbols):
         """
         Returns an equation collection that defines conserved quantities for output. These conserved quantities might
         be slightly different that the ones used as input for the equilibrium e.g. due to a force model.
 
         :param pdfs: values for the pdf entries
-        :param outputQuantityNames: list of conserved quantity names, defining which parameters should be written out.
-                                    See :func:`conservedQuantities`
+        :param outputQuantityNamesToSymbols: dict mapping of conserved quantity names (See :func:`conservedQuantities`)
+                                            to symbols or field accesses where they should be written to
         """
 
     @abc.abstractmethod
diff --git a/methods/momentbased.py b/methods/momentbased.py
index c5fe7d97acf6a56f54bd8412e8b6cb6859795d80..198ed4f3c31d1afbe3e6334eca763f8e74a3de61 100644
--- a/methods/momentbased.py
+++ b/methods/momentbased.py
@@ -5,7 +5,7 @@ from collections import namedtuple, OrderedDict, defaultdict
 from lbmpy.stencils import stencilsHaveSameEntries, getStencil
 from lbmpy.maxwellian_equilibrium import getMomentsOfDiscreteMaxwellianEquilibrium, \
     getMomentsOfContinuousMaxwellianEquilibrium
-from lbmpy.methods.abstractlbmmethod import AbstractLbmMethod, LbmCollisionRule
+from lbmpy.methods.abstractlbmmethod import AbstractLbMethod, LbmCollisionRule
 from lbmpy.methods.conservedquantitycomputation import AbstractConservedQuantityComputation, DensityVelocityComputation
 from lbmpy.moments import MOMENT_SYMBOLS, momentMatrix, isShearMoment, \
     isEven, gramSchmidt, getOrder, getDefaultMomentSetForStencil
@@ -14,7 +14,7 @@ from pystencils.sympyextensions import commonDenominator, replaceAdditive
 RelaxationInfo = namedtuple('Relaxationinfo', ['equilibriumValue', 'relaxationRate'])
 
 
-class MomentBasedLbmMethod(AbstractLbmMethod):
+class MomentBasedLbMethod(AbstractLbMethod):
     def __init__(self, stencil, momentToRelaxationInfoDict, conservedQuantityComputation, forceModel=None):
         """
         Moment based LBM is a class to represent the single (SRT), two (TRT) and multi relaxation time (MRT) methods.
@@ -31,7 +31,7 @@ class MomentBasedLbmMethod(AbstractLbmMethod):
                                              the symbols used in the equilibrium moments like e.g. density and velocity
         :param forceModel: force model instance, or None if no forcing terms are required
         """
-        super(MomentBasedLbmMethod, self).__init__(stencil)
+        super(MomentBasedLbMethod, self).__init__(stencil)
 
         assert isinstance(conservedQuantityComputation, AbstractConservedQuantityComputation)
 
@@ -272,7 +272,7 @@ def createWithDiscreteMaxwellianEqMoments(stencil, momentToRelaxationRateDict, c
                                                           compressible=compressible, order=equilibriumAccuracyOrder)
     rrDict = OrderedDict([(mom, RelaxationInfo(eqMom, rr))
                           for mom, rr, eqMom in zip(momToRrDict.keys(), momToRrDict.values(), eqMoments)])
-    return MomentBasedLbmMethod(stencil, rrDict, densityVelocityComputation, forceModel)
+    return MomentBasedLbMethod(stencil, rrDict, densityVelocityComputation, forceModel)
 
 
 def createWithContinuousMaxwellianEqMoments(stencil, momentToRelaxationRateDict, forceModel=None,
@@ -292,7 +292,7 @@ def createWithContinuousMaxwellianEqMoments(stencil, momentToRelaxationRateDict,
                                                             order=equilibriumAccuracyOrder)
     rrDict = OrderedDict([(mom, RelaxationInfo(eqMom, rr))
                           for mom, rr, eqMom in zip(momToRrDict.keys(), momToRrDict.values(), eqMoments)])
-    return MomentBasedLbmMethod(stencil, rrDict, densityVelocityComputation, forceModel)
+    return MomentBasedLbMethod(stencil, rrDict, densityVelocityComputation, forceModel)
 
 
 # ------------------------------------ SRT / TRT/ MRT Creators ---------------------------------------------------------
diff --git a/plot2d.py b/plot2d.py
new file mode 100644
index 0000000000000000000000000000000000000000..b1bb364721d143a77814256105d9cabdf847db2f
--- /dev/null
+++ b/plot2d.py
@@ -0,0 +1,47 @@
+from matplotlib.pyplot import *
+
+
+def removeGhostLayers(field):
+    return field[1:-1, 1:-1]
+
+
+def vectorField(field, step=2, **kwargs):
+    field = removeGhostLayers(field)
+    veln = field.swapaxes(0, 1)
+    quiver(veln[::step, ::step, 0], veln[::step, ::step, 1], **kwargs)
+
+
+def vectorFieldMagnitude(field, **kwargs):
+    from numpy.linalg import norm
+    field = norm(field, axis=2, ord=2)
+    return scalarField(field, **kwargs)
+
+
+def scalarField(field, **kwargs):
+    import numpy as np
+    field = removeGhostLayers(field)
+    field = np.swapaxes(field, 0, 1)
+    return imshow(field, origin='lower', **kwargs)
+
+
+def vectorFieldMagnitudeAnimation(runFunction, plotSetupFunction=lambda: None,
+                                  plotUpdateFunction=lambda: None, interval=30, frames=180, **kwargs):
+    import matplotlib.animation as animation
+    import numpy as np
+    from numpy.linalg import norm
+
+    fig = gcf()
+    im = None
+    field = runFunction()
+    im = vectorFieldMagnitude(field, **kwargs)
+    plotSetupFunction()
+
+    def updatefig(*args):
+        f = runFunction()
+        f = norm(f, axis=2, ord=2)
+        f = np.swapaxes(f, 0, 1)
+        im.set_array(f)
+        plotUpdateFunction()
+        return im,
+
+    return animation.FuncAnimation(fig, updatefig, interval=interval, frames=frames)
diff --git a/simplificationfactory.py b/simplificationfactory.py
index b6f42ac057ddadc4696799db0d57205938846bbd..ba8962f9ee1cb164d7a8c8c67a0bdab49b111cbd 100644
--- a/simplificationfactory.py
+++ b/simplificationfactory.py
@@ -8,14 +8,14 @@ from pystencils.equationcollection.simplifications import applyOnAllEquations, \
 
 def createSimplificationStrategy(lbmMethod, doCseInOpposingDirections=False, doOverallCse=False, splitInnerLoop=False):
     from pystencils.equationcollection import SimplificationStrategy
-    from lbmpy.methods import MomentBasedLbmMethod
+    from lbmpy.methods import MomentBasedLbMethod
     from lbmpy.methods.momentbasedsimplifications import replaceSecondOrderVelocityProducts, \
         factorDensityAfterFactoringRelaxationTimes, factorRelaxationRates, cseInOpposingDirections, \
         replaceCommonQuadraticAndConstantTerm, replaceDensityAndVelocity
 
     s = SimplificationStrategy()
 
-    if isinstance(lbmMethod, MomentBasedLbmMethod):
+    if isinstance(lbmMethod, MomentBasedLbMethod):
         expand = partial(applyOnAllEquations, operation=sp.expand)
         expand.__name__ = "expand"