[fiat] 01/03: New upstream version 2017.1.0

Johannes Ring johannr-guest at moszumanska.debian.org
Wed May 10 09:41:58 UTC 2017


This is an automated email from the git hooks/post-receive script.

johannr-guest pushed a commit to branch experimental
in repository fiat.

commit 3d0486b36557d4423f4385fe04de4a2691ed58b0
Author: Johannes Ring <johannr at simula.no>
Date:   Wed May 10 11:29:33 2017 +0200

    New upstream version 2017.1.0
---
 ChangeLog                                          |  74 ------
 ChangeLog.rst                                      | 149 ++++++++++++
 FIAT/__init__.py                                   |   4 +-
 FIAT/gauss_legendre.py                             |   3 +-
 FIAT/gauss_lobatto_legendre.py                     |   3 +-
 FIAT/hdiv_trace.py                                 | 262 +++++++++++++++------
 FIAT/reference_element.py                          |   4 +
 MANIFEST.in                                        |   7 +
 README.rst                                         |   2 +-
 doc/sphinx/source/conf.py                          |  19 +-
 doc/sphinx/source/releases.rst                     |   2 +
 doc/sphinx/source/releases/next.rst                |  29 ---
 .../source/releases/{next.rst => v2016.2.0.rst}    |  31 ++-
 doc/sphinx/source/releases/v2017.1.0.rst           |  15 ++
 setup.py                                           |   4 +-
 test/unit/test_hdivtrace.py                        |  36 ++-
 test/unit/test_reference_element.py                |   1 +
 17 files changed, 445 insertions(+), 200 deletions(-)

diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644
index 5397a14..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1,74 +0,0 @@
-2016.2.0 [2016-11-30]
- - Enable Travis CI on GitHub
- - Add Firedrake quadrilateral cell
- - Add tensor product cell
- - Add facet -> cell coordinate transformation
- - Add Bubble element
- - Add discontinuous Taylor element
- - Add broken element and H(div) trace element
- - Add element restrictions onto mesh entities
- - Add tensor product elements (for tensor product cells)
- - Add H(div) and H(curl) element-modifiers for TPEs
- - Add enriched element, i.e. sum of elements (e.g. for building Mini)
- - Add multidimensional taylor elements
- - Add Gauss Lobatto Legendre elements
- - Finding non-vanishing DoFs on a facets
- - Add tensor product quadrature rule
- - Make regression tests working again after few years
- - Prune modules having only __main__ code including transform_morley,
-	transform_hermite (ff86250820e2b18f7a0df471c97afa87207e9a7d)
- - Remove newdubiner module (b3b120d40748961fdd0727a4e6c62450198d9647,
-	reference removed by cb65a84ac639977b7be04962cc1351481ca66124)
- - Switch from homebrew factorial/gamma to math module (wraps C std lib)
-2016.1.0 [2016-06-23]
- - Minor fixes
-1.6.0 [2015-07-28]
- - Support DG on facets through the element "Discontinuous Lagrange Trace"
-1.5.0 [2015-01-12]
- - Require Python 2.7
- - Python 3 support
- - Remove ScientificPython dependency and add dependency on SymPy
-1.4.0 [2014-06-02]
- - Support discontinuous/broken Raviart-Thomas
-1.3.0 [2014-01-07]
- - Version bump.
-1.1.0 [2013-01-07]
- - Support second kind Nedelecs on tetrahedra over degree >= 2
- - Support Brezzi-Douglas-Fortin-Marini elements (of degree 1, 2), again
-1.0.0 [2011-12-07]
- - No changes since 1.0-beta, only updating the version number
-1.0-beta [2011-08-11]
- - Change of license to LGPL v3+
- - Minor fixes
-0.9.9 [2011-02-23]
- - Add __version__
- - Add second kind Nedeles on triangles
-0.9.2 [2010-07-01]
- - Bug fix for 1D quadrature
-0.9.1 [2010-02-03]
- - Cleanups and small fixes
-0.9.0 [2010-02-01]
- - New improved interface with support for arbitrary reference elements
-0.3.5
-0.3.4
-0.3.3
- - Bug fix in Nedelec
- - Support for ufc element
-0.3.1
- - Bug fix in DOF orderings for H(div) elements
- - Preliminary type system for DOF
- - Allow user to change ordering of reference dof
- - Brezzi-Douglas-Fortin-Marini elements working
-0.3.0
- - Small changes to H(div) elements preparing for integration with FFC
- - Switch to numpy
- - Added primitive testing harness in fiat/testing
-0.2.4
- - Fixed but in P0.py
-0.2.3
- - Updated topology/ geometry so to allow different orderings of entities
-0.2.2
- - Added Raviart-Thomas element, verified RT0 against old version of code
- - Started work on BDFM, Nedelec (not working)
- - Fixed projection, union of sets (error in SVD usage)
- - Vector-valued spaces have general number of components
diff --git a/ChangeLog.rst b/ChangeLog.rst
new file mode 100644
index 0000000..7cdd1e3
--- /dev/null
+++ b/ChangeLog.rst
@@ -0,0 +1,149 @@
+Changelog
+=========
+
+2017.1.0 (2017-05-09)
+---------------------
+
+- Extended the discontinuous trace element ``HDivTrace`` to support tensor
+  product reference cells. Tabulating the trace defined on a tensor product
+  cell relies on the argument ``entity`` to specify a facet of the cell. The
+  backwards compatibility case ``entity=None`` does not support tensor product
+  tabulation as a result. Tabulating the trace of triangles or tetrahedron
+  remains unaffected and works as usual with or without an entity argument.
+
+2016.2.0 (2016-11-30)
+---------------------
+
+- Enable Travis CI on GitHub
+- Add Firedrake quadrilateral cell
+- Add tensor product cell
+- Add facet -> cell coordinate transformation
+- Add Bubble element
+- Add discontinuous Taylor element
+- Add broken element and H(div) trace element
+- Add element restrictions onto mesh entities
+- Add tensor product elements (for tensor product cells)
+- Add H(div) and H(curl) element-modifiers for TPEs
+- Add enriched element, i.e. sum of elements (e.g. for building Mini)
+- Add multidimensional taylor elements
+- Add Gauss Lobatto Legendre elements
+- Finding non-vanishing DoFs on a facets
+- Add tensor product quadrature rule
+- Make regression tests working again after few years
+- Prune modules having only ``__main__`` code including
+  transform_morley, transform_hermite
+  (ff86250820e2b18f7a0df471c97afa87207e9a7d)
+- Remove newdubiner module (b3b120d40748961fdd0727a4e6c62450198d9647,
+  reference removed by cb65a84ac639977b7be04962cc1351481ca66124)
+- Switch from homebrew factorial/gamma to math module (wraps C std lib)
+
+2016.1.0 (2016-06-23)
+---------------------
+
+- Minor fixes
+
+1.6.0 (2015-07-28)
+------------------
+
+- Support DG on facets through the element "Discontinuous Lagrange
+  Trace"
+
+1.5.0 (2015-01-12)
+------------------
+
+- Require Python 2.7
+- Python 3 support
+- Remove ScientificPython dependency and add dependency on SymPy
+
+1.4.0 (2014-06-02)
+------------------
+
+- Support discontinuous/broken Raviart-Thomas
+
+1.3.0 (2014-01-07)
+------------------
+
+- Version bump.
+
+1.1.0 (2013-01-07)
+------------------
+
+- Support second kind Nedelecs on tetrahedra over degree >= 2
+- Support Brezzi-Douglas-Fortin-Marini elements (of degree 1, 2), again
+
+1.0.0 (2011-12-07)
+------------------
+
+- No changes since 1.0-beta, only updating the version number
+
+1.0-beta (2011-08-11)
+---------------------
+
+- Change of license to LGPL v3+
+- Minor fixes
+
+0.9.9 (2011-02-23)
+------------------
+
+- Add ``__version__``
+- Add second kind Nedeles on triangles
+
+0.9.2 (2010-07-01)
+------------------
+
+- Bug fix for 1D quadrature
+
+0.9.1 (2010-02-03)
+------------------
+
+- Cleanups and small fixes
+
+0.9.0 (2010-02-01)
+------------------
+
+- New improved interface with support for arbitrary reference elements
+
+0.3.5
+-----
+
+0.3.4
+-----
+
+0.3.3
+-----
+
+- Bug fix in Nedelec
+- Support for ufc element
+
+0.3.1
+-----
+
+- Bug fix in DOF orderings for H(div) elements
+- Preliminary type system for DOF
+- Allow user to change ordering of reference dof
+- Brezzi-Douglas-Fortin-Marini elements working
+
+0.3.0
+-----
+
+- Small changes to H(div) elements preparing for integration with FFC
+- Switch to numpy
+- Added primitive testing harness in fiat/testing
+
+0.2.4
+-----
+
+- Fixed but in P0.py
+
+0.2.3
+-----
+
+- Updated topology/ geometry so to allow different orderings of entities
+
+0.2.2
+-----
+
+- Added Raviart-Thomas element, verified RT0 against old version of code
+- Started work on BDFM, Nedelec (not working)
+- Fixed projection, union of sets (error in SVD usage)
+- Vector-valued spaces have general number of components
diff --git a/FIAT/__init__.py b/FIAT/__init__.py
index b21ce41..7c9324d 100644
--- a/FIAT/__init__.py
+++ b/FIAT/__init__.py
@@ -4,6 +4,8 @@ Simplices in one, two, and three dimensions are supported."""
 
 from __future__ import absolute_import, print_function, division
 
+import pkg_resources
+
 # Import finite element classes
 from FIAT.finite_element import FiniteElement, CiarletElement  # noqa: F401
 from FIAT.argyris import Argyris
@@ -39,7 +41,7 @@ from FIAT.quadrature_schemes import create_quadrature     # noqa: F401
 from FIAT.reference_element import ufc_cell, ufc_simplex  # noqa: F401
 from FIAT.hdivcurl import Hdiv, Hcurl                     # noqa: F401
 
-__version__ = "2016.2.0"
+__version__ = pkg_resources.get_distribution("FIAT").version
 
 # List of supported elements and mapping to element classes
 supported_elements = {"Argyris": Argyris,
diff --git a/FIAT/gauss_legendre.py b/FIAT/gauss_legendre.py
index d407ba7..ae0272a 100644
--- a/FIAT/gauss_legendre.py
+++ b/FIAT/gauss_legendre.py
@@ -41,4 +41,5 @@ class GaussLegendre(finite_element.CiarletElement):
             raise ValueError("Gauss-Legendre elements are only defined in one dimension.")
         poly_set = polynomial_set.ONPolynomialSet(ref_el, degree)
         dual = GaussLegendreDualSet(ref_el, degree)
-        super(GaussLegendre, self).__init__(poly_set, dual, degree)
+        formdegree = ref_el.get_spatial_dimension()  # n-form
+        super(GaussLegendre, self).__init__(poly_set, dual, degree, formdegree)
diff --git a/FIAT/gauss_lobatto_legendre.py b/FIAT/gauss_lobatto_legendre.py
index 488d1c3..ecbe015 100644
--- a/FIAT/gauss_lobatto_legendre.py
+++ b/FIAT/gauss_lobatto_legendre.py
@@ -42,4 +42,5 @@ class GaussLobattoLegendre(finite_element.CiarletElement):
             raise ValueError("Gauss-Lobatto-Legendre elements are only defined in one dimension.")
         poly_set = polynomial_set.ONPolynomialSet(ref_el, degree)
         dual = GaussLobattoLegendreDualSet(ref_el, degree)
-        super(GaussLobattoLegendre, self).__init__(poly_set, dual, degree)
+        formdegree = 0  # 0-form
+        super(GaussLobattoLegendre, self).__init__(poly_set, dual, degree, formdegree)
diff --git a/FIAT/hdiv_trace.py b/FIAT/hdiv_trace.py
index 3cd143a..4e40019 100644
--- a/FIAT/hdiv_trace.py
+++ b/FIAT/hdiv_trace.py
@@ -16,14 +16,20 @@
 # along with FIAT. If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import absolute_import, print_function, division
+from six import iteritems, itervalues
+from six.moves import range
 
 import numpy as np
 from FIAT.discontinuous_lagrange import DiscontinuousLagrange
-from FIAT.reference_element import ufc_simplex
+from FIAT.dual_set import DualSet
+from FIAT.finite_element import FiniteElement
 from FIAT.functional import PointEvaluation
 from FIAT.polynomial_set import mis
-from FIAT import FiniteElement
-from FIAT import dual_set
+from FIAT.reference_element import (ufc_simplex, POINT,
+                                    LINE, QUADRILATERAL,
+                                    TRIANGLE, TETRAHEDRON,
+                                    TENSORPRODUCT)
+from FIAT.tensor_product import TensorProductElement
 
 # Numerical tolerance for facet-entity identifications
 epsilon = 1e-10
@@ -49,47 +55,89 @@ class HDivTrace(FiniteElement):
     """
 
     def __init__(self, ref_el, degree):
