diff --git a/python/dune/perftool/compile.py b/python/dune/perftool/compile.py
index dfcaeba86bdd21bff5b956aa330f016243e2d7c6..7c0b169a108c2b1063d2c0bbc2fcc2ebea90c899 100644
--- a/python/dune/perftool/compile.py
+++ b/python/dune/perftool/compile.py
@@ -36,29 +36,13 @@ def read_ufl(uflfile):
     formdatas = []
     forms = data.forms
     for index, form in enumerate(forms):
-        from dune.perftool.ufl.execution import (JacobianDeterminant,
-                                                 JacobianInverse)
-        formdatas.append(compute_form_data(form,
-                                           do_apply_function_pullbacks=True,
-                                           do_apply_geometry_lowering=True,
-                                           do_apply_integral_scaling=True,
-                                           preserve_geometry_types=(JacobianDeterminant, JacobianInverse)
-                                           )
-                         )
+        from dune.perftool.ufl.preprocess import preprocess_form
+        formdatas.append(preprocess_form(form))
         forms[index] = formdatas[index].preprocessed_form
 
     # We expect at least one form
     assert len(data.forms) >= 1
 
-    # apply some transformations unconditionally!
-    from dune.perftool.ufl.transformations import transform_form
-    from dune.perftool.ufl.transformations.indexpushdown import pushdown_indexed
-    from dune.perftool.ufl.transformations.reindexing import reindexing
-    for i in range(len(forms)):
-        forms[i] = transform_form(forms[i], pushdown_indexed)
-        forms[i] = transform_form(forms[i], reindexing)
-        formdatas[i].preprocessed_form = forms[i]
-
     return formdatas, data
 
 
diff --git a/python/dune/perftool/loopy/transformer.py b/python/dune/perftool/loopy/transformer.py
index bb9efa516b971c03007322216aa59e5cff34523b..ae3396eb0f011d6688c09173683abe2424534941 100644
--- a/python/dune/perftool/loopy/transformer.py
+++ b/python/dune/perftool/loopy/transformer.py
@@ -204,7 +204,7 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker, UFL2PymbolicMapper, GeometryMapp
 
         if self.reference_grad:
             from dune.perftool.pdelab.basis import name_reference_gradient
-            return Subscript(Variable(name_reference_gradient(leaf_element, restriction)), (Variable(iname),))
+            return Subscript(Variable(name_reference_gradient(leaf_element, restriction)), (Variable(iname), 0))
         else:
             from dune.perftool.pdelab.basis import name_basis
             return Subscript(Variable(name_basis(leaf_element, restriction)), (Variable(iname),))
diff --git a/python/dune/perftool/pdelab/basis.py b/python/dune/perftool/pdelab/basis.py
index 416e1cbb29b000a3c1815445faee7b9e854bec49..88b5eed964a2d9c5463dbdead355987ab9f7bdc6 100644
--- a/python/dune/perftool/pdelab/basis.py
+++ b/python/dune/perftool/pdelab/basis.py
@@ -365,7 +365,7 @@ def evaluate_coefficient_gradient(element, name, container, restriction, compone
     coeff = pymbolic_coefficient(container, lfs, index)
     assignee = Subscript(Variable(name), tuple(Variable(i) for i in idims))
 
-    reduction_expr = Product((coeff, Subscript(Variable(basis), (Variable(index), Variable(idims[-1])))))
+    reduction_expr = Product((coeff, Subscript(Variable(basis), (Variable(index), 0, Variable(idims[-1])))))
 
     instruction(expression=Reduction("sum", index, reduction_expr, allow_simultaneous=True),
                 assignee=assignee,
diff --git a/python/dune/perftool/pdelab/geometry.py b/python/dune/perftool/pdelab/geometry.py
index 143a1356214859963345328a0529c07e9800156d..1834f4a4fd2be7f08f04e58bcf80d7d5c4564ee1 100644
--- a/python/dune/perftool/pdelab/geometry.py
+++ b/python/dune/perftool/pdelab/geometry.py
@@ -50,12 +50,19 @@ class GeometryMapper(MultiFunction):
         return Variable(name_jacobian_determinant())
 
     def jacobian_inverse(self, o):
+        restriction = self.restriction
+        if self.measure == 'exterior_facet':
+            restriction = Restriction.NEGATIVE
+
         self.transpose_necessary = True
-        return Variable(name_jacobian_inverse_transposed(self.restriction))
+        return Variable(name_jacobian_inverse_transposed(restriction))
 
     def jacobian(self, o):
         raise NotImplementedError("How did you get Jacobian into your form? We only support JacobianInverse right now. Report!")
 
+    def facet_jacobian_determinant(self, o):
+        return Variable(name_facet_jacobian_determinant())
+
 
 @iname
 def _dimension_iname(context, count):
@@ -341,3 +348,9 @@ def name_jacobian_determinant():
     name = 'detjac'
     define_jacobian_determinant(name)
     return name
+
+
+def name_facet_jacobian_determinant():
+    name = 'fdetjac'
+    define_jacobian_determinant(name)
+    return name
\ No newline at end of file
diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py
index 1b65c0a33653917aa1065d86789fdbe7e86cb799..612eb77b1e4e4b23469ae3be02298ec5ed07c915 100644
--- a/python/dune/perftool/pdelab/localoperator.py
+++ b/python/dune/perftool/pdelab/localoperator.py
@@ -485,7 +485,7 @@ def generate_localoperator_kernels(formdata, data):
                     # In the case of matrix free operator evaluation we need jacobian apply methods
                     if get_option("matrix_free"):
                         from dune.perftool.pdelab.driver import is_linear
-                        if is_linear(form):
+                        if is_linear(formdata.original_form):
                             # Numeical jacobian apply base class
                             base_class("Dune::PDELab::NumericalJacobianApply{}<{}>".format(which, loptype), classtag="operator")
 
@@ -509,17 +509,10 @@ def generate_localoperator_kernels(formdata, data):
     # Generate the necessary jacobian methods
     if not get_option("numerical_jacobian"):
         from ufl import derivative
-        from ufl.algorithms import compute_form_data
-        from dune.perftool.ufl.execution import (JacobianDeterminant,
-                                                 JacobianInverse,
-                                                 )
         jacform = derivative(formdata.original_form, formdata.original_form.coefficients()[0])
-        jacform = compute_form_data(jacform,
-                                    do_apply_function_pullbacks=True,
-                                    do_apply_geometry_lowering=True,
-                                    do_apply_integral_scaling=True,
-                                    preserve_geometry_types=(JacobianDeterminant, JacobianInverse),
-                                    ).preprocessed_form
+
+        from dune.perftool.ufl.preprocess import preprocess_form
+        jacform = preprocess_form(jacform).preprocessed_form
 
         with global_context(form_type="jacobian"):
             for measure in set(i.integral_type() for i in jacform.integrals()):
diff --git a/python/dune/perftool/pdelab/quadrature.py b/python/dune/perftool/pdelab/quadrature.py
index 5db88540ad6e001d6a7753414924e17ebc543b8d..91a25b3318a047ccfb85a2be19dd5311d80cad1f 100644
--- a/python/dune/perftool/pdelab/quadrature.py
+++ b/python/dune/perftool/pdelab/quadrature.py
@@ -52,10 +52,18 @@ def name_quadrature_position_in_cell(restriction):
         return to_cell_coordinates(name_quadrature_position(), name_quadrature_point(), restriction)
 
 
-def name_quadrature_weight():
+def define_quadrature_weight(name):
     qp = name_quadrature_point()
-    return "{}.weight()".format(qp)
+    return quadrature_preamble(code="auto {} = {}.weight();".format(name, qp),
+                               assignees=frozenset({name})
+                               )
+
 
+def name_quadrature_weight():
+    name = 'weight'
+    temporary_variable(name, shape=())
+    define_quadrature_weight(name)
+    return name
 
 
 def name_order():
diff --git a/python/dune/perftool/ufl/preprocess.py b/python/dune/perftool/ufl/preprocess.py
new file mode 100644
index 0000000000000000000000000000000000000000..540300bb3ee61abaa89b6b958df65e879af69e46
--- /dev/null
+++ b/python/dune/perftool/ufl/preprocess.py
@@ -0,0 +1,36 @@
+""" Preprocessing algorithms for UFL forms """
+
+
+def preprocess_form(form):
+    from ufl.classes import (FacetJacobianDeterminant,
+                             FacetNormal,
+                             JacobianDeterminant,
+                             JacobianInverse,
+                             )
+
+    from ufl.algorithms import compute_form_data
+    formdata = compute_form_data(form,
+                                 do_apply_function_pullbacks=True,
+                                 do_apply_geometry_lowering=True,
+                                 do_apply_integral_scaling=True,
+                                 preserve_geometry_types=(FacetJacobianDeterminant,
+                                                          FacetNormal,
+                                                          JacobianDeterminant,
+                                                          JacobianInverse,
+                                                          )
+                                 )
+
+    formdata.preprocessed_form = apply_default_transformations(formdata.preprocessed_form)
+
+    return formdata
+
+
+def apply_default_transformations(form):
+    from dune.perftool.ufl.transformations import transform_form
+    from dune.perftool.ufl.transformations.indexpushdown import pushdown_indexed
+    from dune.perftool.ufl.transformations.reindexing import reindexing
+
+    form = transform_form(form, pushdown_indexed)
+    form = transform_form(form, reindexing)
+
+    return form