diff --git a/cmake/modules/StandardMain.cmake b/cmake/modules/StandardMain.cmake
index 8c8dd056d9916538d2a216ffff6e1a8db88803d8..028c2efc0b208705845326fc9a621697c72ec408 100644
--- a/cmake/modules/StandardMain.cmake
+++ b/cmake/modules/StandardMain.cmake
@@ -18,9 +18,10 @@ int main(int argc, char** argv)
       std::cout<<"I am rank "<<helper.rank()<<" of "<<helper.size()
         <<" processes!"<<std::endl;
 
-    driver(argc, argv);
-
-    return 0;
+    if (driver(argc, argv))
+      return 1;
+    else
+      return 0;
   }
   catch (Dune::Exception &e){
     std::cerr << "Dune reported error: " << e << std::endl;
diff --git a/python/dune/perftool/loopy/transformer.py b/python/dune/perftool/loopy/transformer.py
index 78e872f6b3410c0323f0b91edeca496c7c7132cc..0129f4d70888be3db7f4ef1dd418956252754fba 100644
--- a/python/dune/perftool/loopy/transformer.py
+++ b/python/dune/perftool/loopy/transformer.py
@@ -236,9 +236,9 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker, UFL2PymbolicMapper, GeometryMapp
 
         # Check if this is a parameter function
         else:
-            # We expect all coefficients to be of type Expression or VectorExpression!
-            from dune.perftool.ufl.execution import Expression, VectorExpression
-            assert isinstance(o, (Expression, VectorExpression))
+            # We expect all coefficients to be of type Expression!
+            from dune.perftool.ufl.execution import Expression
+            assert isinstance(o, Expression)
 
             # Determine the name of the parameter function
             from dune.perftool.generation import get_global_context_value
diff --git a/python/dune/perftool/pdelab/driver.py b/python/dune/perftool/pdelab/driver.py
index 57ae37c02406953ba799be1322cbc24f1ca42ac5..1fca4361b09ee9758a05924a01a5a6af46ba04c3 100644
--- a/python/dune/perftool/pdelab/driver.py
+++ b/python/dune/perftool/pdelab/driver.py
@@ -423,9 +423,9 @@ def define_intersection_lambda(expression, name):
     if expression is None:
         return "auto {} = [&](const auto& x){{ return 0; }};".format(name)
     if expression.is_global:
-        return "auto {} = [&](const auto& x){{ {} }};".format(name, expression.c_expr)
+        return "auto {} = [&](const auto& x){{ {} }};".format(name, expression.c_expr[0])
     else:
-        return "auto {} = [&](const auto& is, const auto& x){{ {} }};".format(name, expression.c_expr)
+        return "auto {} = [&](const auto& is, const auto& x){{ {} }};".format(name, expression.c_expr[0])
 
 
 @symbol
@@ -741,9 +741,9 @@ def define_boundary_lambda(boundary, name):
     if boundary is None:
         return "auto {} = [&](const auto& x){{ return 0.0; }};".format(name)
     if boundary.is_global:
-        return "auto {} = [&](const auto& x){{ {} }};".format(name, boundary.c_expr)
+        return "auto {} = [&](const auto& x){{ {} }};".format(name, boundary.c_expr[0])
     else:
-        return "auto {} = [&](const auto& e, const auto& x){{ {} }};".format(name, boundary.c_expr)
+        return "auto {} = [&](const auto& e, const auto& x){{ {} }};".format(name, boundary.c_expr[0])
 
 
 @symbol
@@ -777,41 +777,61 @@ def define_compositegfs_parameterfunction(name, *children):
                                                                     ', '.join(children))
 
 
+def expression_splitter(expr, length):
+    if expr is None:
+        return (None,) * length
+    else:
+        from dune.perftool.ufl.execution import split_expression
+        return split_expression(expr)
+
+
 @symbol
-def name_boundary_function(expr):
+def _name_boundary_function(element, boundary, name=None):
     from ufl import MixedElement, VectorElement, TensorElement
-    if isinstance(expr, (VectorElement, TensorElement)):
-        element, (_, boundary) = get_constraints_metadata(expr)
+    if isinstance(element, (VectorElement, TensorElement)):
         from dune.perftool.generation import get_global_context_value
-        name = get_global_context_value("data").object_names.get(id(boundary), "zero")
-        define_boundary_function(boundary, name)
-        return name
-    if isinstance(expr, MixedElement):
-        children = tuple(name_boundary_function(el) for el in expr.sub_elements())
+        basename = get_global_context_value("data").object_names.get(id(boundary), "veczero")
+        children = tuple(_name_boundary_function(el, exp, basename + '_' + str(i)) for el, exp, i in zip(element.sub_elements(), expression_splitter(boundary, element.num_sub_elements()), range(element.num_sub_elements())))
+        define_compositegfs_parameterfunction(basename, *children)
+        return basename
+    if isinstance(element, MixedElement):
+        children = tuple(name_boundary_function(el) for el in element.sub_elements())
         name = '_'.join(children)
         define_compositegfs_parameterfunction(name, *children)
         return name
 
-    # This is a scalar leaf of the ansatz function tree
-    element, (_, boundary) = get_constraints_metadata(expr)
-
     from dune.perftool.generation import get_global_context_value
-    name = get_global_context_value("data").object_names.get(id(boundary), "zero")
+    if name is None:
+        name = get_global_context_value("data").object_names.get(id(boundary), "zero")
 
     define_boundary_function(boundary, name)
     return name
 
 
