diff --git a/grudge/discretization.py b/grudge/discretization.py
index 817a0bc20b1c0708e6788ba042265cc1e1ea256b..02283d412ade424c090cc0092d8db4d7675b495d 100644
--- a/grudge/discretization.py
+++ b/grudge/discretization.py
@@ -63,15 +63,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
 
@@ -83,21 +81,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):
@@ -109,19 +110,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
@@ -149,18 +143,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 287355829aa82d0c36817d0a00e8e0b3fb6f81b9..f038ad07b4c4fe38c9cafe0f9491f6584062803c 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)
@@ -275,17 +275,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(
@@ -293,7 +293,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 9eb8e2b3bcb18c822335a8a6a884daf903ae3efc..405cb5f06706116266322c3d9ab0ab1c206a6c22 100644
--- a/grudge/symbolic/mappers/__init__.py
+++ b/grudge/symbolic/mappers/__init__.py
@@ -573,16 +573,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)
@@ -854,7 +854,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 dc2e4fa1afd8cf6bd91ff1faa8b8df7a34b06a46..34ec47aaa556369ecea8e688f81bdcbaa0a6db3f 100644
--- a/grudge/symbolic/operators.py
+++ b/grudge/symbolic/operators.py
@@ -384,11 +384,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")
@@ -403,7 +403,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)
@@ -413,7 +413,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 11d5ae8a5dc802b0a75d0f705494b6483ac40b78..2f3e8787ec7620151d4abdf973c8a5b3d0d4d0f3 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  # 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: