# Path: FIAT/expansions.py
# def jrc(a, b, n):
# def _tabulate_dpts(tabulator, D, n, order, pts):
#     def form_derivative(F):
#     def numpy_lambdify(X, F):
#     def evaluate_lambda(lmbd, x):
# def xi_triangle(eta):
# def xi_tetrahedron(eta):
#     def __init__(self, ref_el):
#     def get_num_members(self, n):
#     def tabulate(self, n, pts):
#     def tabulate_derivatives(self, n, pts):
#     def __init__(self, ref_el):
#     def get_num_members(self, n):
#     def tabulate(self, n, pts):
#     def tabulate_derivatives(self, n, pts):
#     def __init__(self, ref_el):
#     def get_num_members(self, n):
#     def tabulate(self, n, pts):
#     def _tabulate(self, n, pts):
#         def idx(p, q):
#     def tabulate_derivatives(self, n, pts):
#     def tabulate_jet(self, n, pts, order=1):
#     def __init__(self, ref_el):
#     def get_num_members(self, n):
#     def tabulate(self, n, pts):
#     def _tabulate(self, n, pts):
#         def idx(p, q, r):
#     def tabulate_derivatives(self, n, pts):
#     def tabulate_jet(self, n, pts, order=1):
# def get_expansion_set(ref_el):
# def polynomial_dimension(ref_el, degree):
#     X = sympy.DeferredVector('x')
#         D = 3
# class PointExpansionSet(object):
# class LineExpansionSet(object):
# class TriangleExpansionSet(object):
# class TetrahedronExpansionSet(object):
# 
# Path: FIAT/arnold_winther.py
# class ArnoldWinther(CiarletElement):
#     """The definition of the conforming Arnold-Winther element.
#     """
#     def __init__(self, cell, degree):
#         assert degree == 3, "Only defined for degree 3"
#         Ps = ONSymTensorPolynomialSet(cell, degree)
#         Ls = ArnoldWintherDual(cell, degree)
#         mapping = "double contravariant piola"
#         super(ArnoldWinther, self).__init__(Ps, Ls, degree, mapping=mapping)
# 
# Path: FIAT/quadrature.py
# def make_quadrature(ref_el, m):
#     """Returns the collapsed quadrature rule using m points per
#     direction on the given reference element. In the tensor product
#     case, m is a tuple."""
# 
#     if isinstance(m, tuple):
#         min_m = min(m)
#     else:
#         min_m = m
# 
#     msg = "Expecting at least one (not %d) quadrature point per direction" % min_m
#     assert (min_m > 0), msg
# 
#     if ref_el.get_shape() == reference_element.POINT:
#         return QuadratureRule(ref_el, [()], [1])
#     elif ref_el.get_shape() == reference_element.LINE:
#         return GaussJacobiQuadratureLineRule(ref_el, m)
#     elif ref_el.get_shape() == reference_element.TRIANGLE:
#         return CollapsedQuadratureTriangleRule(ref_el, m)
#     elif ref_el.get_shape() == reference_element.TETRAHEDRON:
#         return CollapsedQuadratureTetrahedronRule(ref_el, m)
#     elif ref_el.get_shape() == reference_element.QUADRILATERAL:
#         line_rule = GaussJacobiQuadratureLineRule(ref_el.construct_subelement(1), m)
#         return make_tensor_product_quadrature(line_rule, line_rule)
#     elif ref_el.get_shape() == reference_element.HEXAHEDRON:
#         line_rule = GaussJacobiQuadratureLineRule(ref_el.construct_subelement(1), m)
#         return make_tensor_product_quadrature(line_rule, line_rule, line_rule)
#     else:
#         raise ValueError("Unable to make quadrature for cell: %s" % ref_el)
# 
# Path: FIAT/reference_element.py
# def ufc_simplex(spatial_dim):
#     """Factory function that maps spatial dimension to an instance of
#     the UFC reference simplex of that dimension."""
#     if spatial_dim == 0:
#         return Point()
#     elif spatial_dim == 1:
#         return UFCInterval()
#     elif spatial_dim == 2:
#         return UFCTriangle()
#     elif spatial_dim == 3:
#         return UFCTetrahedron()
#     else:
#         raise RuntimeError("Can't create UFC simplex of dimension %s." % str(spatial_dim))


import numpy as np
from FIAT import ufc_simplex, ArnoldWinther, make_quadrature, expansions
                ntvals[i, j] = n @ vals[i, :, :, j] @ t

        ntmoments = np.zeros((30, 2))

        for bf in range(30):
            for k in range(nqpline):
                for m in (0, 1):
                    ntmoments[bf, m] += wts[k] * ntvals[bf, k] * linevals[m, k]

        for bf in range(30):
            if bf != AW.dual.entity_ids[1][ed][1] and bf != AW.dual.entity_ids[1][ed][3]:
                assert np.allclose(ntmoments[bf, :], np.zeros(2))

    # check internal dofs
    Q = make_quadrature(T, 6)
    qpvals = AW.tabulate(0, Q.pts)[(0, 0)]
    const_moms = qpvals @ Q.wts
    assert np.allclose(const_moms[:21], np.zeros((21, 2, 2)))
    assert np.allclose(const_moms[24:], np.zeros((6, 2, 2)))
    assert np.allclose(const_moms[21:24, 0, 0], np.asarray([1, 0, 0]))
    assert np.allclose(const_moms[21:24, 0, 1], np.asarray([0, 1, 0]))
    assert np.allclose(const_moms[21:24, 1, 0], np.asarray([0, 1, 0]))
    assert np.allclose(const_moms[21:24, 1, 1], np.asarray([0, 0, 1]))


def frob(a, b):
    return a.ravel() @ b.ravel()


def test_projection():

