diff --git a/grudge/discretization.py b/grudge/discretization.py index 19b9230ba592cec49c2cb381f993c26de762a7f8..e84016c61a7f8591ccd546b4bd1556b832c225f9 100644 --- a/grudge/discretization.py +++ b/grudge/discretization.py @@ -76,6 +76,10 @@ class DiscretizationCollection: .. automethod:: nodes .. automethod:: normal + + .. rubric:: Internal functionality + + .. automethod:: _base_to_geoderiv_connection """ # {{{ constructor @@ -309,6 +313,64 @@ class DiscretizationCollection: # }}} + # {{{ _base_to_geoderiv_connection + + @memoize_method + def _has_affine_groups(self): + from modepy.shapes import Simplex + return any( + megrp.is_affine + and issubclass(megrp._modepy_shape_cls, Simplex) + for megrp in self._volume_discr.mesh.groups) + + @memoize_method + def _base_to_geoderiv_connection(self, dd: DOFDesc): + r"""The "geometry derivatives" discretization for a given *dd* is + typically identical to the one returned by :meth:`discr_from_dd`, + however for affinely-mapped simplicial elements, it will use a + :math:`P^0` discretization having a single DOF per element. + As a result, :class:`~meshmode.dof_array.DOFArray`\ s on this + are broadcast-compatible with the discretizations returned by + :meth:`discr_from_dd`. + + This is an internal function, not intended for use outside + :mod:`grudge`. + """ + base_discr = self.discr_from_dd(dd) + if not self._has_affine_groups(): + # no benefit to having another discretization that takes + # advantage of affine-ness + from meshmode.discretization.connection import \ + IdentityDiscretizationConnection + return IdentityDiscretizationConnection(base_discr) + + base_group_factory = self.group_factory_for_discretization_tag( + dd.discretization_tag) + + def geo_group_factory(megrp, index): + from modepy.shapes import Simplex + from meshmode.discretization.poly_element import \ + PolynomialEquidistantSimplexElementGroup + if megrp.is_affine and issubclass(megrp._modepy_shape_cls, Simplex): + return PolynomialEquidistantSimplexElementGroup( + megrp, order=0, index=index) + else: + return base_group_factory(megrp, index) + + from meshmode.discretization import Discretization + geo_deriv_discr = Discretization( + self._setup_actx, base_discr.mesh, + geo_group_factory) + + from meshmode.discretization.connection.same_mesh import \ + make_same_mesh_connection + return make_same_mesh_connection( + self._setup_actx, + to_discr=geo_deriv_discr, + from_discr=base_discr) + + # }}} + # {{{ connection_from_dds @memoize_method