diff --git a/grudge/discretization.py b/grudge/discretization.py
index 50e112def7a9a4e64d8697bc46c3b33f22191715..b3596acbe2448cf0367df9ddcf9aee18a41678c2 100644
--- a/grudge/discretization.py
+++ b/grudge/discretization.py
@@ -62,15 +62,13 @@ class Discretization(DiscretizationBase):
         if quad_min_degrees is None:
             quad_min_degrees = {}
 
+        self.order = order
+        self.quad_min_degrees = quad_min_degrees
+
         from meshmode.discretization import Discretization
-        from meshmode.discretization.poly_element import \
-                PolynomialWarpAndBlendGroupFactory
 
         self.volume_discr = Discretization(cl_ctx, mesh,
-                PolynomialWarpAndBlendGroupFactory(order=order))
-
-        self.order = order
-        self.quad_min_degrees = quad_min_degrees
+                self.get_group_factory_for_quadrature_tag(sym.QTAG_NONE))
 
         # {{{ management of discretization-scoped common subexpressions
 
@@ -82,21 +80,24 @@ class Discretization(DiscretizationBase):
 
         # }}}
 
-    # {{{ boundary
+    def get_group_factory_for_quadrature_tag(self, quadrature_tag):
+        if quadrature_tag is not sym.QTAG_NONE:
+            # FIXME
+            raise NotImplementedError("quadrature")
 
-    @memoize_method
-    def boundary_connection(self, boundary_tag, quadrature_tag=None):
         from meshmode.discretization.poly_element import \
                 PolynomialWarpAndBlendGroupFactory
 
-        if quadrature_tag is not sym.QTAG_NONE:
-            # FIXME
-            raise NotImplementedError("quadrature")
+        return PolynomialWarpAndBlendGroupFactory(order=self.order)
 
+    # {{{ boundary
+
+    @memoize_method
+    def boundary_connection(self, boundary_tag, quadrature_tag=None):
         from meshmode.discretization.connection import make_face_restriction
         return make_face_restriction(
                         self.volume_discr,
-                        PolynomialWarpAndBlendGroupFactory(order=self.order),
+                        self.get_group_factory_for_quadrature_tag(quadrature_tag),
                         boundary_tag=boundary_tag)
 
     def boundary_discr(self, boundary_tag, quadrature_tag=None):
@@ -108,19 +109,12 @@ class Discretization(DiscretizationBase):
 
     @memoize_method
     def interior_faces_connection(self, quadrature_tag=None):
