diff --git a/hog/forms.py b/hog/forms.py
index 081b05854ac98850d1a6621498542ee5e0cfedaf..4a9439ad920f1796126b7f3085311ebe056adf36 100644
--- a/hog/forms.py
+++ b/hog/forms.py
@@ -33,7 +33,13 @@ from hog.fem_helpers import (
     fem_function_on_element,
     fem_function_gradient_on_element,
 )
-from hog.function_space import FunctionSpace, N1E1Space, TrialSpace, TestSpace, LagrangianFunctionSpace
+from hog.function_space import (
+    FunctionSpace,
+    N1E1Space,
+    TrialSpace,
+    TestSpace,
+    LagrangianFunctionSpace,
+)
 from hog.math_helpers import dot, inv, abs, det, double_contraction
 from hog.quadrature import Quadrature, Tabulation
 from hog.symbolizer import Symbolizer
@@ -322,7 +328,6 @@ def epsilon(
     variable_viscosity: bool = True,
     coefficient_function_space: Optional[FunctionSpace] = None,
     rotation_wrapper: bool = False,
-    normal_fspace: Optional[FunctionSpace] = None,
 ) -> Form:
     docstring = f"""
 "Epsilon" operator.
@@ -342,10 +347,10 @@ where
     ε(w) := (1/2) (∇w + (∇w)ᵀ)
 """
 
-    
     if not variable_viscosity:
         raise HOGException("Constant viscosity currently not supported.")
 