+def name_boundary_function(expr):
+    # This is a scalar leaf of the ansatz function tree
+    element, (_, boundary) = get_constraints_metadata(expr)
+
+    return _name_boundary_function(element, boundary)
+
+
 @symbol
-def name_solution_function(expr):
-    # Get expression representing solution
+def name_solution_function(tree_path=()):
+    from dune.perftool.generation import get_global_context_value
+    expr = get_global_context_value("data").object_by_name[get_option("exact_solution_expression")]
+
+    from dune.perftool.ufl.execution import split_expression
+    for i in tree_path:
+        expr = split_expression(expr)[int(i)]
+
     from dune.perftool.generation import get_global_context_value
-    solution_expression_name = get_option("exact_solution_expression")
-    solution_expression = get_global_context_value("data").object_by_name[solution_expression_name]
+    try:
+        name = get_global_context_value("data").object_names[id(expr)]
+    except KeyError:
+        from dune.perftool.generation.cache import _GlobalCounter
+        name = 'generic_{}'.format(_GlobalCounter().get())
 
-    # Create function just like it is done for boundary_function
-    name = "solution_function"
-    define_boundary_function(solution_expression, name)
+    define_boundary_function(expr, name)
 
     return name
 
@@ -833,7 +853,7 @@ def interpolate_solution_expression(name):
     formdata = _driver_data['formdata']
     define_vector(name, formdata)
     element = _driver_data['form'].coefficients()[0].ufl_element()
-    sol = name_solution_function(element)
+    sol = name_solution_function()
     gfs = name_gfs(element)
     return "Dune::PDELab::interpolate({}, {}, {});".format(sol,
                                                            gfs,
@@ -1156,6 +1176,7 @@ def name_vtkfile():
 def compare_dofs():
     v = name_vector(_driver_data['formdata'])
     solution = name_vector_from_solution_expression()
+    fail = name_test_fail_variable()
     return ["",
             "// Maximum norm of difference between dof vectors of the",
             "// numerical solution and the interpolation of the exact solution",
@@ -1166,44 +1187,161 @@ def compare_dofs():
             "    maxerror = std::abs(native({})[i]-native({})[i]);".format(v, solution),
             "std::cout << std::endl << \"Maxerror: \" << maxerror << std::endl;",
             "if (maxerror>{})".format(get_option("compare_dofs")),
-            "  throw;"]
+            "  {} = true;".format(fail)]
+
+
+@symbol
+def type_discrete_grid_function(gfs):
+    return "DGF_{}".format(gfs.upper())
 
 
 @preamble
 def define_discrete_grid_function(gfs, vector_name, dgf_name):
-    return ["typedef Dune::PDELab::DiscreteGridFunction<decltype({}),decltype({})> DGF;".format(gfs, vector_name),
-            "DGF {}({},{});".format(dgf_name, gfs, vector_name)]
+    dgf_type = type_discrete_grid_function(gfs)
+    return ["typedef Dune::PDELab::DiscreteGridFunction<decltype({}),decltype({})> {};".format(gfs, vector_name, dgf_type),
+            "{} {}({},{});".format(dgf_type, dgf_name, gfs, vector_name)]
 
 
 @symbol
 def name_discrete_grid_function(gfs, vector_name):
-    dgf_name = vector_name + "_dgf"
+    dgf_name = gfs + "_dgf"
     define_discrete_grid_function(gfs, vector_name, dgf_name)
     return dgf_name
 
 
+@symbol
+def type_subgfs(element, tree_path):
+    include_file('dune/pdelab/gridfunctionspace/subspace.hh', filetag='driver')
+    gfs = type_gfs(element)
+    return "Dune::PDELab::GridFunctionSubSpace<{}, Dune::TypeTree::TreePath<{}> >".format(gfs, ', '.join(tree_path))
+
+
 @preamble
-def compare_L2_squared():
+def define_subgfs(name, element, tree_path):
+    t = type_subgfs(element, tree_path)
+    gfs = name_gfs(element)
+
+    return '{} {}({});'.format(t, name, gfs)
+
+
+@symbol
+def name_subgfs(element, tree_path):
+    gfs = name_gfs(element)
+    if len(tree_path) == 0:
+        return gfs
+    else:
+        name = "subgfs_{}_{}".format(gfs, '_'.join(tree_path))
+        define_subgfs(name, element, tree_path)
+        return name
+
+
+@preamble
+def typedef_difference_squared_adapter(name, tree_path):
     element = _driver_data['form'].coefficients()[0].ufl_element()
     formdata = _driver_data['formdata']
-    v = name_vector(formdata)
-    gfs = name_gfs(element)
-    vdgf = name_discrete_grid_function(gfs, v)
-    solution_function = name_solution_function(element)
+
+    solution_function = name_solution_function(tree_path)
+    gfs = name_subgfs(element, tree_path)
+    vector = name_vector(formdata)
+    dgf = name_discrete_grid_function(gfs, vector)
+
+    return 'typedef DifferenceSquaredAdapter<decltype({}), decltype({})> {};'.format(solution_function, dgf, name)
+
+
+@symbol
+def type_difference_squared_adapter(tree_path):
+    t = 'DifferenceSquared_{}'.format('_'.join(tree_path))
+    typedef_difference_squared_adapter(t, tree_path)
+    return t
+
+
+@preamble
+def define_difference_squared_adapter(name, tree_path):
+    element = _driver_data['form'].coefficients()[0].ufl_element()
+    formdata = _driver_data['formdata']
+
+    t = type_difference_squared_adapter(tree_path)
+    solution_function = name_solution_function(tree_path)
+    gfs = name_subgfs(element, tree_path)
+    vector = name_vector(formdata)
+    dgf = name_discrete_grid_function(gfs, vector)
+
+    return '{} {}({}, {});'.format(t, name, solution_function, dgf)
+
+
+def name_difference_squared_adapter(tree_path):
+    name = 'differencesquared_{}'.format('_'.join(tree_path))
+    define_difference_squared_adapter(name, tree_path)
+    return name
+
+
+@preamble
+def _accumulate_L2_squared(tree_path):
+    dsa = name_difference_squared_adapter(tree_path)
+    t_dsa = type_difference_squared_adapter(tree_path)
+    accum_error = name_accumulated_L2_error()
 
     include_file("dune/pdelab/gridfunctionspace/gridfunctionadapter.hh", filetag="driver")
     include_file("dune/pdelab/common/functionutilities.hh", filetag="driver")
 
