# Path: finat/physically_mapped.py
# class PhysicalGeometry(metaclass=ABCMeta):
# 
#     @abstractmethod
#     def cell_size(self):
#         """The cell size at each vertex.
# 
#         :returns: A GEM expression for the cell size, shape (nvertex, ).
#         """
# 
#     @abstractmethod
#     def jacobian_at(self, point):
#         """The jacobian of the physical coordinates at a point.
# 
#         :arg point: The point in reference space (on the cell) to
#              evaluate the Jacobian.
#         :returns: A GEM expression for the Jacobian, shape (gdim, tdim).
#         """
# 
#     @abstractmethod
#     def detJ_at(self, point):
#         """The determinant of the jacobian of the physical coordinates at a point.
# 
#         :arg point: The point in reference space to evaluate the Jacobian determinant.
#         :returns: A GEM expression for the Jacobian determinant.
#         """
# 
#     @abstractmethod
#     def reference_normals(self):
#         """The (unit) reference cell normals for each facet.
# 
#         :returns: A GEM expression for the normal to each
#            facet (numbered according to FIAT conventions), shape
#            (nfacet, tdim).
#         """
# 
#     @abstractmethod
#     def physical_normals(self):
#         """The (unit) physical cell normals for each facet.
# 
#         :returns: A GEM expression for the normal to each
#            facet (numbered according to FIAT conventions).  These are
#            all computed by a clockwise rotation of the physical
#            tangents, shape (nfacet, gdim).
#         """
# 
#     @abstractmethod
#     def physical_tangents(self):
#         """The (unit) physical cell tangents on each facet.
# 
#         :returns: A GEM expression for the tangent to each
#            facet (numbered according to FIAT conventions).  These
#            always point from low to high numbered local vertex, shape
#            (nfacet, gdim).
#         """
# 
#     @abstractmethod
#     def physical_edge_lengths(self):
#         """The length of each edge of the physical cell.
# 
#         :returns: A GEM expression for the length of each
#            edge (numbered according to FIAT conventions), shape
#            (nfacet, ).
#         """
# 
#     @abstractmethod
#     def physical_points(self, point_set, entity=None):
#         """Maps reference element points to GEM for the physical coordinates
# 
#         :arg point_set: A point_set on the reference cell to push forward to physical space.
#         :arg entity: Reference cell entity on which the point set is
#                      defined (for example if it is a point set on a facet).
#         :returns: a GEM expression for the physical locations of the
#                   points, shape (gdim, ) with free indices of the point_set.
#         """
# 
#     @abstractmethod
#     def physical_vertices(self):
#         """Physical locations of the cell vertices.
# 
#         :returns: a GEM expression for the physical vertices, shape
#                 (gdim, )."""


import pytest
import FIAT
import finat
import gem
import numpy as np
from finat.physically_mapped import PhysicalGeometry
        prefs = ps.points
        pvs = self.verts
        pps = np.zeros(prefs.shape, dtype=float)
        for i in range(pps.shape[0]):
            pps[i, :] = (pvs[0, :] * (1-prefs[i, 0]) * (1-prefs[i, 1])
                         + pvs[1, :] * (1-prefs[i, 0]) * prefs[i, 1]
                         + pvs[2, :] * prefs[i, 0] * (1-prefs[i, 1])
                         + pvs[3, :] * prefs[i, 0] * prefs[i, 1])
        return gem.Literal(pps)

    def physical_vertices(self):
        return gem.Literal(self.verts)


def get_pts(cell, deg):
    assert cell.shape == FIAT.reference_element.QUADRILATERAL
    L = cell.construct_subelement(1)
    vs = np.asarray(cell.vertices)
    pts = [pt for pt in cell.vertices]
    Lpts = FIAT.reference_element.make_lattice(L.vertices, deg, 1)
    for e in cell.topology[1]:
        Fmap = cell.get_entity_transform(1, e)
        epts = [tuple(Fmap(pt)) for pt in Lpts]
        pts.extend(epts)
    if deg > 3:
        dx0 = (vs[1, :] - vs[0, :]) / (deg-2)
        dx1 = (vs[2, :] - vs[0, :]) / (deg-2)

        internal_nodes = [tuple(vs[0, :] + dx0 * i + dx1 * j)
                          for i in range(1, deg-2)

# Path: finat/physically_mapped.py
# class PhysicalGeometry(metaclass=ABCMeta):
# 
#     @abstractmethod
#     def cell_size(self):
#         """The cell size at each vertex.
# 
#         :returns: A GEM expression for the cell size, shape (nvertex, ).
#         """
# 
#     @abstractmethod
#     def jacobian_at(self, point):
#         """The jacobian of the physical coordinates at a point.
# 
#         :arg point: The point in reference space (on the cell) to
#              evaluate the Jacobian.
#         :returns: A GEM expression for the Jacobian, shape (gdim, tdim).
#         """
# 
#     @abstractmethod
#     def detJ_at(self, point):
#         """The determinant of the jacobian of the physical coordinates at a point.
# 
#         :arg point: The point in reference space to evaluate the Jacobian determinant.
#         :returns: A GEM expression for the Jacobian determinant.
#         """
# 
#     @abstractmethod
#     def reference_normals(self):
#         """The (unit) reference cell normals for each facet.
# 
#         :returns: A GEM expression for the normal to each
#            facet (numbered according to FIAT conventions), shape
#            (nfacet, tdim).
#         """
# 
#     @abstractmethod
#     def physical_normals(self):
#         """The (unit) physical cell normals for each facet.
# 
#         :returns: A GEM expression for the normal to each
#            facet (numbered according to FIAT conventions).  These are
#            all computed by a clockwise rotation of the physical
#            tangents, shape (nfacet, gdim).
#         """
# 
#     @abstractmethod
#     def physical_tangents(self):
#         """The (unit) physical cell tangents on each facet.
# 
#         :returns: A GEM expression for the tangent to each
#            facet (numbered according to FIAT conventions).  These
#            always point from low to high numbered local vertex, shape
#            (nfacet, gdim).
#         """
# 
#     @abstractmethod
#     def physical_edge_lengths(self):
#         """The length of each edge of the physical cell.
# 
#         :returns: A GEM expression for the length of each
#            edge (numbered according to FIAT conventions), shape
#            (nfacet, ).
#         """
# 
#     @abstractmethod
#     def physical_points(self, point_set, entity=None):
#         """Maps reference element points to GEM for the physical coordinates
# 
#         :arg point_set: A point_set on the reference cell to push forward to physical space.
#         :arg entity: Reference cell entity on which the point set is
#                      defined (for example if it is a point set on a facet).
#         :returns: a GEM expression for the physical locations of the
#                   points, shape (gdim, ) with free indices of the point_set.
#         """
# 
#     @abstractmethod
#     def physical_vertices(self):
#         """Physical locations of the cell vertices.
# 
#         :returns: a GEM expression for the physical vertices, shape
#                 (gdim, )."""


# Path: test/test_direct_serendipity.py
import pytest
import FIAT
import finat
import gem
import numpy as np
from finat.physically_mapped import PhysicalGeometry

        prefs = ps.points
        pvs = self.verts
        pps = np.zeros(prefs.shape, dtype=float)
        for i in range(pps.shape[0]):
            pps[i, :] = (pvs[0, :] * (1-prefs[i, 0]) * (1-prefs[i, 1])
                         + pvs[1, :] * (1-prefs[i, 0]) * prefs[i, 1]
                         + pvs[2, :] * prefs[i, 0] * (1-prefs[i, 1])
                         + pvs[3, :] * prefs[i, 0] * prefs[i, 1])
        return gem.Literal(pps)

    def physical_vertices(self):
        return gem.Literal(self.verts)


def get_pts(cell, deg):
    assert cell.shape == FIAT.reference_element.QUADRILATERAL
    L = cell.construct_subelement(1)
    vs = np.asarray(cell.vertices)
    pts = [pt for pt in cell.vertices]
    Lpts = FIAT.reference_element.make_lattice(L.vertices, deg, 1)
    for e in cell.topology[1]:
        Fmap = cell.get_entity_transform(1, e)
        epts = [tuple(Fmap(pt)) for pt in Lpts]
        pts.extend(epts)
    if deg > 3:
        dx0 = (vs[1, :] - vs[0, :]) / (deg-2)
        dx1 = (vs[2, :] - vs[0, :]) / (deg-2)

        internal_nodes = [tuple(vs[0, :] + dx0 * i + dx1 * j)
                          for i in range(1, deg-2)

                          for j in range(1, deg-1-i)]