# Path: FIAT/expansions.py
# def jrc(a, b, n):
# def _tabulate_dpts(tabulator, D, n, order, pts):
#     def form_derivative(F):
#     def numpy_lambdify(X, F):
#     def evaluate_lambda(lmbd, x):
# def xi_triangle(eta):
# def xi_tetrahedron(eta):
#     def __init__(self, ref_el):
#     def get_num_members(self, n):
#     def tabulate(self, n, pts):
#     def tabulate_derivatives(self, n, pts):
#     def __init__(self, ref_el):
#     def get_num_members(self, n):
#     def tabulate(self, n, pts):
#     def tabulate_derivatives(self, n, pts):
#     def __init__(self, ref_el):
#     def get_num_members(self, n):
#     def tabulate(self, n, pts):
#     def _tabulate(self, n, pts):
#         def idx(p, q):
#     def tabulate_derivatives(self, n, pts):
#     def tabulate_jet(self, n, pts, order=1):
#     def __init__(self, ref_el):
#     def get_num_members(self, n):
#     def tabulate(self, n, pts):
#     def _tabulate(self, n, pts):
#         def idx(p, q, r):
#     def tabulate_derivatives(self, n, pts):
#     def tabulate_jet(self, n, pts, order=1):
# def get_expansion_set(ref_el):
# def polynomial_dimension(ref_el, degree):
#     X = sympy.DeferredVector('x')
#         D = 3
# class PointExpansionSet(object):
# class LineExpansionSet(object):
# class TriangleExpansionSet(object):
# class TetrahedronExpansionSet(object):
# 
# Path: FIAT/arnold_winther.py
# class ArnoldWinther(CiarletElement):
#     """The definition of the conforming Arnold-Winther element.
#     """
#     def __init__(self, cell, degree):
#         assert degree == 3, "Only defined for degree 3"
#         Ps = ONSymTensorPolynomialSet(cell, degree)
#         Ls = ArnoldWintherDual(cell, degree)
#         mapping = "double contravariant piola"
#         super(ArnoldWinther, self).__init__(Ps, Ls, degree, mapping=mapping)
# 
# Path: FIAT/quadrature.py
# def make_quadrature(ref_el, m):
#     """Returns the collapsed quadrature rule using m points per
#     direction on the given reference element. In the tensor product
#     case, m is a tuple."""
# 
#     if isinstance(m, tuple):
#         min_m = min(m)
#     else:
#         min_m = m
# 
#     msg = "Expecting at least one (not %d) quadrature point per direction" % min_m
#     assert (min_m > 0), msg
# 
#     if ref_el.get_shape() == reference_element.POINT:
#         return QuadratureRule(ref_el, [()], [1])
#     elif ref_el.get_shape() == reference_element.LINE:
#         return GaussJacobiQuadratureLineRule(ref_el, m)
#     elif ref_el.get_shape() == reference_element.TRIANGLE:
#         return CollapsedQuadratureTriangleRule(ref_el, m)
#     elif ref_el.get_shape() == reference_element.TETRAHEDRON:
#         return CollapsedQuadratureTetrahedronRule(ref_el, m)
#     elif ref_el.get_shape() == reference_element.QUADRILATERAL:
#         line_rule = GaussJacobiQuadratureLineRule(ref_el.construct_subelement(1), m)
#         return make_tensor_product_quadrature(line_rule, line_rule)
#     elif ref_el.get_shape() == reference_element.HEXAHEDRON:
#         line_rule = GaussJacobiQuadratureLineRule(ref_el.construct_subelement(1), m)
#         return make_tensor_product_quadrature(line_rule, line_rule, line_rule)
#     else:
#         raise ValueError("Unable to make quadrature for cell: %s" % ref_el)
# 
# Path: FIAT/reference_element.py
# def ufc_simplex(spatial_dim):
#     """Factory function that maps spatial dimension to an instance of
#     the UFC reference simplex of that dimension."""
#     if spatial_dim == 0:
#         return Point()
#     elif spatial_dim == 1:
#         return UFCInterval()
#     elif spatial_dim == 2:
#         return UFCTriangle()
#     elif spatial_dim == 3:
#         return UFCTetrahedron()
#     else:
#         raise RuntimeError("Can't create UFC simplex of dimension %s." % str(spatial_dim))


# Path: test/unit/test_awc.py
import numpy as np
from FIAT import ufc_simplex, ArnoldWinther, make_quadrature, expansions

                ntvals[i, j] = n @ vals[i, :, :, j] @ t

        ntmoments = np.zeros((30, 2))

        for bf in range(30):
            for k in range(nqpline):
                for m in (0, 1):
                    ntmoments[bf, m] += wts[k] * ntvals[bf, k] * linevals[m, k]

        for bf in range(30):
            if bf != AW.dual.entity_ids[1][ed][1] and bf != AW.dual.entity_ids[1][ed][3]:
                assert np.allclose(ntmoments[bf, :], np.zeros(2))

    # check internal dofs
    Q = make_quadrature(T, 6)
    qpvals = AW.tabulate(0, Q.pts)[(0, 0)]
    const_moms = qpvals @ Q.wts
    assert np.allclose(const_moms[:21], np.zeros((21, 2, 2)))
    assert np.allclose(const_moms[24:], np.zeros((6, 2, 2)))
    assert np.allclose(const_moms[21:24, 0, 0], np.asarray([1, 0, 0]))
    assert np.allclose(const_moms[21:24, 0, 1], np.asarray([0, 1, 0]))
    assert np.allclose(const_moms[21:24, 1, 0], np.asarray([0, 1, 0]))
    assert np.allclose(const_moms[21:24, 1, 1], np.asarray([0, 0, 1]))


def frob(a, b):
    return a.ravel() @ b.ravel()


def test_projection():

    T = ufc_simplex(2)