+        """Constructor for the HDivTrace element.
+
+        :arg ref_el: A reference element, which may be a tensor product
+                     cell.
+        :arg degree: The degree of approximation. If on a tensor product
+                     cell, then provide a tuple of degrees if you want
+                     varying degrees.
+        """
         sd = ref_el.get_spatial_dimension()
         if sd in (0, 1):
-            raise ValueError("Cannot use this trace class on a %d-dimensional cell." % sd)
-
-        # Constructing facet element as a discontinuous Lagrange element
-        dglagrange = DiscontinuousLagrange(ufc_simplex(sd - 1), degree)
-
-        # Construct entity ids (assigning top. dim. and initializing as empty)
+            raise ValueError("Cannot take the trace of a %d-dim cell." % sd)
+
+        # Store the degrees if on a tensor product cell
+        if ref_el.get_shape() == TENSORPRODUCT:
+            try:
+                degree = tuple(degree)
+            except TypeError:
+                degree = (degree,) * len(ref_el.cells)
+
+            assert len(ref_el.cells) == len(degree), (
+                "Number of specified degrees must be equal to the number of cells."
+            )
+        else:
+            if ref_el.get_shape() not in [TRIANGLE, TETRAHEDRON, QUADRILATERAL]:
+                raise NotImplementedError(
+                    "Trace element on a %s not implemented" % type(ref_el)
+                )
+            # Cannot have varying degrees for these reference cells
+            if isinstance(degree, tuple):
+                raise ValueError("Must have a tensor product cell if providing multiple degrees")
+
+        # Initialize entity dofs and construct the DG elements
+        # for the facets
+        facet_sd = sd - 1
+        dg_elements = {}
         entity_dofs = {}
-
-        # Looping over dictionary of cell topology to construct the empty
-        # dictionary for entity ids of the trace element
         topology = ref_el.get_topology()
-        for top_dim, entities in topology.items():
+        for top_dim, entities in iteritems(topology):
+            cell = ref_el.construct_subelement(top_dim)
             entity_dofs[top_dim] = {}
+
+            # We have a facet entity!
+            if cell.get_spatial_dimension() == facet_sd:
+                dg_elements[top_dim] = construct_dg_element(cell, degree)
+            # Initialize
             for entity in entities:
                 entity_dofs[top_dim][entity] = []
 
-        # Filling in entity ids and generating points for dual basis
-        nf = dglagrange.space_dimension()
-        points = []
-        num_facets = sd + 1
-        for f in range(num_facets):
-            entity_dofs[sd - 1][f] = range(f * nf, (f + 1) * nf)
-
-            for dof in dglagrange.dual_basis():
-                facet_point = list(dof.get_point_dict().keys())[0]
-                transform = ref_el.get_entity_transform(sd - 1, f)
-                points.append(tuple(transform(facet_point)))
+        # Compute the dof numbering for all facet entities
+        # and extract nodes
+        offset = 0
+        pts = []
+        for facet_dim in sorted(dg_elements):
+            element = dg_elements[facet_dim]
+            nf = element.space_dimension()
+            num_facets = len(topology[facet_dim])
+
+            for i in range(num_facets):
+                entity_dofs[facet_dim][i] = list(range(offset, offset + nf))
+                offset += nf
+
+                # Run over nodes and collect the points for point evaluations
+                for dof in element.dual_basis():
+                    facet_pt, = dof.get_point_dict()
+                    transform = ref_el.get_entity_transform(facet_dim, i)
+                    pts.append(tuple(transform(facet_pt)))
 
         # Setting up dual basis - only point evaluations
-        nodes = [PointEvaluation(ref_el, pt) for pt in points]
-        dual = dual_set.DualSet(nodes, ref_el, entity_dofs)
+        nodes = [PointEvaluation(ref_el, pt) for pt in pts]
+        dual = DualSet(nodes, ref_el, entity_dofs)
+
+        # Degree of the element
+        deg = max([e.degree() for e in dg_elements.values()])
 
-        super(HDivTrace, self).__init__(ref_el, dual, dglagrange.get_order(),
-                                        dglagrange.get_formdegree(), dglagrange.mapping()[0])
-        # Set up facet element
-        self.facet_element = dglagrange
+        super(HDivTrace, self).__init__(ref_el, dual, order=deg,
+                                        formdegree=facet_sd,
+                                        mapping="affine")
 
-        # degree for quadrature rule
-        self.polydegree = degree
+        # Set up facet elements
+        self.dg_elements = dg_elements
+
+        # Degree for quadrature rule
+        self.polydegree = deg
 
     def degree(self):
         """Return the degree of the (embedding) polynomial space."""
@@ -116,64 +164,107 @@ class HDivTrace(FiniteElement):
                      reference element to tabulate on.  If ``None``,
                      tabulated values are computed by geometrically
                      approximating which facet the points are on.
