# Source code for ufl_legacy.finiteelement.restrictedelement

    # -*- coding: utf-8 -*-
    "This module defines the UFL finite element classes."

    # Copyright (C) 2008-2016 Martin Sandve Alnæs
    #
    # This file is part of UFL (https://www.fenicsproject.org)
    #
    # SPDX-License-Identifier:    LGPL-3.0-or-later
    #
    # Modified by Kristian B. Oelgaard
    # Modified by Marie E. Rognes 2010, 2012
    # Modified by Massimiliano Leoni, 2016

    from ufl_legacy.finiteelement.finiteelementbase import FiniteElementBase
    from ufl_legacy.log import error

    valid_restriction_domains = ("interior", "facet", "face", "edge", "vertex")

    class RestrictedElement(FiniteElementBase):
        "Represents the restriction of a finite element to a type of cell entity."
        def __init__(self, element, restriction_domain):
            if not isinstance(element, FiniteElementBase):
                error("Expecting a finite element instance.")
            if restriction_domain not in valid_restriction_domains:
                error("Expecting one of the strings %s." % (valid_restriction_domains,))

            FiniteElementBase.__init__(self, "RestrictedElement", element.cell(),
                                       element.degree(),
                                       element.quadrature_scheme(),
                                       element.value_shape(),
                                       element.reference_value_shape())

            self._element = element

            self._restriction_domain = restriction_domain

            self._repr = "RestrictedElement(%s, %s)" % (
                repr(self._element), repr(self._restriction_domain))

        def is_cellwise_constant(self):
            """Return whether the basis functions of this element is spatially
            constant over each cell.

            """
            return self._element.is_cellwise_constant()

        def sub_element(self):
            "Return the element which is restricted."
            return self._element

        def mapping(self):
            return self._element.mapping()

        def restriction_domain(self):
            "Return the domain onto which the element is restricted."
            return self._restriction_domain

        def reconstruct(self, **kwargs):
            element = self._element.reconstruct(**kwargs)
            return RestrictedElement(element, self._restriction_domain)

        def __str__(self):
            "Format as string for pretty printing."
            return "<%s>|_{%s}" % (self._element, self._restriction_domain)

        def shortstr(self):
            "Format as string for pretty printing."
            return "<%s>|_{%s}" % (self._element.shortstr(),
                                   self._restriction_domain)

        def symmetry(self):
            """Return the symmetry dict, which is a mapping :math:`c_0 \\to c_1`
            meaning that component :math:`c_0` is represented by component
            :math:`c_1`.  A component is a tuple of one or more ints.

            """
            return self._element.symmetry()

        def num_sub_elements(self):
            "Return number of sub elements."
            return self._element.num_sub_elements()

        def sub_elements(self):
            "Return list of sub elements."
            return self._element.sub_elements()

        def num_restricted_sub_elements(self):
            # FIXME: Use this where intended, for disambiguation
            #        w.r.t. different sub_elements meanings.
            "Return number of restricted sub elements."
            return 1

        def restricted_sub_elements(self):
            # FIXME: Use this where intended, for disambiguation
            #        w.r.t. different sub_elements meanings.
            "Return list of restricted sub elements."
            return (self._element,)