-    return ["",
-            "// L2 error squared of difference between numerical",
-            "// solution and the interpolation of exact solution",
-            "typedef DifferenceSquaredAdapter<decltype({}),decltype({})> DifferenceSquared;".format(solution_function, vdgf),
-            "DifferenceSquared differencesquared({},{});".format(solution_function, vdgf),
-            "typename DifferenceSquared::Traits::RangeType l2errorsquared(0.0);",
-            "Dune::PDELab::integrateGridFunction(differencesquared,l2errorsquared,10);",
-            "std::cout << \"l2errorsquared: \" << l2errorsquared << std::endl;",
-            "if (l2errorsquared>{})".format(get_option("compare_l2errorsquared")),
-            "  throw;"]
+    return ["{",
+            "  // L2 error squared of difference between numerical",
+            "  // solution and the interpolation of exact solution",
+            "  // only subgfs with treepath: {}".format(', '.join(tree_path)),
+            "  typename {}::Traits::RangeType err(0.0);".format(t_dsa),
+            "  Dune::PDELab::integrateGridFunction({}, err, 10);".format(dsa),
+            "  {} += err;".format(accum_error),
+            "  std::cout << \"Accumlated L2 Error for tree path {}: \" << err << std::endl;".format(tree_path),
+            "}"]
+
+
+def accumulate_L2_squared(tree_path=()):
+    element = _driver_data['form'].coefficients()[0].ufl_element()
+    from ufl.functionview import select_subelement
+    from ufl.classes import MultiIndex, FixedIndex
+    element = select_subelement(element, MultiIndex(tuple(FixedIndex(int(i)) for i in tree_path)))
+
+    from ufl import MixedElement
+    if isinstance(element, MixedElement):
+        for i, subel in enumerate(element.sub_elements()):
+            accumulate_L2_squared(tree_path + (str(i),))
+    else:
+        _accumulate_L2_squared(tree_path)
+
+
+@preamble
+def define_accumulated_L2_error(name):
+    return "double {}(0.0);".format(name)
+
+
+@symbol
+def name_accumulated_L2_error():
+    name = 'l2error'
+    define_accumulated_L2_error(name)
+    return name
+
+
+@preamble
+def compare_L2_squared():
+    accumulate_L2_squared()
+
+    accum_error = name_accumulated_L2_error()
+    fail = name_test_fail_variable()
+    return ["std::cout << \"l2errorsquared: \" << {} << std::endl;".format(accum_error),
+            "if ({}>{})".format(accum_error, get_option("compare_l2errorsquared")),
+            "  {} = true;".format(fail)]
+
+
+@preamble
+def define_test_fail_variable(name):
+    return 'bool {}(false);'.format(name)
+
+
+@symbol
+def name_test_fail_variable():
+    name = "testfail"
+    define_test_fail_variable(name)
+    return name
 
 
 @preamble
@@ -1289,10 +1427,6 @@ def vtkoutput():
     print_matrix()
 
     if get_option("exact_solution_expression"):
-        from ufl import MixedElement, VectorElement, TensorElement
-        if isinstance(_driver_data['form'].coefficients()[0].ufl_element(), (MixedElement, VectorElement, TensorElement)):
-            raise NotImplementedError("Comparing to exact solution is olny implemented for scalar elements.")
-
         if get_option("compare_dofs"):
             compare_dofs()
         if get_option("compare_l2errorsquared"):
@@ -1424,16 +1558,18 @@ def solve_instationary():
     print_residual()
     print_matrix()
     if get_option("exact_solution_expression"):
-        from ufl import MixedElement, VectorElement, TensorElement
-        if isinstance(_driver_data['form'].coefficients()[0].ufl_element(), (MixedElement, VectorElement, TensorElement)):
-            raise NotImplementedError("Comparing to exact solution is olny implemented for scalar elements.")
-
         if get_option("compare_dofs"):
             compare_dofs()
         if get_option("compare_l2errorsquared"):
             compare_L2_squared()
 
 
+@preamble
+def return_statement():
+    fail = name_test_fail_variable()
+    return "return {};".format(fail)
+
+
 def generate_driver(formdatas, data):
     # The driver module uses a global dictionary for storing necessary data
     set_driver_data(formdatas, data)
@@ -1445,9 +1581,11 @@ def generate_driver(formdatas, data):
     else:
         solve_instationary()
 
+    return_statement()
+
     from dune.perftool.generation import retrieve_cache_items
     from cgen import FunctionDeclaration, FunctionBody, Block, Value
-    driver_signature = FunctionDeclaration(Value('void', 'driver'), [Value('int', 'argc'), Value('char**', 'argv')])
+    driver_signature = FunctionDeclaration(Value('bool', 'driver'), [Value('int', 'argc'), Value('char**', 'argv')])
     driver_body = Block(contents=[i for i in retrieve_cache_items("preamble", make_generable=True)])
     driver = FunctionBody(driver_signature, driver_body)
 
diff --git a/python/dune/perftool/pdelab/parameter.py b/python/dune/perftool/pdelab/parameter.py
index 79fede9c1eb72e20613b2db92cd6df8b1463050c..624f82dbaa97c4e39bc9ad0223e38613874b4ded 100644
--- a/python/dune/perftool/pdelab/parameter.py
+++ b/python/dune/perftool/pdelab/parameter.py
@@ -69,8 +69,22 @@ def define_set_time_method():
     return result
 
 
+def component_to_tree_path(element, component):
+    subel = element.extract_subelement_component(component)
+
+    def _flatten(x):
+        if isinstance(x, tuple):
+            return '_'.join(_flatten(i) for i in x if i != ())
+        else:
+            return str(x)
+
+    return _flatten(subel)
+
+
 @class_member("parameterclass", access=AccessModifier.PUBLIC)
-def define_parameter_function_class_member(name, expr, t, cell):
+def define_parameter_function_class_member(name, expr, baset, shape, cell):
+    t = construct_nested_fieldvector(baset, shape)
+
     geot = "E" if cell else "I"
     geo = geot.lower()
     result = ["template<typename {}, typename X>".format(geot),
@@ -78,12 +92,32 @@ def define_parameter_function_class_member(name, expr, t, cell):
               "{",
               ]
 
-    if expr.is_global:
-        result.append("  auto x = {}.geometry().global(local);".format(geo))
+    # In the case of a non-scalar parameter function, recurse into leafs
+    if expr.element.value_shape():
+        # Check that this is a VectorElement, as I have no idea how a parameter function
+        # over a non-vector mixed element should be well-defined in PDELab.
+        from ufl import VectorElement
+        assert isinstance(expr.element, VectorElement)
+
+        result.append("  {} result(0.0);".format(t))
+
+        from dune.perftool.ufl.execution import split_expression
+        for i, subexpr in enumerate(split_expression(expr)):
+            child_name = "{}_{}".format(name, component_to_tree_path(expr.element, i))
+            result.append("  result[{}] = {}({}, local);".format(i, child_name, geo))
+            define_parameter_function_class_member(child_name, subexpr, baset, shape[1:], cell)
+
+        result.append("  return result;")
+
     else:
-        result.append("  auto x = local;")
+        # Evaluate a scalar parameter function
+        if expr.is_global:
+            result.append("  auto x = {}.geometry().global(local);".format(geo))
+        else:
+            result.append("  auto x = local;")
+
+        result.append("  " + expr.c_expr[0])
 
-    result.append("  " + expr.c_expr)
     result.append("}")
 
     return result
@@ -175,8 +209,7 @@ def construct_nested_fieldvector(t, shape):
 def cell_parameter_function(name, expr, restriction, cellwise_constant, t='double'):
     shape = expr.ufl_element().value_shape()
     shape_impl = ('fv',) * len(shape)
-    t = construct_nested_fieldvector(t, shape)
-    define_parameter_function_class_member(name, expr, t, True)
+    define_parameter_function_class_member(name, expr, t, shape, True)
     if cellwise_constant:
         from dune.perftool.generation.loopy import default_declaration
         default_declaration(name, shape, shape_impl)