+
+        .. note ::
+
+           Performing illegal tabulations on this element will result in either
+           a tabulation table of `numpy.nan` arrays (`entity=None` case), or
+           insertions of the `TraceError` exception class. This is due to the
+           fact that performing cell-wise tabulations, or asking for any order
+           of derivative evaluations, are not mathematically well-defined.
         """
-        facet_dim = self.ref_el.get_spatial_dimension() - 1
-        sdim = self.space_dimension()
-        nf = self.facet_element.space_dimension()
+        sd = self.ref_el.get_spatial_dimension()
+        facet_sd = sd - 1
 
         # Initializing dictionary with zeros
         phivals = {}
         for i in range(order + 1):
-            alphas = mis(self.ref_el.get_spatial_dimension(), i)
+            alphas = mis(sd, i)
             for alpha in alphas:
-                phivals[alpha] = np.zeros(shape=(sdim, len(points)))
-        evalkey = (0,) * (facet_dim + 1)
+                phivals[alpha] = np.zeros(shape=(self.space_dimension(), len(points)))
+
+        evalkey = (0,) * sd
 
         # If entity is None, identify facet using numerical tolerance and
         # return the tabulated values
         if entity is None:
+            # NOTE: Numerical approximation of the facet id is currently only
+            # implemented for simplex reference cells.
+            if self.ref_el.get_shape() not in [TRIANGLE, TETRAHEDRON]:
+                raise NotImplementedError(
+                    "Tabulating this element on a %s cell without providing "
+                    "an entity is not currently supported." % type(self.ref_el)
+                )
+
             # Attempt to identify which facet (if any) the given points are on
             vertices = self.ref_el.vertices
             coordinates = barycentric_coordinates(points, vertices)
-            (unique_facet, success) = extract_unique_facet(coordinates)
+            unique_facet, success = extract_unique_facet(coordinates)
 
-            # If we are not successful in finding a unique facet, raise an exception
+            # If not successful, return NaNs
             if not success:
-                raise TraceError("Could not find a unique facet to tabulate on.")
-
-            # Map points to the reference facet
-            new_points = map_to_reference_facet(points, vertices, unique_facet)
+                for key in phivals:
+                    phivals[key] = np.full(shape=(sd, len(points)), fill_value=np.nan)
 
-            # Retrieve values by tabulating the DiscontinuousLagrange element
-            nonzerovals = list(self.facet_element.tabulate(order, new_points).values())[0]
-            phivals[evalkey][nf*unique_facet:nf*(unique_facet + 1), :] = nonzerovals
+                return phivals
 
-            return phivals
+            # Otherwise, extract non-zero values and insertion indices
+            else:
+                # Map points to the reference facet
+                new_points = map_to_reference_facet(points, vertices, unique_facet)
 
-        entity_dim, entity_id = entity
-
-        # If the user is directly specifying cell-wise tabulation, return TraceErrors in dict for
-        # appropriate handling in the form compiler
-        if entity_dim != facet_dim:
-            for key in phivals.keys():
-                phivals[key] = TraceError("Attempting to tabulate a %d-entity. Expecting a %d-entitiy" % (entity_dim, facet_dim))
-            return phivals
+                # Retrieve values by tabulating the DG element
+                element = self.dg_elements[facet_sd]
+                nf = element.space_dimension()
+                nonzerovals, = itervalues(element.tabulate(order, new_points))
+                indices = slice(nf * unique_facet, nf * (unique_facet + 1))
 
         else:
-            # Retrieve function evaluations (order = 0 case)
-            nonzerovals = list(self.facet_element.tabulate(0, points).values())[0]
-            phivals[evalkey][nf*entity_id:nf*(entity_id + 1), :] = nonzerovals
-
-            # If asking for gradient evaluations, insert TraceError in gradient evaluations
-            if order > 0:
-                for key in phivals.keys():
-                    if key != evalkey:
-                        phivals[key] = TraceError("Gradient evaluations are illegal on trace elements.")
-            return phivals
+            entity_dim, _ = entity
+
+            # If the user is directly specifying cell-wise tabulation, return
+            # TraceErrors in dict for appropriate handling in the form compiler
+            if entity_dim not in self.dg_elements:
+                for key in phivals:
+                    msg = "The HDivTrace element can only be tabulated on facets."
+                    phivals[key] = TraceError(msg)
+
+                return phivals
+
+            else:
+                # Retrieve function evaluations (order = 0 case)
+                offset = 0
+                for facet_dim in sorted(self.dg_elements):
+                    element = self.dg_elements[facet_dim]
+                    nf = element.space_dimension()
+                    num_facets = len(self.ref_el.get_topology()[facet_dim])
+
+                    # Loop over the number of facets until we find a facet
+                    # with matching dimension and id
+                    for i in range(num_facets):
+                        # Found it! Grab insertion indices
+                        if (facet_dim, i) == entity:
+                            nonzerovals, = itervalues(element.tabulate(0, points))
+                            indices = slice(offset, offset + nf)
+
+                        offset += nf
+
+        # If asking for gradient evaluations, insert TraceError in
+        # gradient slots
+        if order > 0:
+            msg = "Gradients on trace elements are not well-defined."
+            for key in phivals:
+                if key != evalkey:
+                    phivals[key] = TraceError(msg)
+
+        # Insert non-zero values in appropriate place
+        phivals[evalkey][indices, :] = nonzerovals
+
+        return phivals
 
     def value_shape(self):
         """Return the value shape of the finite element functions."""
-        return self.facet_element.value_shape()
+        return ()
 
     def dmats(self):
         """Return dmats: expansion coefficients for basis function