-        from meshmode.discretization.poly_element import \
-                PolynomialWarpAndBlendGroupFactory
-
-        if quadrature_tag is not sym.QTAG_NONE:
-            # FIXME
-            raise NotImplementedError("quadrature")
-
         from meshmode.discretization.connection import (
-                make_face_restriction, FRESTR_INTERIOR_FACES)
+                make_face_restriction, FACE_RESTR_INTERIOR)
         return make_face_restriction(
                         self.volume_discr,
-                        PolynomialWarpAndBlendGroupFactory(order=self.order),
-                        FRESTR_INTERIOR_FACES,
+                        self.get_group_factory_for_quadrature_tag(quadrature_tag),
+                        FACE_RESTR_INTERIOR,
 
                         # FIXME: This will need to change as soon as we support
                         # pyramids or other elements with non-identical face
@@ -148,18 +142,12 @@ class Discretization(DiscretizationBase):
 
     @memoize_method
     def all_faces_volume_connection(self, quadrature_tag=None):
-        if quadrature_tag is not sym.QTAG_NONE:
-            # FIXME
-            raise NotImplementedError("quadrature")
-
-        from meshmode.discretization.poly_element import \
-                PolynomialWarpAndBlendGroupFactory
         from meshmode.discretization.connection import (
-                make_face_restriction, FRESTR_ALL_FACES)
+                make_face_restriction, FACE_RESTR_ALL)
         return make_face_restriction(
                         self.volume_discr,
-                        PolynomialWarpAndBlendGroupFactory(order=self.order),
-                        FRESTR_ALL_FACES,
+                        self.get_group_factory_for_quadrature_tag(quadrature_tag),
+                        FACE_RESTR_ALL,
 
                         # FIXME: This will need to change as soon as we support
                         # pyramids or other elements with non-identical face
diff --git a/grudge/execution.py b/grudge/execution.py
index c48cc39298d24705dc7a18d616a50851e620cdb0..f33e2a1e9ebaacd3cb0c0917ea558b1bd3733d59 100644
--- a/grudge/execution.py
+++ b/grudge/execution.py
@@ -59,9 +59,9 @@ class ExecutionMapper(mappers.Evaluator,
                 raise NotImplementedError("quadrature")
             return self.discr.volume_discr
 
-        elif dd.domain_tag is sym.FRESTR_ALL_FACES:
+        elif dd.domain_tag is sym.FACE_RESTR_ALL:
             return self.discr.all_faces_discr(qtag)
-        elif dd.domain_tag is sym.FRESTR_INTERIOR_FACES:
+        elif dd.domain_tag is sym.FACE_RESTR_INTERIOR:
             return self.discr.interior_faces_discr(qtag)
         elif dd.is_boundary():
             return self.discr.boundary_discr(dd.domain_tag, qtag)
@@ -249,17 +249,17 @@ class ExecutionMapper(mappers.Evaluator,
             qtag = sym.QTAG_NONE
 
         if dd_in.is_volume():
-            if dd_out.domain_tag is sym.FRESTR_ALL_FACES:
+            if dd_out.domain_tag is sym.FACE_RESTR_ALL:
                 conn = self.discr.all_faces_connection(qtag)
-            elif dd_out.domain_tag is sym.FRESTR_INTERIOR_FACES:
+            elif dd_out.domain_tag is sym.FACE_RESTR_INTERIOR:
                 conn = self.discr.interior_faces_connection(qtag)
             elif dd_out.is_boundary():
                 conn = self.discr.boundary_connection(dd_out.domain_tag, qtag)
             else:
                 raise ValueError("cannot interpolate from volume to: " + str(dd_out))
 
-        elif dd_in.domain_tag is sym.FRESTR_INTERIOR_FACES:
-            if dd_out.domain_tag is sym.FRESTR_ALL_FACES:
+        elif dd_in.domain_tag is sym.FACE_RESTR_INTERIOR:
+            if dd_out.domain_tag is sym.FACE_RESTR_ALL:
                 conn = self.discr.all_faces_connection(None, qtag)
             else:
                 raise ValueError(
@@ -267,7 +267,7 @@ class ExecutionMapper(mappers.Evaluator,
                         + str(dd_out))
 
         elif dd_in.is_boundary():
-            if dd_out.domain_tag is sym.FRESTR_ALL_FACES:
+            if dd_out.domain_tag is sym.FACE_RESTR_ALL:
                 conn = self.discr.all_faces_connection(dd_in.domain_tag, qtag)
             else:
                 raise ValueError(
diff --git a/grudge/symbolic/mappers/__init__.py b/grudge/symbolic/mappers/__init__.py
index 933d1fbfd7b049c8fd18eee18d579909101af457..f9cde6aaee0db43c4df17b94885e0989f66a7dc2 100644
--- a/grudge/symbolic/mappers/__init__.py
+++ b/grudge/symbolic/mappers/__init__.py
@@ -593,16 +593,16 @@ class StringifyMapper(pymbolic.mapper.stringifier.StringifyMapper):
                 return repr(s)
 
         from meshmode.discretization.connection import (
-                FRESTR_ALL_FACES, FRESTR_INTERIOR_FACES)
+                FACE_RESTR_ALL, FACE_RESTR_INTERIOR)
         if dd.domain_tag is None:
             result = "?"
         elif dd.domain_tag is sym.DTAG_VOLUME_ALL:
             result = "vol"
         elif dd.domain_tag is sym.DTAG_SCALAR:
             result = "scalar"
-        elif dd.domain_tag is FRESTR_ALL_FACES:
+        elif dd.domain_tag is FACE_RESTR_ALL:
             result = "all_faces"
-        elif dd.domain_tag is FRESTR_INTERIOR_FACES:
+        elif dd.domain_tag is FACE_RESTR_INTERIOR:
             result = "int_faces"
         else:
             result = fmt(dd.domain_tag)
@@ -871,7 +871,7 @@ class EmptyFluxKiller(CSECachingMapperMixin, IdentityMapper):
         if (isinstance(expr.op, sym.InterpolationOperator)
                 and expr.op.dd_out.is_boundary()
                 and expr.op.dd_out.domain_tag not in [
-                    sym.FRESTR_ALL_FACES, sym.FRESTR_INTERIOR_FACES]
+                    sym.FACE_RESTR_ALL, sym.FACE_RESTR_INTERIOR]
                 and is_boundary_tag_empty(self.mesh,
                     expr.op.dd_out.domain_tag)):
             return 0
diff --git a/grudge/symbolic/operators.py b/grudge/symbolic/operators.py
index 8bde018dc0e18b05ccad2666bbbd9d96e750a2a5..efabdaa3639b41a8bc3784b9ec2aa4130e153a38 100644
--- a/grudge/symbolic/operators.py
+++ b/grudge/symbolic/operators.py
@@ -405,11 +405,11 @@ class OppositeInteriorFaceSwap(Operator):
         sym = _sym()
 
         if dd_in is None:
-            dd_in = sym.DOFDesc(sym.FRESTR_INTERIOR_FACES, None)
+            dd_in = sym.DOFDesc(sym.FACE_RESTR_INTERIOR, None)
         if dd_out is None:
             dd_out = dd_in
 
-        if dd_in.domain_tag is not sym.FRESTR_INTERIOR_FACES:
+        if dd_in.domain_tag is not sym.FACE_RESTR_INTERIOR:
             raise ValueError("dd_in must be an interior faces domain")
         if dd_out != dd_in:
             raise ValueError("dd_out and dd_in must be identical")
@@ -424,7 +424,7 @@ class FaceMassOperatorBase(ElementwiseLinearOperator):
         sym = _sym()
 
         if dd_in is None:
-            dd_in = sym.DOFDesc(sym.FRESTR_ALL_FACES, None)
+            dd_in = sym.DOFDesc(sym.FACE_RESTR_ALL, None)
 
         if dd_out is None:
             dd_out = sym.DOFDesc("vol", sym.QTAG_NONE)
@@ -434,7 +434,7 @@ class FaceMassOperatorBase(ElementwiseLinearOperator):
 
         if not dd_out.is_volume():
             raise ValueError("dd_out must be a volume domain")
-        if dd_in.domain_tag is not sym.FRESTR_ALL_FACES:
+        if dd_in.domain_tag is not sym.FACE_RESTR_ALL:
             raise ValueError("dd_in must be an interior faces domain")
 
         super(FaceMassOperatorBase, self).__init__(dd_in, dd_out)
diff --git a/grudge/symbolic/primitives.py b/grudge/symbolic/primitives.py
index a6593e998ba64d4574a0eb0aecae79c56cc3e4b9..5b21b3d0b44b6f17039cf0ef5b8318d7dd8c3b17 100644
--- a/grudge/symbolic/primitives.py
+++ b/grudge/symbolic/primitives.py
@@ -30,7 +30,7 @@ import numpy as np
 import pymbolic.primitives
 from meshmode.mesh import BTAG_ALL, BTAG_REALLY_ALL, BTAG_NONE, BTAG_PARTITION  # noqa
 from meshmode.discretization.connection import (  # noqa
-        FRESTR_ALL_FACES, FRESTR_INTERIOR_FACES)
+        FACE_RESTR_ALL, FACE_RESTR_INTERIOR)
 
 from pymbolic.primitives import (  # noqa
         cse_scope as cse_scope_base,
@@ -145,10 +145,10 @@ class DOFDesc(object):
             :class:`grudge.sym.DTAG_SCALAR` (or the string ``"scalar"``),
             :class:`grudge.sym.DTAG_VOLUME_ALL` (or the string ``"vol"``)
             for the default volume discretization,
-            :class:`meshmode.discretization.connection.FRESTR_ALL_FACES`
+            :class:`meshmode.discretization.connection.FACE_RESTR_ALL`
             (or the string ``"all_faces"``),
             or
-            :class:`meshmode.discretization.connection.FRESTR_INTERIOR_FACES`
+            :class:`meshmode.discretization.connection.FACE_RESTR_INTERIOR`
             (or the string ``"int_faces"``),
             or one of
             :class:`meshmode.discretization.BTAG_ALL`,
@@ -172,12 +172,12 @@ class DOFDesc(object):
         elif domain_tag is DTAG_VOLUME_ALL:
             pass
         elif domain_tag == "all_faces":
-            domain_tag = FRESTR_ALL_FACES
-        elif domain_tag is FRESTR_ALL_FACES:
+            domain_tag = FACE_RESTR_ALL
+        elif domain_tag is FACE_RESTR_ALL:
             pass
         elif domain_tag == "int_faces":
-            domain_tag = FRESTR_INTERIOR_FACES
-        elif domain_tag is FRESTR_INTERIOR_FACES:
+            domain_tag = FACE_RESTR_INTERIOR
+        elif domain_tag is FACE_RESTR_INTERIOR:
             pass
         elif domain_tag is None:
             pass
@@ -215,8 +215,8 @@ class DOFDesc(object):
     def is_trace(self):
         return (self.is_boundary()
                 or self.domain_tag in [
-                    FRESTR_ALL_FACES,
-                    FRESTR_INTERIOR_FACES])
+                    FACE_RESTR_ALL,
+                    FACE_RESTR_INTERIOR])
 
     def uses_quadrature(self):
         if self.quadrature_tag is None: