diff --git a/astnodes.py b/astnodes.py
index 5a3602f410570a1978d946c2671342e3f25d91dd..f6c2d24de3cf93660b49d1ca563e3e92d49b694e 100644
--- a/astnodes.py
+++ b/astnodes.py
@@ -40,9 +40,10 @@ class Node(object):
 class KernelFunction(Node):
 
     class Argument:
-        def __init__(self, name, dtype):
+        def __init__(self, name, dtype, kernelFunctionNode):
+            from pystencils.transformations import symbolNameToVariableName
             self.name = name
-            self.dtype = dtype  # TODO ordentliche Klasse
+            self.dtype = dtype
             self.isFieldPtrArgument = False
             self.isFieldShapeArgument = False
             self.isFieldStrideArgument = False
@@ -63,6 +64,11 @@ class KernelFunction(Node):
                 self.isFieldArgument = True
                 self.fieldName = name[len(Field.STRIDE_PREFIX):]
 
+            self.field = None
+            if self.isFieldArgument:
+                fieldMap = {symbolNameToVariableName(f.name): f for f in kernelFunctionNode.fieldsAccessed}
+                self.field = fieldMap[self.fieldName]
+
         def __repr__(self):
             return '<{0} {1}>'.format(self.dtype, self.name)
 
@@ -105,12 +111,11 @@ class KernelFunction(Node):
 
     def _updateParameters(self):
         undefinedSymbols = self._body.undefinedSymbols - self.globalVariables
-        self._parameters = [KernelFunction.Argument(s.name, s.dtype) for s in undefinedSymbols]
+        self._parameters = [KernelFunction.Argument(s.name, s.dtype, self) for s in undefinedSymbols]
         self._parameters.sort(key=lambda l: (l.fieldName, l.isFieldPtrArgument, l.isFieldShapeArgument,
                                              l.isFieldStrideArgument, l.name),
                               reverse=True)
 