@@ -185,6 +276,43 @@ class HDivTrace(FiniteElement):
         raise NotImplementedError("get_num_members not implemented for the trace element.")
 
 
+def construct_dg_element(ref_el, degree):
+    """Constructs a discontinuous galerkin element of a given degree
+    on a particular reference cell.
+    """
+    if ref_el.get_shape() in [LINE, TRIANGLE]:
+        dg_element = DiscontinuousLagrange(ref_el, degree)
+
+    # Quadrilateral facets could be on a FiredrakeQuadrilateral.
+    # In this case, we treat this as an interval x interval cell:
+    elif ref_el.get_shape() == QUADRILATERAL:
+        dg_a = DiscontinuousLagrange(ufc_simplex(1), degree)
+        dg_b = DiscontinuousLagrange(ufc_simplex(1), degree)
+        dg_element = TensorProductElement(dg_a, dg_b)
+
+    # This handles the more general case for facets:
+    elif ref_el.get_shape() == TENSORPRODUCT:
+        assert len(degree) == len(ref_el.cells), (
+            "Must provide the same number of degrees as the number "
+            "of cells that make up the tensor product cell."
+        )
+        sub_elements = [construct_dg_element(c, d)
+                        for c, d in zip(ref_el.cells, degree)
+                        if c.get_shape() != POINT]
+
+        if len(sub_elements) > 1:
+            dg_element = TensorProductElement(*sub_elements)
+        else:
+            dg_element, = sub_elements
+
+    else:
+        raise NotImplementedError(
+            "Reference cells of type %s not currently supported" % type(ref_el)
+        )
+
+    return dg_element
+
+
 # The following functions are credited to Marie E. Rognes:
 def extract_unique_facet(coordinates, tolerance=epsilon):
     """Determines whether a set of points (described in its barycentric coordinates)
diff --git a/FIAT/reference_element.py b/FIAT/reference_element.py
index 72cd47c..3e042f9 100644
--- a/FIAT/reference_element.py
+++ b/FIAT/reference_element.py
@@ -451,6 +451,10 @@ class Simplex(Cell):
             return lambda point: point
         elif dim == space_dim - 1:  # facet points
             return self.get_facet_transform(entity_i)
+        elif dim == 0:  # vertex point
+            i, = self.get_topology()[dim][entity_i]
+            vertex = self.get_vertices()[i]
+            return lambda point: vertex
         else:
             raise NotImplementedError("Co-dimension >1 not implemented.")
 
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..3e89746
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,7 @@
+include AUTHORS
+include COPYING
+include COPYING.LESSER
+include ChangeLog
+recursive-include doc *
+recursive-include test *
+global-exclude __pycache__ *.pyc
diff --git a/README.rst b/README.rst
index 73e0ec5..6014d29 100644
--- a/README.rst
+++ b/README.rst
@@ -45,7 +45,7 @@ Code Coverage
 -------------
 
 Code coverage reports can be viewed at
-https://coveralls.io/repos/bitbucket/fenics-project/fiat.
+https://coveralls.io/bitbucket/fenics-project/fiat.
 
 .. image:: https://coveralls.io/repos/bitbucket/fenics-project/fiat/badge.svg?branch=master
    :target: https://coveralls.io/bitbucket/fenics-project/fiat?branch=master
diff --git a/doc/sphinx/source/conf.py b/doc/sphinx/source/conf.py
index 1ec1d8d..43cb30d 100644
--- a/doc/sphinx/source/conf.py
+++ b/doc/sphinx/source/conf.py
@@ -15,6 +15,8 @@
 import sys
 import os
 import shlex
+import pkg_resources
+import datetime
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
@@ -52,19 +54,10 @@ master_doc = 'index'
 
 # General information about the project.
 project = u'FInite element Automatic Tabulator (FIAT)'
-copyright = u'2015, FEniCS Project'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-import FIAT
-fiat_version = FIAT.__version__
-
-# The short X.Y version.
-version = fiat_version
-# The full version, including alpha/beta/rc tags.
-release = fiat_version
+this_year = datetime.date.today().year
+copyright = u'%s, FEniCS Project' % this_year
+version = pkg_resources.get_distribution("FIAT").version
+release = version
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/doc/sphinx/source/releases.rst b/doc/sphinx/source/releases.rst
index 796ed29..ee8b507 100644
--- a/doc/sphinx/source/releases.rst
+++ b/doc/sphinx/source/releases.rst
@@ -9,5 +9,7 @@ Release notes
    :maxdepth: 2
 
    releases/next
+   releases/v2017.1.0
+   releases/v2016.2.0
    releases/v2016.1.0
    releases/v1.6.0
diff --git a/doc/sphinx/source/releases/next.rst b/doc/sphinx/source/releases/next.rst
index d6610a7..cdcd4a3 100644
--- a/doc/sphinx/source/releases/next.rst
+++ b/doc/sphinx/source/releases/next.rst
@@ -11,35 +11,6 @@ Summary of changes
           be published (and renamed) to list the most important
           changes in the new release.
 
-- More elegant edge-based degrees of freedom are used for generalized Regge
-  finite elements.  This is a internal change and is not visible to other parts
-  of FEniCS.
-- The name of the mapping for generalized Regge finite element is changed to
-  "double covariant piola" from "pullback as metric". Geometrically, this
-  mapping is just the pullback of covariant 2-tensor fields in terms of proxy
-  matrix-fields. Because the mapping for 1-forms in FEniCS is currently named
-  "covariant piola", this mapping for symmetric tensor product of 1-forms is
-  thus called "double covariant piola". This change causes multiple internal
-  changes downstream in UFL and FFC. But this change should not be visible to
-  the end-user.
-- Added support for the Hellan-Herrmann-Johnson element (symmetric matrix
-  fields with normal-normal continuity in 2D).
-- Add method ``FiniteElement.is_nodal()`` for checking element nodality
-- Add ``NodalEnrichedElement`` which merges dual bases (nodes) of given
-  elements and orthogonalizes basis for nodality
-- Restructuring ``finite_element.py`` with the addition of a non-nodal class
-  ``FiniteElement`` and a nodal class ``CiarletElement``. ``FiniteElement`` is
-  designed to be used to create elements where, in general, a nodal basis isn't
-  well-defined. ``CiarletElement`` implements the usual nodal abstraction of
-  a finite element.
-- Removing ``trace.py`` and ``trace_hdiv.py`` with a new implementation of the
-  trace element of an HDiv-conforming element: ``HDivTrace``. It is also
-  mathematically equivalent to the former ``DiscontinuousLagrangeTrace``, that
-  is, the DG field defined only on co-dimension 1 entities.
-- All nodal finite elements inherit from ``CiarletElement``, and the non-nodal
-  ``TensorProductElement``, ``EnrichedElement`` and ``HDivTrace`` inherit from
-  ``FiniteElement``.
-
 Detailed changes
 ================
 
diff --git a/doc/sphinx/source/releases/next.rst b/doc/sphinx/source/releases/v2016.2.0.rst
similarity index 64%
copy from doc/sphinx/source/releases/next.rst
copy to doc/sphinx/source/releases/v2016.2.0.rst
index d6610a7..5df8558 100644
--- a/doc/sphinx/source/releases/next.rst
+++ b/doc/sphinx/source/releases/v2016.2.0.rst
@@ -1,16 +1,12 @@
 ===========================
-Changes in the next release
+Changes in version 2016.2.0
 ===========================
 
+FIAT 2016.2.0 was released on 2016-11-30.
 
 Summary of changes
 ==================
 
-.. note:: Developers should use this page to track and list changes
-          during development. At the time of release, this page should
-          be published (and renamed) to list the most important
-          changes in the new release.
-
 - More elegant edge-based degrees of freedom are used for generalized Regge
   finite elements.  This is a internal change and is not visible to other parts
   of FEniCS.
@@ -43,5 +39,24 @@ Summary of changes
 Detailed changes
 ================
 
-.. note:: At the time of release, make a verbatim copy of the
-          ChangeLog here (and remove this note).
+- Enable Travis CI on GitHub
+- Add Firedrake quadrilateral cell
+- Add tensor product cell
+- Add facet -> cell coordinate transformation
+- Add Bubble element
+- Add discontinuous Taylor element
+- Add broken element and H(div) trace element
+- Add element restrictions onto mesh entities
+- Add tensor product elements (for tensor product cells)
+- Add H(div) and H(curl) element-modifiers for TPEs
+- Add enriched element, i.e. sum of elements (e.g. for building Mini)
+- Add multidimensional taylor elements
+- Add Gauss Lobatto Legendre elements
+- Finding non-vanishing DoFs on a facets
+- Add tensor product quadrature rule
+- Make regression tests working again after few years
+- Prune modules having only __main__ code including transform_morley,
+  transform_hermite (ff86250820e2b18f7a0df471c97afa87207e9a7d)
+- Remove newdubiner module (b3b120d40748961fdd0727a4e6c62450198d9647,
+  reference removed by cb65a84ac639977b7be04962cc1351481ca66124)
+- Switch from homebrew factorial/gamma to math module (wraps C std lib)
diff --git a/doc/sphinx/source/releases/v2017.1.0.rst b/doc/sphinx/source/releases/v2017.1.0.rst
new file mode 100644
index 0000000..2320b1a
--- /dev/null
+++ b/doc/sphinx/source/releases/v2017.1.0.rst
@@ -0,0 +1,15 @@
+===========================
+Changes in version 2017.1.0
+===========================
+
+FIAT 2017.1.0 was released on 2017-05-09.
+
+Summary of changes
+==================
+
+- Extended the discontinuous trace element ``HDivTrace`` to support tensor
+  product reference cells. Tabulating the trace defined on a tensor product
+  cell relies on the argument ``entity`` to specify a facet of the cell. The
+  backwards compatibility case ``entity=None`` does not support tensor product
+  tabulation as a result. Tabulating the trace of triangles or tetrahedron
+  remains unaffected and works as usual with or without an entity argument.
diff --git a/setup.py b/setup.py
index ab4782e..17999c8 100755
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,6 @@
 
 from __future__ import absolute_import, print_function, division
 
-import re
 import sys
 
 try:
@@ -14,8 +13,7 @@ if sys.version_info < (2, 7):
     print("Python 2.7 or higher required, please upgrade.")
     sys.exit(1)
 
-version = re.findall('__version__ = "(.*)"',
-                     open('FIAT/__init__.py', 'r').read())[0]
+version = "2017.1.0"
 
 url = "https://bitbucket.org/fenics-project/fiat/"
 tarball = None
diff --git a/test/unit/test_hdivtrace.py b/test/unit/test_hdivtrace.py
index cfd96d9..71c8e87 100644
--- a/test/unit/test_hdivtrace.py
+++ b/test/unit/test_hdivtrace.py
@@ -43,7 +43,8 @@ def test_basis_values(dim, degree):
     ref_el = ufc_simplex(dim)
     quadrule = make_quadrature(ufc_simplex(dim - 1), degree + 1)
     fiat_element = HDivTrace(ref_el, degree)
-    nf = fiat_element.facet_element.space_dimension()
+    facet_element = fiat_element.dg_elements[dim - 1]
+    nf = facet_element.space_dimension()
 
     for facet_id in range(dim + 1):
         # Tabulate without an entity pair given --- need to map to cell coordinates
@@ -58,7 +59,7 @@ def test_basis_values(dim, degree):
 
         for test_degree in range(degree + 1):
             coeffs = [n(lambda x: x[0]**test_degree)
-                      for n in fiat_element.facet_element.dual.nodes]
+                      for n in facet_element.dual.nodes]
 
             cintegral = np.dot(coeffs, np.dot(ctab, quadrule.wts))
             eintegral = np.dot(coeffs, np.dot(etab, quadrule.wts))
@@ -70,6 +71,37 @@ def test_basis_values(dim, degree):
             assert np.allclose(eintegral, reference, rtol=1e-14)
 
 
+ at pytest.mark.parametrize("degree", range(4))
+def test_quad_trace(degree):
+    """Test the trace element defined on a quadrilateral cell"""
+    from FIAT import ufc_simplex, HDivTrace, make_quadrature
+    from FIAT.reference_element import TensorProductCell
+
+    tpc = TensorProductCell(ufc_simplex(1), ufc_simplex(1))
+    fiat_element = HDivTrace(tpc, (degree, degree))
+    facet_elements = fiat_element.dg_elements
+    quadrule = make_quadrature(ufc_simplex(1), degree + 1)
+
+    for i, entity in enumerate([((0, 1), 0), ((0, 1), 1),
+                                ((1, 0), 0), ((1, 0), 1)]):
+        entity_dim, _ = entity
+        element = facet_elements[entity_dim]
+        nf = element.space_dimension()
+
+        tab = fiat_element.tabulate(0, quadrule.pts,
+                                    entity)[(0, 0)][nf*i:nf*(i+1)]
+
+        for test_degree in range(degree + 1):
+            coeffs = [n(lambda x: x[0]**test_degree)
+                      for n in element.dual.nodes]
+
+            integral = np.dot(coeffs, np.dot(tab, quadrule.wts))
+
+            reference = np.dot([x[0]**test_degree
+                                for x in quadrule.pts], quadrule.wts)
+            assert np.allclose(integral, reference, rtol=1e-14)
+
+
 @pytest.mark.parametrize("dim", (2, 3))
 @pytest.mark.parametrize("order", range(1, 4))
 @pytest.mark.parametrize("degree", range(4))
diff --git a/test/unit/test_reference_element.py b/test/unit/test_reference_element.py
index 4034f80..7fb41c7 100644
--- a/test/unit/test_reference_element.py
+++ b/test/unit/test_reference_element.py
@@ -96,6 +96,7 @@ def test_reference_normal_vert(cell, normals):
         assert np.allclose(normals[facet_number],
                            cell.compute_reference_normal(vert_dim, facet_number))
 
+
 if __name__ == '__main__':
     import os
     pytest.main(os.path.abspath(__file__))

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/fenics/fiat.git



More information about the debian-science-commits mailing list