@@ -190,8 +223,7 @@ def cell_parameter_function(name, expr, restriction, cellwise_constant, t='doubl
 def intersection_parameter_function(name, expr, cellwise_constant, t='double'):
     shape = expr.ufl_element().value_shape()
     shape_impl = ('fv',) * len(shape)
-    t = construct_nested_fieldvector(t, shape)
-    define_parameter_function_class_member(name, expr, t, False)
+    define_parameter_function_class_member(name, expr, t, shape, False)
     if cellwise_constant:
         from dune.perftool.generation.loopy import default_declaration
         default_declaration(name, shape, shape_impl)
diff --git a/python/dune/perftool/ufl/execution.py b/python/dune/perftool/ufl/execution.py
index fb0aa6b5d008dd028f3d7903c3b57a43ed728842..32717a9ed2b703eaf2fe44e9081e61fdc98f82a2 100644
--- a/python/dune/perftool/ufl/execution.py
+++ b/python/dune/perftool/ufl/execution.py
@@ -38,7 +38,10 @@ class Coefficient(ufl.Coefficient):
         ufl.Coefficient.__init__(self, element, count)
 
 
-split = ufl.split_functions.split2
+def split(obj):
+    if isinstance(obj, Expression):
+        return split_expression(obj)
+    return ufl.split_functions.split2(obj)
 
 
 def Coefficients(element):
@@ -54,42 +57,66 @@ def TrialFunctions(element):
 
 
 class Expression(Coefficient):
-    def __init__(self, expr, is_global=True, on_intersection=False, cell_type="triangle", cellwise_constant=False):
-        assert isinstance(expr, str)
-        self.c_expr = expr
-        self.is_global = is_global
-        self.on_intersection = on_intersection
-
-        # Avoid ufl complaining about not matching dimension/cells
-        if cellwise_constant:
-            _dg = FiniteElement("DG", cell_type, 0)
-        else:
-            _dg = FiniteElement("DG", cell_type, 1)
+    def __init__(self, cppcode=None, element=None, cell="triangle", degree=None, is_global=True, on_intersection=False, cellwise_constant=False):
+        assert cppcode
 
-        # Initialize a coefficient with a dummy finite element map.
-        Coefficient.__init__(self, _dg)
+        if isinstance(cppcode, str):
+            cppcode = (cppcode,)
 
-    # TODO the subdomain_data code needs a uflid, not idea how to get it here
-    # The standard way through class decorator fails here...
-    def ufl_id(self):
-        return 0
+        def wrap_return(e):
+            if "return" not in e:
+                return "return {};".format(e)
+            else:
+                return e
 
+        cppcode = tuple(wrap_return(e) for e in cppcode)
 
-class VectorExpression(Coefficient):
-    def __init__(self, expr, is_global=True, on_intersection=False, cell_type="triangle", cellwise_constant=False):
-        assert isinstance(expr, str)
-        self.c_expr = expr
+        if cellwise_constant:
+            if element:
+                assert element.degree() == 0
+            elif degree is not None:
+                assert degree == 0
+            else:
+                element = FiniteElement("DG", cell, 0)
+
+        if degree is None:
+            degree = 1
+
+        if element is None:
+            if len(cppcode) == 1:
+                element = FiniteElement("DG", cell, degree)
+            else:
+                element = VectorElement("DG", cell, degree, len(cppcode))
+
+        def element_length(elem):
+            if isinstance(elem, ufl.FiniteElement):
+                return 1
+            else:
+                return elem.value_shape()[0]
+
+        assert element_length(element) == len(cppcode)
+
+        self.c_expr = cppcode
         self.is_global = is_global
         self.on_intersection = on_intersection
-
-        # Avoid ufl complaining about not matching dimension/cells
-        if cellwise_constant:
-            _dgvec = VectorElement("DG", cell_type, 0)
-        else:
-            _dgvec = VectorElement("DG", cell_type, 1)
+        self.element = element
 
         # Initialize a coefficient with a dummy finite element map.
-        Coefficient.__init__(self, _dgvec)
+        Coefficient.__init__(self, element)
+
+    def __mul__(self, other):
+        # Allow the combination of Expressions
+        if isinstance(other, Expression):
+            def get_sub(elem):
+                if isinstance(elem, MixedElement) and not isinstance(elem, (VectorElement, TensorElement)):
+                    return elem.sub_elements()
+                else:
+                    return [elem]
+
+            newelem = MixedElement(*(get_sub(self.element) + get_sub(other.element)))
+            return Expression(cppcode=self.c_expr + other.c_expr, element=newelem)
+        else:
+            return Coefficient.__mul__(self, other)
 
     # TODO the subdomain_data code needs a uflid, not idea how to get it here
     # The standard way through class decorator fails here...
@@ -97,6 +124,19 @@ class VectorExpression(Coefficient):
         return 0
 
 
+def split_expression(expr):
+    assert isinstance(expr, Expression)
+
+    def element_slice(expression, sub):
+        offset = sum(subel.value_size() for subel in expression.element.sub_elements()[:sub])
+        return expression.c_expr[offset:offset + expr.element.sub_elements()[sub].value_size()]
+
+    return tuple(Expression(cppcode=element_slice(expr, i),
+                            element=expr.element.sub_elements()[i])
+                 for i in range(expr.element.num_sub_elements())
+                 )
+
+
 class FiniteElement(ufl.FiniteElement):
     def __init__(self, *args, **kwargs):
         if ('dirichlet_constraints' in kwargs) or ('dirichlet_expression' in kwargs):
diff --git a/test/heatequation/heatequation.mini b/test/heatequation/heatequation.mini
index 6087d4160a3084387be6fa5af703745893d6dfde..b5897d254180c71726bf0b181e6ae72e6afa8714 100644
--- a/test/heatequation/heatequation.mini
+++ b/test/heatequation/heatequation.mini
@@ -15,3 +15,6 @@ extension = vtu
 explicit_time_stepping = 0, 1 | expand scheme
 exact_solution_expression = g
 compare_l2errorsquared = 1e-7
+
+# Disable explicit tests for now
+{__exec_suffix} == explicit | exclude
diff --git a/test/heatequation/heatequation_dg.mini b/test/heatequation/heatequation_dg.mini
index e2a455372a077c34f9a46f239da702363a8cdde1..47559b75a86880bddb1134be30a31dfa4494b8e0 100644
--- a/test/heatequation/heatequation_dg.mini
+++ b/test/heatequation/heatequation_dg.mini
@@ -15,3 +15,6 @@ extension = vtu
 explicit_time_stepping = 0, 1 | expand scheme
 exact_solution_expression = g
 compare_l2errorsquared = 1e-5
+
+# Disable explicit tests for now
+{__exec_suffix} == explicit | exclude
diff --git a/test/poisson/dimension-grid-variations/poisson_1d_cg_interval.ufl b/test/poisson/dimension-grid-variations/poisson_1d_cg_interval.ufl
index 864810e8a0dd87330992901f0badaf53c9eedbe3..6bda534f16236d66b351c0ac1c0671a41f03f9de 100644
--- a/test/poisson/dimension-grid-variations/poisson_1d_cg_interval.ufl
+++ b/test/poisson/dimension-grid-variations/poisson_1d_cg_interval.ufl
@@ -1,9 +1,9 @@
-cell_type = "interval"
+cell = "interval"
 
-f = Expression("return -2.0*x.size();", cell_type=cell_type)
-g = Expression("return x.two_norm2();", cell_type=cell_type)
+f = Expression("return -2.0*x.size();", cell=cell)
+g = Expression("return x.two_norm2();", cell=cell)
 
-V = FiniteElement("CG", cell_type, 1, dirichlet_expression=g)
+V = FiniteElement("CG", cell, 1, dirichlet_expression=g)
 u = TrialFunction(V)
 v = TestFunction(V)
 
diff --git a/test/poisson/dimension-grid-variations/poisson_1d_dg_interval.ufl b/test/poisson/dimension-grid-variations/poisson_1d_dg_interval.ufl
index f7775baf11b5225addc511a2016ddaac8ad0d9fe..907f19841d51695f3944617ff162b33fce7b5053 100644
--- a/test/poisson/dimension-grid-variations/poisson_1d_dg_interval.ufl
+++ b/test/poisson/dimension-grid-variations/poisson_1d_dg_interval.ufl
@@ -1,14 +1,14 @@
-cell_type = "interval"
+cell = "interval"
 
-f = Expression("return -2.0*x.size();", cell_type=cell_type)
-g = Expression("return x.two_norm2();", on_intersection=True, cell_type=cell_type)
+f = Expression("return -2.0*x.size();", cell=cell)
+g = Expression("return x.two_norm2();", on_intersection=True, cell=cell)
 
-V = FiniteElement("DG", cell_type, 1)
+V = FiniteElement("DG", cell, 1)
 
 u = TrialFunction(V)
 v = TestFunction(V)
 
-n = FacetNormal(cell_type)('+')
+n = FacetNormal(cell)('+')
 
 gamma = 1.0
 theta = 1.0
diff --git a/test/poisson/dimension-grid-variations/poisson_2d_cg_quadrilateral.ufl b/test/poisson/dimension-grid-variations/poisson_2d_cg_quadrilateral.ufl
index 7d43c7eb3ee86e180ad51443d2d4bb370e79e4c2..5a2c570583a2fe200e91a1dbf20b0dde699ec156 100644
--- a/test/poisson/dimension-grid-variations/poisson_2d_cg_quadrilateral.ufl
+++ b/test/poisson/dimension-grid-variations/poisson_2d_cg_quadrilateral.ufl
@@ -1,9 +1,9 @@
-cell_type = "quadrilateral"
+cell = "quadrilateral"
 
-f = Expression("return -2.0*x.size();", cell_type=cell_type)
-g = Expression("return x.two_norm2();", cell_type=cell_type)
+f = Expression("return -2.0*x.size();", cell=cell)
+g = Expression("return x.two_norm2();", cell=cell)
 
-V = FiniteElement("CG", cell_type, 1, dirichlet_expression=g)
+V = FiniteElement("CG", cell, 1, dirichlet_expression=g)
 u = TrialFunction(V)
 v = TestFunction(V)
 
diff --git a/test/poisson/dimension-grid-variations/poisson_2d_dg_quadrilateral.ufl b/test/poisson/dimension-grid-variations/poisson_2d_dg_quadrilateral.ufl
index 24dbccae56b8b93ae305b561e1ac5025d3a53bd7..1ca65e1eaf16d4ff71444bd71626c277b82328c9 100644
--- a/test/poisson/dimension-grid-variations/poisson_2d_dg_quadrilateral.ufl
+++ b/test/poisson/dimension-grid-variations/poisson_2d_dg_quadrilateral.ufl
@@ -1,14 +1,14 @@
-cell_type = "quadrilateral"
+cell = "quadrilateral"
 
-f = Expression("return -2.0*x.size();", cell_type=cell_type)
-g = Expression("return x.two_norm2();", on_intersection=True, cell_type=cell_type)
+f = Expression("return -2.0*x.size();", cell=cell)
+g = Expression("return x.two_norm2();", on_intersection=True, cell=cell)
 
-V = FiniteElement("DG", cell_type, 1)
+V = FiniteElement("DG", cell, 1)
 
 u = TrialFunction(V)
 v = TestFunction(V)
 
-n = FacetNormal(cell_type)('+')
+n = FacetNormal(cell)('+')
 
 gamma = 1.0
 theta = 1.0
diff --git a/test/poisson/dimension-grid-variations/poisson_3d_cg_hexahedron.ufl b/test/poisson/dimension-grid-variations/poisson_3d_cg_hexahedron.ufl
index 5c0091d74b1e9349fd6631b18b2ffdfbd42e990d..4cad67e31f354a7eb0c4c6d25b95713f31067612 100644
--- a/test/poisson/dimension-grid-variations/poisson_3d_cg_hexahedron.ufl
+++ b/test/poisson/dimension-grid-variations/poisson_3d_cg_hexahedron.ufl
@@ -1,9 +1,9 @@
-cell_type = "hexahedron"
+cell = "hexahedron"
 
-f = Expression("return -2.0*x.size();", cell_type=cell_type)
-g = Expression("return x.two_norm2();", cell_type=cell_type)
+f = Expression("return -2.0*x.size();", cell=cell)
+g = Expression("return x.two_norm2();", cell=cell)
 
-V = FiniteElement("CG", cell_type, 1, dirichlet_expression=g)
+V = FiniteElement("CG", cell, 1, dirichlet_expression=g)
 u = TrialFunction(V)
 v = TestFunction(V)
 
diff --git a/test/poisson/dimension-grid-variations/poisson_3d_cg_tetrahedron.ufl b/test/poisson/dimension-grid-variations/poisson_3d_cg_tetrahedron.ufl
index 1456671d43ce0de2d3bfbf8d1ca13fda9f8e0733..d8f43c0941267480a07eba857b93d635571af43d 100644
--- a/test/poisson/dimension-grid-variations/poisson_3d_cg_tetrahedron.ufl
+++ b/test/poisson/dimension-grid-variations/poisson_3d_cg_tetrahedron.ufl
@@ -1,7 +1,7 @@
-cell_type = "tetrahedron"
+cell = "tetrahedron"
 
-f = Expression("return -2.0*x.size();", cell_type=cell_type)
-g = Expression("return x.two_norm2();", cell_type=cell_type)
+f = Expression("return -2.0*x.size();", cell=cell)
+g = Expression("return x.two_norm2();", cell=cell)
 
 V = FiniteElement("CG", "tetrahedron", 1, dirichlet_expression=g)
 u = TrialFunction(V)
diff --git a/test/poisson/dimension-grid-variations/poisson_3d_dg_hexahedron.ufl b/test/poisson/dimension-grid-variations/poisson_3d_dg_hexahedron.ufl
index 3a410e3011596ab6372028e1e705d26cd5747216..bf5cc370a5651c1a408d2f1b6687d4c3255c0172 100644
--- a/test/poisson/dimension-grid-variations/poisson_3d_dg_hexahedron.ufl
+++ b/test/poisson/dimension-grid-variations/poisson_3d_dg_hexahedron.ufl
@@ -1,14 +1,14 @@
-cell_type = "hexahedron"
+cell = "hexahedron"
 
-f = Expression("return -2.0*x.size();", cell_type=cell_type)
-g = Expression("return x.two_norm2();", on_intersection=True, cell_type=cell_type)
+f = Expression("return -2.0*x.size();", cell=cell)
+g = Expression("return x.two_norm2();", on_intersection=True, cell=cell)
 
-V = FiniteElement("DG", cell_type, 1)
+V = FiniteElement("DG", cell, 1)
 
 u = TrialFunction(V)
 v = TestFunction(V)
 
-n = FacetNormal(cell_type)('+')
+n = FacetNormal(cell)('+')
 
 gamma = 1.0
 theta = 1.0
diff --git a/test/poisson/dimension-grid-variations/poisson_3d_dg_tetrahedron.ufl b/test/poisson/dimension-grid-variations/poisson_3d_dg_tetrahedron.ufl
index a2d8135baa6d8f6556dcff607989af38a9ffa826..4c73c7debf2ac3a5f81941d2e6d12cb5ee4ff4fa 100644
--- a/test/poisson/dimension-grid-variations/poisson_3d_dg_tetrahedron.ufl
+++ b/test/poisson/dimension-grid-variations/poisson_3d_dg_tetrahedron.ufl
@@ -1,14 +1,14 @@
-cell_type = "tetrahedron"
+cell = "tetrahedron"
 
-f = Expression("return -2.0*x.size();", cell_type=cell_type)
-g = Expression("return x.two_norm2();", on_intersection=True, cell_type=cell_type)
+f = Expression("return -2.0*x.size();", cell=cell)
+g = Expression("return x.two_norm2();", on_intersection=True, cell=cell)
 
-V = FiniteElement("DG", cell_type, 1)
+V = FiniteElement("DG", cell, 1)
 
 u = TrialFunction(V)
 v = TestFunction(V)
 
-n = FacetNormal(cell_type)('+')
+n = FacetNormal(cell)('+')
 
 gamma = 1.0
 theta = 1.0
diff --git a/test/stokes/CMakeLists.txt b/test/stokes/CMakeLists.txt
index 8d6fa96d619fc308cba1a75296dc91c84fe43413..0d3751b8483822901ea723d51bd14e71a68657fb 100644
--- a/test/stokes/CMakeLists.txt
+++ b/test/stokes/CMakeLists.txt
@@ -5,17 +5,14 @@ dune_symlink_to_source_files(FILES hagenpoiseuille_ref.vtu
 dune_add_formcompiler_system_test(UFLFILE stokes.ufl
                                   BASENAME stokes
                                   INIFILE stokes.mini
-                                  SCRIPT dune_vtkcompare.py
                                   )
 
 dune_add_formcompiler_system_test(UFLFILE stokes_dg.ufl
                                   BASENAME stokes_dg
                                   INIFILE stokes_dg.mini
-                                  SCRIPT dune_vtkcompare.py
                                   )
 
 dune_add_formcompiler_system_test(UFLFILE stokes_stress.ufl
                                   BASENAME stokes_stress
                                   INIFILE stokes_stress.mini
-                                  SCRIPT dune_vtkcompare.py
                                   )
diff --git a/test/stokes/stokes.mini b/test/stokes/stokes.mini
index 23a7932929a7783a92ee032727b9749022bdfe47..6bb834ff2fa259e99a2fa835cd4564765d63cd9b 100644
--- a/test/stokes/stokes.mini
+++ b/test/stokes/stokes.mini
@@ -14,3 +14,5 @@ extension = vtu
 
 [formcompiler]
 numerical_jacobian = 0, 1 | expand num
+exact_solution_expression = g
+compare_l2errorsquared = 1e-6
diff --git a/test/stokes/stokes.ufl b/test/stokes/stokes.ufl
index 9252834820f67c72a6b28f08b6b1bd1b164ad04c..da632caf9ecbf0f93eb5aa1c70cd5df17aba01b6 100644
--- a/test/stokes/stokes.ufl
+++ b/test/stokes/stokes.ufl
@@ -1,8 +1,11 @@
 v_bctype = Expression("if (x[0] < 1. - 1e-8) return 1; else return 0;", on_intersection=True)
-v_dirichlet = Expression("Dune::FieldVector<double, 2> y(0.0); y[0] = 4*x[1]*(1.-x[1]); return y;")
+g_v = Expression(("4*x[1]*(1.-x[1])", "0.0"))
+g_p = Expression("8*(1.-x[0])")
+
+g = g_v * g_p
 
 cell = triangle
-P2 = VectorElement("Lagrange", cell, 2, dirichlet_constraints=v_bctype, dirichlet_expression=v_dirichlet)
+P2 = VectorElement("Lagrange", cell, 2, dirichlet_constraints=v_bctype, dirichlet_expression=g_v)
 P1 = FiniteElement("Lagrange", cell, 1)
 TH = P2 * P1
 
diff --git a/test/stokes/stokes_dg.mini b/test/stokes/stokes_dg.mini
index 6448f4f5b36dfad891d76e069c3e5573546e6f85..20d92508ac79daf523858c1c99b4476c2cc0b65e 100644
--- a/test/stokes/stokes_dg.mini
+++ b/test/stokes/stokes_dg.mini
@@ -16,3 +16,5 @@ zeroThreshold.data_1 = 1e-6
 
 [formcompiler]
 numerical_jacobian = 0, 1 | expand num
+exact_solution_expression = g
+compare_l2errorsquared = 1e-5
diff --git a/test/stokes/stokes_dg.ufl b/test/stokes/stokes_dg.ufl
index 7b15e24ce48c5aac90f274581d3e13f44ae80fb5..b63893f0fe98622e1b24019e930026c615074010 100644
--- a/test/stokes/stokes_dg.ufl
+++ b/test/stokes/stokes_dg.ufl
@@ -1,4 +1,6 @@
-g = VectorExpression("Dune::FieldVector<double, 2> y(0.0); y[0]=4*x[1]*(1.-x[1]); return y;", on_intersection=True)
+g_v = Expression(("4*x[1]*(1.-x[1])", "0.0"), on_intersection=True)
+g_p = Expression("8*(1.-x[0])")
+g = g_v * g_p
 bctype = Expression("if (x[0] < 1. - 1e-8) return 1; else return 0;", on_intersection=True)
 
 cell = triangle
@@ -19,15 +21,15 @@ r = inner(grad(u), grad(v))*dx \
   + inner(avg(grad(u))*n, jump(v))*dS \
   - eps * inner(avg(grad(v))*n, jump(u))*dS \
   - inner(grad(u)*n, v)*ds \
-  + eps * inner(grad(v)*n, u-g)*ds \
+  + eps * inner(grad(v)*n, u-g_v)*ds \
   + sigma * inner(jump(u), jump(v))*dS \
-  + sigma * inner(u-g, v)*ds \
+  + sigma * inner(u-g_v, v)*ds \
   - p*div(v)*dx \
   - avg(p)*inner(jump(v), n)*dS \
   + p*inner(v, n)*ds \
   - q*div(u)*dx \
   - avg(q)*inner(jump(u), n)*dS \
   + q*inner(u, n)*ds \
-  - q*inner(g, n)*ds
+  - q*inner(g_v, n)*ds
 
 forms = [r]
diff --git a/test/stokes/stokes_stress.mini b/test/stokes/stokes_stress.mini
index 642ef6d2ea8768f1fad13f29c6773e2ee173b830..4481e91d21e683dc8452c84c35ca03eca7a2182c 100644
--- a/test/stokes/stokes_stress.mini
+++ b/test/stokes/stokes_stress.mini
@@ -14,3 +14,5 @@ extension = vtu
 
 [formcompiler]
 numerical_jacobian = 0, 1 | expand num
+exact_solution_expression = g
+compare_l2errorsquared = 1e-6
diff --git a/test/stokes/stokes_stress.ufl b/test/stokes/stokes_stress.ufl
index 9eb4f3b750e26bb930acda17387da3644773d044..d5c41e301ce7919fbd94fb86f9c6cab250ae9083 100644
--- a/test/stokes/stokes_stress.ufl
+++ b/test/stokes/stokes_stress.ufl
@@ -1,16 +1,19 @@
 v_bctype = Expression("if (x[0] < 1. - 1e-8) return 1; else return 0;", on_intersection=True)
-v_dirichlet = Expression("Dune::FieldVector<double, 2> y(0.0); y[0] = 4*x[1]*(1.-x[1]); return y;")
+g_v = Expression(("4*x[1]*(1.-x[1])", "0.0"))
+g_p = Expression("8*(1.-x[0])")
+g_S = Expression(("0.0", "0.0", "-8*x[1] + 4.", "0.0"))
+g = g_v * g_p * g_S
 
 cell = triangle
-P2 = VectorElement("Lagrange", cell, 2, dirichlet_constraints=v_bctype, dirichlet_expression=v_dirichlet)
+P2 = VectorElement("Lagrange", cell, 2, dirichlet_constraints=v_bctype, dirichlet_expression=g_v)
 P1 = FiniteElement("Lagrange", cell, 1)
-P2_stress = TensorElement("Lagrange", cell, 2)
+P2_stress = TensorElement("DG", cell, 1)
 
 TH = MixedElement(P2, P1, P2_stress)
 
 v, q, T  = TestFunctions(TH)
 u, p, S  = TrialFunctions(TH)
 
-r = (inner(grad(v), S) + inner(S - grad(u), T)- div(v)*p - q*div(u))*dx
+r = (inner(grad(v), S) + inner(grad(u) - S, T) - div(v)*p - q*div(u))*dx
 
 forms = [r]