+    from hog.recipes.integrands.volume.rotation import RotationType
     from hog.recipes.integrands.volume.epsilon import integrand
     from hog.recipes.integrands.volume.epsilon_affine import (
         integrand as integrand_affine,
@@ -357,8 +362,6 @@ where
     if blending == IdentityMap():
         integr = integrand_affine
 
-
-
     return process_integrand(
         integr,
         trial,
@@ -369,7 +372,9 @@ where
         is_symmetric=trial == test,
         docstring=docstring,
         fe_coefficients={"mu": coefficient_function_space},
-        rotation_wrapper=rotation_wrapper,
+        rot_type=RotationType.PRE_AND_POST_MULTIPLY
+        if rotation_wrapper
+        else RotationType.NO_ROTATION,
     )
 
 
@@ -547,6 +552,7 @@ def divergence(
     symbolizer: Symbolizer,
     blending: GeometryMap = IdentityMap(),
     component_index: int = 0,
+    rotation_wrapper: bool = False,
 ) -> Form:
     docstring = f"""
 Divergence.
@@ -563,6 +569,7 @@ Weak formulation
 """
 
     from hog.recipes.integrands.volume.divergence import integrand
+    from hog.recipes.integrands.volume.rotation import RotationType
 
     return process_integrand(
         integrand,
@@ -573,6 +580,9 @@ Weak formulation
         blending=blending,
         is_symmetric=False,
         docstring=docstring,
+        rot_type=RotationType.POST_MULTIPLY
+        if rotation_wrapper
+        else RotationType.NO_ROTATION,
     )
 
 
@@ -583,6 +593,7 @@ def gradient(
     symbolizer: Symbolizer,
     blending: GeometryMap = IdentityMap(),
     component_index: int = 0,
+    rotation_wrapper: bool = False,
 ) -> Form:
     docstring = f"""
     Gradient.
@@ -599,6 +610,7 @@ def gradient(
     """
 
     from hog.recipes.integrands.volume.gradient import integrand
+    from hog.recipes.integrands.volume.rotation import RotationType
 
     return process_integrand(
         integrand,
@@ -609,6 +621,9 @@ def gradient(
         blending=blending,
         is_symmetric=False,
         docstring=docstring,
+        rot_type=RotationType.PRE_MULTIPLY
+        if rotation_wrapper
+        else RotationType.NO_ROTATION,
     )
 
 
@@ -774,6 +789,7 @@ The resulting matrix must be multiplied with a vector of ones to be used as the
         docstring=docstring,
     )
 
+
 def divdiv(
     trial: TrialSpace,
     test: TestSpace,
@@ -851,11 +867,10 @@ Weak formulation
         blending=blending,
         is_symmetric=trial == test,
         docstring=docstring,
-        fe_coefficients={
-            "k": coefficient_function_space
-        }
+        fe_coefficients={"k": coefficient_function_space},
     )
 
+
 def advection(
     trial: TrialSpace,
     test: TestSpace,
@@ -895,7 +910,9 @@ Weak formulation
             "ux": velocity_function_space,
             "uy": velocity_function_space,
             "uz": velocity_function_space,
-        } if constant_cp else {
+        }
+        if constant_cp
+        else {
             "ux": velocity_function_space,
             "uy": velocity_function_space,
             "uz": velocity_function_space,
diff --git a/hog/integrand.py b/hog/integrand.py
index 7f82fed228c8de2b2e27c10d762b74f647ec3890..b43c3721b4d8675859838c62be39214636610053 100644
--- a/hog/integrand.py
+++ b/hog/integrand.py
@@ -88,8 +88,6 @@ class Form:
     symmetric: bool
     free_symbols: List[sp.Symbol] = field(default_factory=lambda: list())
     docstring: str = ""
-    rotmat: sp.MatrixBase = sp.Matrix([0])
-    rot_type: RotationType = RotationType.NO_ROTATION
 
     def integrate(self, quad: Quadrature, symbolizer: Symbolizer) -> sp.Matrix:
         """Integrates the form using the passed quadrature directly, i.e. without tabulations or loops."""
@@ -233,7 +231,7 @@ def process_integrand(
     boundary_geometry: ElementGeometry | None = None,
     fe_coefficients: Dict[str, Union[FunctionSpace, None]] | None = None,
     is_symmetric: bool = False,
-    rotation_wrapper: bool = False,
+    rot_type: RotationType = RotationType.NO_ROTATION,
     docstring: str = "",
 ) -> Form:
     """
@@ -496,13 +494,45 @@ def process_integrand(
 
     free_symbols_sorted = sorted(list(free_symbols), key=lambda x: str(x))
 
-    if rotation_wrapper:
-        if not trial.is_vectorial:
-            raise HOGException("Rotation wrapper can only work with vectorial spaces")
+    if not rot_type == RotationType.NO_ROTATION:
+        if rot_type == RotationType.PRE_AND_POST_MULTIPLY:
+            if not trial == test:
+                HOGException(
+                    "Trial and Test spaces must be the same for RotationType.PRE_AND_POST_MULTIPLY"
+                )
+
+            if not trial.is_vectorial:
+                raise HOGException(
+                    "Rotation wrapper can only work with vectorial spaces"
+                )
+
+            rot_space = TensorialVectorFunctionSpace(
+                LagrangianFunctionSpace(trial.degree, symbolizer)
+            )
+
+        elif rot_type == RotationType.PRE_MULTIPLY:
+            if not test.is_vectorial:
+                raise HOGException(
+                    "Rotation wrapper can only work with vectorial spaces"
+                )
+
+            rot_space = TensorialVectorFunctionSpace(
+                LagrangianFunctionSpace(test.degree, symbolizer)
+            )
+
+        elif rot_type == RotationType.POST_MULTIPLY:
+            if not trial.is_vectorial:
+                raise HOGException(
+                    "Rotation wrapper can only work with vectorial spaces"
+                )
+
+            rot_space = TensorialVectorFunctionSpace(
+                LagrangianFunctionSpace(trial.degree, symbolizer)
+            )
 
         from hog.recipes.integrands.volume.rotation import rotation_matrix
 
-        normal_fspace = LagrangianFunctionSpace(trial.degree, symbolizer)
+        normal_fspace = rot_space.component_function_space
 
         normals = (
             ["nx_rotation", "ny_rotation"]
@@ -532,12 +562,19 @@ def process_integrand(
                 n_dof_symbols.append(nc_dof_symbols)
 
         rotmat = rotation_matrix(
-            trial.num_dofs(volume_geometry),
-            int(trial.num_dofs(volume_geometry) / volume_geometry.dimensions),
+            rot_space.num_dofs(volume_geometry),
+            int(rot_space.num_dofs(volume_geometry) / volume_geometry.dimensions),
             n_dof_symbols,
             volume_geometry,
         )
 
+        if rot_type == RotationType.PRE_AND_POST_MULTIPLY:
+            mat = rotmat * mat * rotmat.T
+        elif rot_type == RotationType.PRE_MULTIPLY:
+            mat = rotmat * mat
+        elif rot_type == RotationType.POST_MULTIPLY:
+            mat = mat * rotmat.T
+
         docstring += f"""
 
 And the assembled FE matrix (K) is wrapped with a Rotation matrix (R) locally as below,
@@ -560,6 +597,4 @@ where
         symmetric=is_symmetric,
         free_symbols=free_symbols_sorted,
         docstring=docstring,
-        rotmat=rotmat if rotation_wrapper else sp.Matrix([0]),
-        rot_type=RotationType.PRE_AND_POST_MULTIPLY if rotation_wrapper else RotationType.NO_ROTATION,
     )
diff --git a/hog/operator_generation/operators.py b/hog/operator_generation/operators.py
index 3bc0c03b617bc31185326040fe3fe1ea876038c0..78181e54045231302d4eded19c20da780c36704c 100644
--- a/hog/operator_generation/operators.py
+++ b/hog/operator_generation/operators.py
@@ -398,17 +398,6 @@ class HyTeGElementwiseOperator:
                                 mat[row, col], self.symbolizer, blending
                             )
 
-        if not form.rot_type == RotationType.NO_ROTATION:
-            if form.rot_type == RotationType.PRE_AND_POST_MULTIPLY:
-                mat = form.rotmat * mat * form.rotmat.T
-            elif form.rot_type == RotationType.PRE_MULTIPLY:
-                mat = form.rotmat * mat
-            elif form.rot_type == RotationType.POST_MULTIPLY:
-                mat = mat * form.rotmat.T
-            else:
-                raise HOGException("Not implemented")
-
-
         if volume_geometry.space_dimension not in self.integration_infos:
             self.integration_infos[volume_geometry.space_dimension] = []