-
     def __str__(self):
         self._updateParameters()
         return '{0} {1}({2})\n{3}'.format(type(self).__name__, self.functionName, self.parameters,
diff --git a/cpu/cpujit.py b/cpu/cpujit.py
index 18429d1200c9a04f0c50cb7abc994c43398ff63a..2bc08985668322a96bba9a4a737d9d98bb4ccc57 100644
--- a/cpu/cpujit.py
+++ b/cpu/cpujit.py
@@ -10,7 +10,7 @@ import hashlib
 from pystencils.transformations import symbolNameToVariableName
 
 CONFIG_GCC = {
-    'compiler': 'g++',
+    'compiler': 'g++-4.8',
     'flags': '-Ofast -DNDEBUG -fPIC -shared -march=native -fopenmp',
 }
 CONFIG_INTEL = {
@@ -108,11 +108,24 @@ def compileAndLoad(kernelFunctionNode):
 def buildCTypeArgumentList(parameterSpecification, argumentDict):
     argumentDict = {symbolNameToVariableName(k): v for k, v in argumentDict.items()}
     ctArguments = []
+    arrayShapes = set()
     for arg in parameterSpecification:
         if arg.isFieldArgument:
             field = argumentDict[arg.fieldName]
+            symbolicField = arg.field
             if arg.isFieldPtrArgument:
                 ctArguments.append(field.ctypes.data_as(ctypeFromString(arg.dtype)))
+                if symbolicField.hasFixedShape:
+                    if tuple(int(i) for i in symbolicField.shape) != field.shape:
+                        raise ValueError("Passed array '%s' has shape %s which does not match expected shape %s" %
+                                         (arg.fieldName, str(field.shape), str(symbolicField.shape)))
+                if symbolicField.hasFixedShape:
+                    if tuple(int(i) * field.itemsize for i in symbolicField.strides) != field.strides:
+                        raise ValueError("Passed array '%s' has strides %s which does not match expected strides %s" %
+                                         (arg.fieldName, str(field.strides), str(symbolicField.strides)))
+
+                if not symbolicField.isIndexField:
+                    arrayShapes.add(field.shape[:symbolicField.spatialDimensions])
             elif arg.isFieldShapeArgument:
                 dataType = ctypeFromString(arg.dtype, includePointers=False)
                 ctArguments.append(field.ctypes.shape_as(dataType))
@@ -130,6 +143,9 @@ def buildCTypeArgumentList(parameterSpecification, argumentDict):
             param = argumentDict[arg.name]
             expectedType = ctypeFromString(arg.dtype)
             ctArguments.append(expectedType(param))
+
+    if len(arrayShapes) > 1:
+        raise ValueError("All passed arrays have to have the same size " + str(arrayShapes))
     return ctArguments
 
 
diff --git a/field.py b/field.py
index 18ea09dafc997cec4f129fb507e278bd0e0f8465..2b3c19e9da4a77dd9d718bb31d9d8f6395ceb1cd 100644
--- a/field.py
+++ b/field.py
@@ -46,8 +46,34 @@ class Field:
         Eq(dst_C^0, src_C^0)
         Eq(dst_C^1, src_S^1)
         Eq(dst_C^2, src_N^2)
-
     """
+
+    @staticmethod
+    def createGeneric(fieldName, spatialDimensions, dtype=np.float64, indexDimensions=0, layout='numpy'):
+        """
+        Creates a generic field where the field size is not fixed i.e. can be called with arrays of different sizes
+
+        :param fieldName: symbolic name for the field
+        :param dtype: numpy data type of the array the kernel is called with later
+        :param spatialDimensions: see documentation of Field
+        :param indexDimensions: see documentation of Field
+        :param layout: tuple specifying the loop ordering of the spatial dimensions e.g. (2, 1, 0 ) means that
+                       the outer loop loops over dimension 2, the second outer over dimension 1, and the inner loop
+                       over dimension 0. Also allowed: the strings 'numpy' (0,1,..d) or 'reverseNumpy' (d, ..., 1, 0)
+        """
+        if isinstance(layout, str) and (layout == 'numpy' or layout.lower() == 'c'):
+            layout = tuple(range(spatialDimensions))
+        elif isinstance(layout, str) and (layout == 'reverseNumpy' or layout.lower() == 'f'):
+            layout = tuple(reversed(range(spatialDimensions)))
+        if len(layout) != spatialDimensions:
+            raise ValueError("Layout")
+        shapeSymbol = IndexedBase(TypedSymbol(Field.SHAPE_PREFIX + fieldName, Field.SHAPE_DTYPE), shape=(1,))
+        strideSymbol = IndexedBase(TypedSymbol(Field.STRIDE_PREFIX + fieldName, Field.STRIDE_DTYPE), shape=(1,))
+        totalDimensions = spatialDimensions + indexDimensions
+        shape = tuple([shapeSymbol[i] for i in range(totalDimensions)])
+        strides = tuple([strideSymbol[i] for i in range(totalDimensions)])
+        return Field(fieldName, dtype, layout, shape, strides)
+
     @staticmethod
     def createFromNumpyArray(fieldName, npArray, indexDimensions=0):
         """
@@ -66,43 +92,43 @@ class Field:
         assert len(spatialLayout) == spatialDimensions
 
         strides = tuple([s // np.dtype(npArray.dtype).itemsize for s in npArray.strides])
-        shape = tuple([int(s) for s in npArray.shape])
+        shape = tuple(int(s) for s in npArray.shape)
 
         return Field(fieldName, npArray.dtype, spatialLayout, shape, strides)
 
     @staticmethod
-    def createGeneric(fieldName, spatialDimensions, dtype=np.float64, indexDimensions=0, layout='numpy'):
+    def createFixedSize(fieldName, shape, indexDimensions=0, dtype=np.float64, layout='numpy'):
         """
-        Creates a generic field where the field size is not fixed i.e. can be called with arrays of different sizes
+        Creates a field with fixed sizes i.e. can be called only wity arrays of the same size and layout
 
         :param fieldName: symbolic name for the field
+        :param shape: overall shape of the array
+        :param indexDimensions: how many of the trailing dimensions are interpreted as index (as opposed to spatial)
         :param dtype: numpy data type of the array the kernel is called with later
-        :param spatialDimensions: see documentation of Field
-        :param indexDimensions: see documentation of Field
-        :param layout: tuple specifying the loop ordering of the spatial dimensions e.g. (2, 1, 0 ) means that
-                       the outer loop loops over dimension 2, the second outer over dimension 1, and the inner loop
-                       over dimension 0. Also allowed: the strings 'numpy' (0,1,..d) or 'reverseNumpy' (d, ..., 1, 0)
+        :param layout: see createGeneric
         """
+        spatialDimensions = len(shape) - indexDimensions
+        assert spatialDimensions >= 1
+
         if isinstance(layout, str) and (layout == 'numpy' or layout.lower() == 'c'):
             layout = tuple(range(spatialDimensions))
         elif isinstance(layout, str) and (layout == 'reverseNumpy' or layout.lower() == 'f'):
             layout = tuple(reversed(range(spatialDimensions)))
-        if len(layout) != spatialDimensions:
-            raise ValueError("Layout")
-        shapeSymbol = IndexedBase(TypedSymbol(Field.SHAPE_PREFIX + fieldName, Field.SHAPE_DTYPE), shape=(1,))
-        strideSymbol = IndexedBase(TypedSymbol(Field.STRIDE_PREFIX + fieldName, Field.STRIDE_DTYPE), shape=(1,))
-        totalDimensions = spatialDimensions + indexDimensions
-        shape = tuple([shapeSymbol[i] for i in range(totalDimensions)])
-        strides = tuple([strideSymbol[i] for i in range(totalDimensions)])
-        return Field(fieldName, dtype, layout, shape, strides)
+
+        shape = tuple(int(s) for s in shape)
+        strides = computeStrides(shape, layout)
+        return Field(fieldName, dtype, layout[:spatialDimensions], shape, strides)
 
     def __init__(self, fieldName, dtype, layout, shape, strides):
         """Do not use directly. Use static create* methods"""
         self._fieldName = fieldName
         self._dtype = numpyDataTypeToC(dtype)
-        self._layout = layout
+        self._layout = normalizeLayout(layout)
         self.shape = shape
         self.strides = strides
+        # index fields are currently only used for boundary handling
+        # the coordinates are not the loop counters in that case, but are read from this index field
+        self.isIndexField = False
 
     @property
     def spatialDimensions(self):
@@ -124,6 +150,14 @@ class Field:
     def spatialShape(self):
         return self.shape[:self.spatialDimensions]
 
+    @property
+    def hasFixedShape(self):
+        try:
+            [int(i) for i in self.shape]
+            return True
+        except TypeError:
+            return False
+
     @property
     def indexShape(self):
         return self.shape[self.spatialDimensions:]
@@ -308,7 +342,34 @@ def getLayoutFromNumpyArray(arr, indexDimensionIds=[]):
     """
     coordinates = list(range(len(arr.shape)))
     relevantStrides = [stride for i, stride in enumerate(arr.strides) if i not in indexDimensionIds]
-    return tuple(x for (y, x) in sorted(zip(relevantStrides, coordinates), key=lambda pair: pair[0], reverse=True))
+    result = [x for (y, x) in sorted(zip(relevantStrides, coordinates), key=lambda pair: pair[0], reverse=True)]
+    return normalizeLayout(result)
+
+
+def normalizeLayout(layout):
+    """Takes a layout tuple and subtracts the minimum from all entries"""
+    minEntry = min(layout)
+    return tuple(i - minEntry for i in layout)
+
+
+def computeStrides(shape, layout):
+    """
+    Computes strides assuming no padding exists
+    :param shape: shape (size) of array
+    :param layout: layout specification as tuple
+    :return: strides in elements, not in bytes
+    """
+    layout = list(reversed(layout))
+    N = len(shape)
+    assert len(layout) == N
+    assert len(set(layout)) == N
+    strides = [0] * N
+    product = 1
+    for i in range(N):
+        j = layout.index(i)
+        strides[j] = product
+        product *= shape[j]
+    return tuple(strides)
 
 
 def numpyDataTypeToC(dtype):
diff --git a/transformations.py b/transformations.py
index c93d98ca291521838efda267d9e62bbe4a684ecf..1d2dfd5244a4297ed56b9f40e0f2211c0e207402 100644
--- a/transformations.py
+++ b/transformations.py
@@ -43,15 +43,24 @@ def makeLoopOverDomain(body, functionName, iterationSlice=None, ghostLayers=None
     if loopOrder is None:
         loopOrder = getOptimalLoopOrdering(fields)
 
-    shapes = set([f.spatialShape for f in fields])
-
-    if len(shapes) > 1:
-        nrOfFixedSizedFields = 0
-        for shape in shapes:
-            if not isinstance(shape[0], sp.Basic):
-                nrOfFixedSizedFields += 1
-        assert nrOfFixedSizedFields <= 1, "Differently sized field accesses in loop body: " + str(shapes)
-    shape = list(shapes)[0]
+    nrOfFixedShapedFields = 0
+    for f in fields:
+        if f.hasFixedShape:
+            nrOfFixedShapedFields += 1
+
+    if nrOfFixedShapedFields > 0 and nrOfFixedShapedFields != len(fields):
+        fixedFieldNames = ",".join([f.name for f in fields if f.hasFixedShape])
+        varFieldNames = ",".join([f.name for f in fields if not f.hasFixedShape])
+        msg = "Mixing fixed-shaped and variable-shape fields in a single kernel is not possible\n"
+        msg += "Variable shaped: %s \nFixed shaped:    %s" % (varFieldNames, fixedFieldNames)
+        raise ValueError(msg)
+
+    shapeSet = set([f.spatialShape for f in fields])
+    if nrOfFixedShapedFields == len(fields):
+        if len(shapeSet) != 1:
+            raise ValueError("Differently sized field accesses in loop body: " + str(shapeSet))
+
+    shape = list(shapeSet)[0]
 
     if iterationSlice is not None:
         iterationSlice = normalizeSlice(iterationSlice, shape)