[ufl] 01/06: New upstream version 2017.2.0.0

Drew Parsons dparsons at moszumanska.debian.org
Fri Jan 19 15:28:43 UTC 2018


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

dparsons pushed a commit to tag experimental/2017.2.0.0-1exp1
in repository ufl.

commit 9e54ad23dab17ceea399270288c7309809287928
Author: Drew Parsons <dparsons at debian.org>
Date:   Fri Jan 19 22:58:59 2018 +0800

    New upstream version 2017.2.0.0
---
 ChangeLog.rst                             |  14 ++-
 doc/sphinx/source/releases.rst            |   1 +
 doc/sphinx/source/releases/next.rst       |   1 +
 doc/sphinx/source/releases/v2017.2.0.rst  |   7 +-
 shippable.yml                             |  12 --
 test/test_automatic_differentiation.py    |  12 +-
 test/test_change_to_reference_frame.py    |   2 +-
 test/test_classcoverage.py                |   2 +
 test/test_derivative.py                   |   7 ++
 test/test_piecewise_checks.py             |   2 +
 test/test_signature.py                    |   5 +-
 test/test_str.py                          |   4 +
 ufl/__init__.py                           |   6 +-
 ufl/algorithms/apply_derivatives.py       |   3 +
 ufl/algorithms/apply_geometry_lowering.py | 180 ++++++++++++------------------
 ufl/algorithms/elementtransformations.py  |   3 +
 ufl/algorithms/renumbering.py             |   2 +-
 ufl/algorithms/transformer.py             |   4 +-
 ufl/core/expr.py                          |   2 +-
 ufl/core/terminal.py                      |   2 +-
 ufl/finiteelement/mixedelement.py         |   4 +-
 ufl/formatting/ufl2latex.py               |  16 +--
 ufl/formatting/ufl2unicode.py             |   4 +-
 ufl/geometry.py                           |  89 ++++++++++++++-
 ufl/mathfunctions.py                      |   2 +-
 ufl/objects.py                            |   2 +-
 ufl/operators.py                          |   2 +-
 ufl/tensors.py                            |   8 +-
 ufl/utils/formatting.py                   |   2 +-
 29 files changed, 239 insertions(+), 161 deletions(-)

diff --git a/ChangeLog.rst b/ChangeLog.rst
index bbfa1a9..c2a6704 100644
--- a/ChangeLog.rst
+++ b/ChangeLog.rst
@@ -1,10 +1,20 @@
 Changelog
 =========
 
-2017.2.0 (2017-09-15)
+2017.2.0 (2017-11-30)
 ---------------------
 
-- Testing release method
+- Add geometric quantity ``CellDiameter`` defined as a set diameter
+  of the cell, i.e., maximal distance between any two points of the
+  cell; implemented on simplices and quads/hexes
+- Rename internally used reference quantities
+  ``(Cell|Facet)EdgeVectors`` to ``Reference(Cell|Facet)EdgeVectors``
+- Add internally used quantites ``CellVertices``,
+  ``(Cell|Facet)EdgeVectors`` which are physical-coordinates-valued;
+  will be useful for further geometry lowering implementations
+  for quads/hexes
+- Implement geometry lowering of ``(Min|Max)(Cell|Facet)EdgeLength``
+  for quads and hexes
 
 2017.1.0.post1 (2017-09-12)
 ---------------------------
diff --git a/doc/sphinx/source/releases.rst b/doc/sphinx/source/releases.rst
index 4758874..787e2f2 100644
--- a/doc/sphinx/source/releases.rst
+++ b/doc/sphinx/source/releases.rst
@@ -9,6 +9,7 @@ Release notes
    :maxdepth: 2
 
    releases/next
+   releases/v2017.2.0
    releases/v2017.1.0.post1
    releases/v2017.1.0
    releases/v2016.2.0
diff --git a/doc/sphinx/source/releases/next.rst b/doc/sphinx/source/releases/next.rst
index cdcd4a3..1bfdf0e 100644
--- a/doc/sphinx/source/releases/next.rst
+++ b/doc/sphinx/source/releases/next.rst
@@ -11,6 +11,7 @@ Summary of changes
           be published (and renamed) to list the most important
           changes in the new release.
 
+
 Detailed changes
 ================
 
diff --git a/doc/sphinx/source/releases/v2017.2.0.rst b/doc/sphinx/source/releases/v2017.2.0.rst
index ea1fb3f..462d022 100644
--- a/doc/sphinx/source/releases/v2017.2.0.rst
+++ b/doc/sphinx/source/releases/v2017.2.0.rst
@@ -2,7 +2,12 @@
 Changes in version 2017.2.0
 ===========================
 
-UFL 2017.2.0 was released on 2017-09-15.
+UFL 2017.2.0 was released on 2017-11-30.
 
 Summary of changes
 ==================
+
+- Add ``CellDiameter`` expression giving diameter of a cell, i.e.,
+  maximal distance between any two points of the cell. Implemented
+  for all simplices and quads/hexes.
+- Make ``(Min|Max)(Cell|Facet)EdgeLength`` working for quads/hexes
diff --git a/shippable.yml b/shippable.yml
deleted file mode 100644
index ab12e61..0000000
--- a/shippable.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-language: python
-python:
-  - 2.7
-  - 3.6
-
-build:
-  ci:
-  - pip install --upgrade pip
-  - pip install flake8 pytest
-  - pip install .
-  - python -m flake8 ufl/
-  - python -m pytest -v test/
diff --git a/test/test_automatic_differentiation.py b/test/test_automatic_differentiation.py
index 0b326c1..6d6b3ee 100755
--- a/test/test_automatic_differentiation.py
+++ b/test/test_automatic_differentiation.py
@@ -32,9 +32,17 @@ class ExpressionCollection(object):
         x = SpatialCoordinate(cell)
         n = FacetNormal(cell)
         c = CellVolume(cell)
-        h = Circumradius(cell)
+        R = Circumradius(cell)
+        h = CellDiameter(cell)
         f = FacetArea(cell)
         # s = CellSurfaceArea(cell)
+        mince = MinCellEdgeLength(cell)
+        maxce = MaxCellEdgeLength(cell)
+        minfe = MinFacetEdgeLength(cell)
+        maxfe = MaxFacetEdgeLength(cell)
+        J = Jacobian(cell)
+        detJ = JacobianDeterminant(cell)
+        invJ = JacobianInverse(cell)
         # FIXME: Add all new geometry types here!
 
         I = Identity(d)
@@ -58,7 +66,7 @@ class ExpressionCollection(object):
             setattr(self.shared_objects, key, value)
 
         self.literals = list(map(as_ufl, [0, 1, 3.14, I, eps]))
-        self.geometry = [x, n, c, h, f]
+        self.geometry = [x, n, c, R, h, f, mince, maxce, minfe, maxfe, J, detJ, invJ]
         self.functions = [u, du, v, dv, w, dw]
 
         self.terminals = []
diff --git a/test/test_change_to_reference_frame.py b/test/test_change_to_reference_frame.py
index 64d4cd5..bfae470 100755
--- a/test/test_change_to_reference_frame.py
+++ b/test/test_change_to_reference_frame.py
@@ -25,7 +25,7 @@ from ufl.classes import (Expr, FormArgument, GeometricQuantity,
                          Jacobian, JacobianInverse, JacobianDeterminant,
                          FacetJacobian, FacetJacobianInverse, FacetJacobianDeterminant,
                          CellFacetJacobian,
-                         CellEdgeVectors, FacetEdgeVectors,
+                         ReferenceCellEdgeVectors, ReferenceFacetEdgeVectors,
                          FacetNormal, CellNormal, ReferenceNormal,
                          CellVolume, FacetArea,
                          CellOrientation, FacetOrientation, QuadratureWeight,
diff --git a/test/test_classcoverage.py b/test/test_classcoverage.py
index f4c4779..3a25afe 100755
--- a/test/test_classcoverage.py
+++ b/test/test_classcoverage.py
@@ -193,6 +193,8 @@ def testAll(self):
 
     g = CellVolume(cell)
     _test_object(g, (), ())
+    g = CellDiameter(cell)
+    _test_object(g, (), ())
     g = Circumradius(cell)
     _test_object(g, (), ())
     # g = CellSurfaceArea(cell)
diff --git a/test/test_derivative.py b/test/test_derivative.py
index 45e7a40..52f0e93 100755
--- a/test/test_derivative.py
+++ b/test/test_derivative.py
@@ -155,6 +155,13 @@ def testFacetArea(self):
     _test(self, f, df)
 
 
+def testCellDiameter(self):
+    def f(w): return CellDiameter(triangle)
+
+    def df(w, v): return zero()
+    _test(self, f, df)
+
+
 def testCircumradius(self):
     def f(w): return Circumradius(triangle)
 
diff --git a/test/test_piecewise_checks.py b/test/test_piecewise_checks.py
index 76fe2e2..1db8ec6 100755
--- a/test/test_piecewise_checks.py
+++ b/test/test_piecewise_checks.py
@@ -139,6 +139,8 @@ def test_always_cellwise_constant_geometric_quantities(domains):
     "Test geometric quantities that are always constant over a cell."
     e = CellVolume(domains)
     assert is_cellwise_constant(e)
+    e = CellDiameter(domains)
+    assert is_cellwise_constant(e)
     e = Circumradius(domains)
     assert is_cellwise_constant(e)
     e = FacetArea(domains)
diff --git a/test/test_signature.py b/test/test_signature.py
index 2f8c0b0..840a956 100755
--- a/test/test_signature.py
+++ b/test/test_signature.py
@@ -111,6 +111,7 @@ def test_terminal_hashdata_depends_on_geometry(self):
             d = cell.geometric_dimension()
             x = SpatialCoordinate(cell)
             n = FacetNormal(cell)
+            h = CellDiameter(cell)
             r = Circumradius(cell)
             a = FacetArea(cell)
             # s = CellSurfaceArea(cell)
@@ -118,7 +119,7 @@ def test_terminal_hashdata_depends_on_geometry(self):
             I = Identity(d)
 
             ws = (x, n)
-            qs = (r, a, v)  # , s)
+            qs = (h, r, a, v)  # , s)
             for w in ws:
                 for q in qs:
                     expr = (I[0, j]*(q*w[j]))
@@ -128,7 +129,7 @@ def test_terminal_hashdata_depends_on_geometry(self):
                     yield compute_terminal_hashdata(expr, domain_numbering(*cells))
 
     c, d, r, h = compute_unique_terminal_hashdatas(forms())
-    assert c == 2*3*2  # len(ws)*len(qs)*len(cells)
+    assert c == 2*4*2  # len(ws)*len(qs)*len(cells)
     assert d == c
     assert r == c
     assert h == c
diff --git a/test/test_str.py b/test/test_str.py
index f9a7c34..f5021a0 100755
--- a/test/test_str.py
+++ b/test/test_str.py
@@ -38,6 +38,10 @@ def test_str_circumradius(self):
     assert str(Circumradius(triangle)) == "circumradius"
 
 
+def test_str_diameter(self):
+    assert str(CellDiameter(triangle)) == "diameter"
+
+
 # def test_str_cellsurfacearea(self):
 #     assert str(CellSurfaceArea(triangle)) == "surfacearea"
 
diff --git a/ufl/__init__.py b/ufl/__init__.py
index b043db5..b09fdee 100644
--- a/ufl/__init__.py
+++ b/ufl/__init__.py
@@ -120,6 +120,7 @@ A very brief overview of the language contents follows:
     - FacetNormal
     - CellNormal
     - CellVolume
+    - CellDiameter
     - Circumradius
     - MinCellEdgeLength
     - MaxCellEdgeLength
@@ -267,7 +268,7 @@ from ufl.domain import as_domain, AbstractDomain, Mesh, MeshView, TensorProductM
 from ufl.geometry import (
     SpatialCoordinate,
     FacetNormal, CellNormal,
-    CellVolume, Circumradius, MinCellEdgeLength, MaxCellEdgeLength,
+    CellVolume, CellDiameter, Circumradius, MinCellEdgeLength, MaxCellEdgeLength,
     FacetArea, MinFacetEdgeLength, MaxFacetEdgeLength,
     Jacobian, JacobianDeterminant, JacobianInverse
     )
@@ -372,7 +373,8 @@ __all__ = as_native_strings([
     'as_domain', 'AbstractDomain', 'Mesh', 'MeshView', 'TensorProductMesh',
     'L2', 'H1', 'H2', 'HCurl', 'HDiv',
     'SpatialCoordinate',
-    'CellVolume', 'Circumradius', 'MinCellEdgeLength', 'MaxCellEdgeLength',
+    'CellVolume', 'CellDiameter', 'Circumradius',
+    'MinCellEdgeLength', 'MaxCellEdgeLength',
     'FacetArea', 'MinFacetEdgeLength', 'MaxFacetEdgeLength',
     'FacetNormal', 'CellNormal',
     'Jacobian', 'JacobianDeterminant', 'JacobianInverse',
diff --git a/ufl/algorithms/apply_derivatives.py b/ufl/algorithms/apply_derivatives.py
index 287c8cb..210c038 100644
--- a/ufl/algorithms/apply_derivatives.py
+++ b/ufl/algorithms/apply_derivatives.py
@@ -158,8 +158,11 @@ class GenericDerivativeRuleset(MultiFunction):
     # cell_facet_jacobian = unexpected
     # cell_facet_jacobian_determinant = unexpected
     # cell_facet_jacobian_inverse = unexpected
+    # cell_vertices = unexpected
     # cell_edge_vectors = unexpected
     # facet_edge_vectors = unexpected
+    # reference_cell_edge_vectors = unexpected
+    # reference_facet_edge_vectors = unexpected
     # cell_normal = unexpected # TODO: Expecting rename
     # cell_normals = unexpected
     # facet_tangents = unexpected
diff --git a/ufl/algorithms/apply_geometry_lowering.py b/ufl/algorithms/apply_geometry_lowering.py
index 8b10a97..d83b984 100644
--- a/ufl/algorithms/apply_geometry_lowering.py
+++ b/ufl/algorithms/apply_geometry_lowering.py
@@ -24,6 +24,9 @@ of mostly the Jacobian and reference cell data.
 
 from six.moves import xrange as range
 
+from functools import reduce
+from itertools import combinations
+
 from ufl.log import error, warning
 
 from ufl.core.multiindex import Index, indices
@@ -37,10 +40,10 @@ from ufl.classes import (Expr, Form, Integral,
                          CellOrientation, CellOrigin, CellCoordinate,
                          FacetJacobian, FacetJacobianDeterminant,
                          CellFacetJacobian,
-                         CellEdgeVectors, FacetEdgeVectors,
+                         MaxCellEdgeLength,
+                         CellEdgeVectors, FacetEdgeVectors, CellVertices,
                          ReferenceNormal,
-                         ReferenceCellVolume, ReferenceFacetVolume,
-                         CellVolume, FacetArea,
+                         ReferenceCellVolume, ReferenceFacetVolume, CellVolume,
                          SpatialCoordinate,
                          FloatValue)
 # FacetJacobianInverse,
@@ -233,38 +236,29 @@ class GeometryLoweringApplier(MultiFunction):
             return o
 
         domain = o.ufl_domain()
+
         if not domain.is_piecewise_linear_simplex_domain():
-            # Don't lower for non-affine cells, instead leave it to
-            # form compiler
-            warning("Only know how to compute the circumradius of an affine cell.")
-            return o
+            error("Circumradius only makes sense for affine simplex cells")
 
         cellname = domain.ufl_cell().cellname()
         cellvolume = self.cell_volume(CellVolume(domain))
 
         if cellname == "interval":
-            r = 0.5 * cellvolume
+            # Optimization for square interval; no square root needed
+            return 0.5 * cellvolume
 
-        elif cellname == "triangle":
-            J = self.jacobian(Jacobian(domain))
-            trev = CellEdgeVectors(domain)
-            num_edges = 3
-            i, j, k = indices(3)
-            elen = [sqrt((J[i, j]*trev[edge, j])*(J[i, k]*trev[edge, k]))
-                    for edge in range(num_edges)]
+        # Compute lengths of cell edges
+        edges = CellEdgeVectors(domain)
+        num_edges = edges.ufl_shape[0]
+        j = Index()
+        elen = [sqrt(edges[e, j]*edges[e, j]) for e in range(num_edges)]
 
-            r = (elen[0] * elen[1] * elen[2]) / (4.0 * cellvolume)
+        if cellname == "triangle":
+            return (elen[0] * elen[1] * elen[2]) / (4.0 * cellvolume)
 
         elif cellname == "tetrahedron":
-            J = self.jacobian(Jacobian(domain))
-            trev = CellEdgeVectors(domain)
-            num_edges = 6
-            i, j, k = indices(3)
-            elen = [sqrt((J[i, j]*trev[edge, j])*(J[i, k]*trev[edge, k]))
-                    for edge in range(num_edges)]
-
-            # elen[3] = length of edge 3
             # la, lb, lc = lengths of the sides of an intermediate triangle
+            # NOTE: Is here some hidden numbering assumption?
             la = elen[3] * elen[2]
             lb = elen[4] * elen[1]
             lc = elen[5] * elen[0]
@@ -274,126 +268,92 @@ class GeometryLoweringApplier(MultiFunction):
             s = p / 2
             # area of intermediate triangle with Herons formula
             triangle_area = sqrt(s * (s - la) * (s - lb) * (s - lc))
-            r = triangle_area / (6.0 * cellvolume)
-
-        else:
-            error("Unhandled cell type %s." % cellname)
+            return triangle_area / (6.0 * cellvolume)
 
-        return r
+    @memoized_handler
+    def max_cell_edge_length(self, o):
+        return self._reduce_cell_edge_length(o, max_value)
 
     @memoized_handler
     def min_cell_edge_length(self, o):
+        return self._reduce_cell_edge_length(o, min_value)
+
+    def _reduce_cell_edge_length(self, o, reduction_op):
         if self._preserve_types[o._ufl_typecode_]:
             return o
 
         domain = o.ufl_domain()
-        if not domain.is_piecewise_linear_simplex_domain():
-            # Don't lower for non-affine cells, instead leave it to
-            # form compiler
-            warning("Only know how to compute the min_cell_edge_length of an affine cell.")
-            return o
 
-        cellname = domain.ufl_cell().cellname()
+        if not domain.ufl_coordinate_element().degree() == 1:
+            # Don't lower bendy cells, instead leave it to form compiler
+            warning("Only know how to compute cell edge lengths of P1 or Q1 cell.")
+            return o
 
-        J = self.jacobian(Jacobian(domain))
-        trev = CellEdgeVectors(domain)
-        num_edges = trev.ufl_shape[0]
-        i, j, k = indices(3)
-        elen = [sqrt((J[i, j]*trev[edge, j])*(J[i, k]*trev[edge, k]))
-                for edge in range(num_edges)]
+        elif domain.ufl_cell().cellname() == "interval":
+            # Interval optimization, square root not needed
+            return self.cell_volume(CellVolume(domain))
 
-        if cellname == "triangle":
-            return min_value(elen[0], min_value(elen[1], elen[2]))
-        elif cellname == "tetrahedron":
-            min1 = min_value(elen[0], min_value(elen[1], elen[2]))
-            min2 = min_value(elen[3], min_value(elen[4], elen[5]))
-            return min_value(min1, min2)
         else:
-            error("Unhandled cell type %s." % cellname)
+            # Other P1 or Q1 cells
+            edges = CellEdgeVectors(domain)
+            num_edges = edges.ufl_shape[0]
+            j = Index()
+            elen2 = [edges[e, j]*edges[e, j] for e in range(num_edges)]
+            return sqrt(reduce(reduction_op, elen2))
 
     @memoized_handler
-    def max_cell_edge_length(self, o):
+    def cell_diameter(self, o):
         if self._preserve_types[o._ufl_typecode_]:
             return o
 
         domain = o.ufl_domain()
-        if not domain.is_piecewise_linear_simplex_domain():
-            # Don't lower for non-affine cells, instead leave it to
-            # form compiler
-            warning("Only know how to compute the max_cell_edge_length of an affine cell.")
-            return o
 
-        cellname = domain.ufl_cell().cellname()
+        if not domain.ufl_coordinate_element().degree() == 1:
+            # Don't lower bendy cells, instead leave it to form compiler
+            warning("Only know how to compute cell diameter of P1 or Q1 cell.")
+            return o
 
-        J = self.jacobian(Jacobian(domain))
-        trev = CellEdgeVectors(domain)
-        num_edges = trev.ufl_shape[0]
-        i, j, k = indices(3)
-        elen = [sqrt((J[i, j]*trev[edge, j])*(J[i, k]*trev[edge, k]))
-                for edge in range(num_edges)]
+        elif domain.is_piecewise_linear_simplex_domain():
+            # Simplices
+            return self.max_cell_edge_length(MaxCellEdgeLength(domain))
 
-        if cellname == "triangle":
-            return max_value(elen[0], max_value(elen[1], elen[2]))
-        elif cellname == "tetrahedron":
-            max1 = max_value(elen[0], max_value(elen[1], elen[2]))
-            max2 = max_value(elen[3], max_value(elen[4], elen[5]))
-            return max_value(max1, max2)
         else:
-            error("Unhandled cell type %s." % cellname)
+            # Q1 cells, maximal distance between any two vertices
+            verts = CellVertices(domain)
+            verts = [verts[v, ...] for v in range(verts.ufl_shape[0])]
+            j = Index()
+            elen2 = ((v0-v1)[j]*(v0-v1)[j] for v0, v1 in combinations(verts, 2))
+            return sqrt(reduce(max_value, elen2))
+
+    @memoized_handler
+    def max_facet_edge_length(self, o):
+        return self._reduce_facet_edge_length(o, max_value)
 
     @memoized_handler
     def min_facet_edge_length(self, o):
+        return self._reduce_facet_edge_length(o, min_value)
+
+    def _reduce_facet_edge_length(self, o, reduction_op):
         if self._preserve_types[o._ufl_typecode_]:
             return o
 
         domain = o.ufl_domain()
-        if not domain.is_piecewise_linear_simplex_domain():
-            # Don't lower for non-affine cells, instead leave it to
-            # form compiler
-            warning("Only know how to compute the min_facet_edge_length of an affine cell.")
-            return o
-
-        cellname = domain.ufl_cell().cellname()
-
-        if cellname == "triangle":
-            return self.facet_area(FacetArea(domain))
-        elif cellname == "tetrahedron":
-            J = self.jacobian(Jacobian(domain))
-            trev = FacetEdgeVectors(domain)
-            num_edges = 3
-            i, j, k = indices(3)
-            elen = [sqrt((J[i, j]*trev[edge, j])*(J[i, k]*trev[edge, k]))
-                    for edge in range(num_edges)]
-            return min_value(elen[0], min_value(elen[1], elen[2]))
-        else:
-            error("Unhandled cell type %s." % cellname)
 
-    @memoized_handler
-    def max_facet_edge_length(self, o):
-        if self._preserve_types[o._ufl_typecode_]:
-            return o
+        if domain.ufl_cell().topological_dimension() < 3:
+            error("Facet edge lengths only make sense for topological dimension >= 3.")
 
-        domain = o.ufl_domain()
-        if not domain.is_piecewise_linear_simplex_domain():
-            # Don't lower for non-affine cells, instead leave it to
-            # form compiler
-            warning("Only know how to compute the max_facet_edge_length of an affine cell.")
+        elif not domain.ufl_coordinate_element().degree() == 1:
+            # Don't lower bendy cells, instead leave it to form compiler
+            warning("Only know how to compute facet edge lengths of P1 or Q1 cell.")
             return o
 
-        cellname = domain.ufl_cell().cellname()
-
-        if cellname == "triangle":
-            return self.facet_area(FacetArea(domain))
-        elif cellname == "tetrahedron":
-            J = self.jacobian(Jacobian(domain))
-            trev = FacetEdgeVectors(domain)
-            num_edges = 3
-            i, j, k = indices(3)
-            elen = [sqrt((J[i, j]*trev[edge, j])*(J[i, k]*trev[edge, k]))
-                    for edge in range(num_edges)]
-            return max_value(elen[0], max_value(elen[1], elen[2]))
         else:
-            error("Unhandled cell type %s." % cellname)
+            # P1 tetrahedron or Q1 hexahedron
+            edges = FacetEdgeVectors(domain)
+            num_edges = edges.ufl_shape[0]
+            j = Index()
+            elen2 = [edges[e, j]*edges[e, j] for e in range(num_edges)]
+            return sqrt(reduce(reduction_op, elen2))
 
     @memoized_handler
     def cell_normal(self, o):
diff --git a/ufl/algorithms/elementtransformations.py b/ufl/algorithms/elementtransformations.py
index 9e68c70..ad15700 100644
--- a/ufl/algorithms/elementtransformations.py
+++ b/ufl/algorithms/elementtransformations.py
@@ -48,6 +48,9 @@ def tear(element):
 
 def _increase_degree(element, degree_rise):
     if isinstance(element, (FiniteElement, VectorElement, TensorElement)):
+        # Can't increase degree for reals
+        if element.family() == "Real":
+            return element
         return element.reconstruct(degree=(element.degree() + degree_rise))
     elif isinstance(element, MixedElement):
         return MixedElement([_increase_degree(e, degree_rise)
diff --git a/ufl/algorithms/renumbering.py b/ufl/algorithms/renumbering.py
index 86f32b6..465fec9 100644
--- a/ufl/algorithms/renumbering.py
+++ b/ufl/algorithms/renumbering.py
@@ -33,7 +33,7 @@ class VariableRenumberingTransformer(ReuseTransformer):
         self.variable_map = {}
 
     def variable(self, o):
-        e, l = o.ufl_operands
+        e, l = o.ufl_operands  # noqa: E741
         v = self.variable_map.get(l)
         if v is None:
             e = self.visit(e)
diff --git a/ufl/algorithms/transformer.py b/ufl/algorithms/transformer.py
index 90fec7c..7efbd0e 100644
--- a/ufl/algorithms/transformer.py
+++ b/ufl/algorithms/transformer.py
@@ -149,7 +149,7 @@ class Transformer(object):
     def reuse_variable(self, o):
         # Check variable cache to reuse previously transformed
         # variable if possible
-        e, l = o.ufl_operands
+        e, l = o.ufl_operands  # noqa: E741
         v = self._variable_cache.get(l)
         if v is not None:
             return v
@@ -171,7 +171,7 @@ class Transformer(object):
     def reconstruct_variable(self, o):
         # Check variable cache to reuse previously transformed
         # variable if possible
-        e, l = o.ufl_operands
+        e, l = o.ufl_operands  # noqa: E741
         v = self._variable_cache.get(l)
         if v is not None:
             return v
diff --git a/ufl/core/expr.py b/ufl/core/expr.py
index 42d6e21..23e9b7b 100644
--- a/ufl/core/expr.py
+++ b/ufl/core/expr.py
@@ -334,7 +334,7 @@ class Expr(object):
         "Try to evaluate as scalar and cast to float."
         try:
             v = float(self._ufl_evaluate_scalar_())
-        except:
+        except Exception:
             v = NotImplemented
         return v
 
diff --git a/ufl/core/terminal.py b/ufl/core/terminal.py
index 52c3d38..039a413 100644
--- a/ufl/core/terminal.py
+++ b/ufl/core/terminal.py
@@ -61,7 +61,7 @@ class Terminal(Expr):
                 if derivatives:
                     f = 0.0
                 return f
-            except:
+            except Exception:
                 pass
             # If it has an ufl_evaluate function, call it
             if hasattr(self, 'ufl_evaluate'):
diff --git a/ufl/finiteelement/mixedelement.py b/ufl/finiteelement/mixedelement.py
index 4879076..e9413b5 100644
--- a/ufl/finiteelement/mixedelement.py
+++ b/ufl/finiteelement/mixedelement.py
@@ -367,7 +367,7 @@ class TensorElement(MixedElement):
             if cell is not None:
                 cell = as_cell(cell)
             # Create scalar sub element
-            sub_element = FiniteElement(family, cell, degree, quad_scheme)
+            sub_element = FiniteElement(family, cell, degree, quad_scheme=quad_scheme)
 
         if sub_element.value_shape() != ():
             error("Expecting only scalar valued subelement for TensorElement.")
@@ -464,7 +464,7 @@ class TensorElement(MixedElement):
         self._check_component(i)
 
         i = self.symmetry().get(i, i)
-        l = len(self._shape)
+        l = len(self._shape)  # noqa: E741
         ii = i[:l]
         jj = i[l:]
         if ii not in self._sub_element_mapping:
diff --git a/ufl/formatting/ufl2latex.py b/ufl/formatting/ufl2latex.py
index 96ec8e8..5a4feb2 100644
--- a/ufl/formatting/ufl2latex.py
+++ b/ufl/formatting/ufl2latex.py
@@ -185,7 +185,7 @@ class Expression2LatexHandler(MultiFunction):
 
     def variable(self, o):
         # TODO: Ensure variable has been handled
-        e, l = o.ufl_operands
+        e, l = o.ufl_operands  # noqa: E741
         return "s_{%d}" % l._count
 
     # --- Non-terminal objects ---
@@ -330,13 +330,13 @@ class Expression2LatexHandler(MultiFunction):
         shape = o.ufl_shape
         if len(shape) == 1:
             ops = [self.visit(op) for op in o.ufl_operands]
-            l = " \\\\ \n ".join(ops)
+            l = " \\\\ \n ".join(ops)  # noqa: E741
         elif len(shape) == 2:
             rows = []
             for row in o.ufl_operands:
                 cols = (self.visit(op) for op in row.ufl_operands)
                 rows.append(" & \n ".join(cols))
-            l = " \\\\ \n ".join(rows)
+            l = " \\\\ \n ".join(rows)  # noqa: E741
         else:
             error("TODO: LaTeX handler for list tensor of rank 3 or higher not implemented!")
         return "\\left[\\begin{matrix}{%s}\\end{matrix}\\right]^T" % l
@@ -382,10 +382,10 @@ class Expression2LatexHandler(MultiFunction):
         return "!(%s)" % (a,)
 
     def conditional(self, o, c, t, f):
-        l = "\\begin{cases}\n"
-        l += "%s, &\text{if }\quad %s, \\\\\n" % (t, c)
-        l += "%s, &\text{otherwise.}\n" % f
-        l += "\\end{cases}"
+        l = "\\begin{cases}\n"  # noqa: E741
+        l += "%s, &\text{if }\quad %s, \\\\\n" % (t, c)  # noqa: E741
+        l += "%s, &\text{otherwise.}\n" % f  # noqa: E741
+        l += "\\end{cases}"  # noqa: E741
         return l
 
     def min_value(self, o, a, b):
@@ -472,7 +472,7 @@ def form2latex(form, formdata):
     for itg in integrals:
         variables = _extract_variables(itg.integrand())
         for v in variables:
-            l = v._label
+            l = v._label  # noqa: E741
             if l not in handled_variables:
                 handled_variables.add(l)
                 exprlatex = expression2latex(v._expression,
diff --git a/ufl/formatting/ufl2unicode.py b/ufl/formatting/ufl2unicode.py
index 04ece3a..64471e4 100644
--- a/ufl/formatting/ufl2unicode.py
+++ b/ufl/formatting/ufl2unicode.py
@@ -621,7 +621,7 @@ class Expression2UnicodeHandler(MultiFunction):
         return mathop(o, A, "sym")
 
     def list_tensor(self, o, *ops):
-        l = ", ".join(ops)
+        l = ", ".join(ops)  # noqa: E741
         return "%s%s%s" % ("[", l, "]")
 
     def component_tensor(self, o, A, ii):
@@ -677,7 +677,7 @@ class Expression2UnicodeHandler(MultiFunction):
         f = par(t)
         If = opfont("if")
         Else = opfont("else")
-        l = " ".join((t, If, c, Else, f))
+        l = " ".join((t, If, c, Else, f))  # noqa: E741
         return l
 
     def min_value(self, o, a, b):
diff --git a/ufl/geometry.py b/ufl/geometry.py
index 7199233..c78096f 100644
--- a/ufl/geometry.py
+++ b/ufl/geometry.py
@@ -367,10 +367,10 @@ class CellFacetJacobian(GeometricFacetQuantity):  # dX/dXf
 
 
 @ufl_type()
-class CellEdgeVectors(GeometricCellQuantity):
+class ReferenceCellEdgeVectors(GeometricCellQuantity):
     """UFL geometry representation: The vectors between reference cell vertices for each edge in cell."""
     __slots__ = ()
-    name = "CEV"
+    name = "RCEV"
 
     def __init__(self, domain):
         GeometricCellQuantity.__init__(self, domain)
@@ -392,10 +392,10 @@ class CellEdgeVectors(GeometricCellQuantity):
 
 
 @ufl_type()
-class FacetEdgeVectors(GeometricFacetQuantity):
+class ReferenceFacetEdgeVectors(GeometricFacetQuantity):
     """UFL geometry representation: The vectors between reference cell vertices for each edge in current facet."""
     __slots__ = ()
-    name = "FEV"
+    name = "RFEV"
 
     def __init__(self, domain):
         GeometricFacetQuantity.__init__(self, domain)
@@ -416,6 +416,78 @@ class FacetEdgeVectors(GeometricFacetQuantity):
         return True
 
 
+ at ufl_type()
+class CellVertices(GeometricCellQuantity):
+    """UFL geometry representation: Physical cell vertices."""
+    __slots__ = ()
+    name = "CV"
+
+    def __init__(self, domain):
+        GeometricCellQuantity.__init__(self, domain)
+
+    @property
+    def ufl_shape(self):
+        cell = self.ufl_domain().ufl_cell()
+        nv = cell.num_vertices()
+        g = cell.geometric_dimension()
+        return (nv, g)
+
+    def is_cellwise_constant(self):
+        "Return whether this expression is spatially constant over each cell."
+        # This is always constant for a given cell type
+        return True
+
+
+ at ufl_type()
+class CellEdgeVectors(GeometricCellQuantity):
+    """UFL geometry representation: The vectors between physical cell vertices for each edge in cell."""
+    __slots__ = ()
+    name = "CEV"
+
+    def __init__(self, domain):
+        GeometricCellQuantity.__init__(self, domain)
+        t = self._domain.topological_dimension()
+        if t < 2:
+            error("CellEdgeVectors is only defined for topological dimensions >= 2.")
+
+    @property
+    def ufl_shape(self):
+        cell = self.ufl_domain().ufl_cell()
+        ne = cell.num_edges()
+        g = cell.geometric_dimension()
+        return (ne, g)
+
+    def is_cellwise_constant(self):
+        "Return whether this expression is spatially constant over each cell."
+        # This is always constant for a given cell type
+        return True
+
+
+ at ufl_type()
+class FacetEdgeVectors(GeometricFacetQuantity):
+    """UFL geometry representation: The vectors between physical cell vertices for each edge in current facet."""
+    __slots__ = ()
+    name = "FEV"
+
+    def __init__(self, domain):
+        GeometricFacetQuantity.__init__(self, domain)
+        t = self._domain.topological_dimension()
+        if t < 3:
+            error("FacetEdgeVectors is only defined for topological dimensions >= 3.")
+
+    @property
+    def ufl_shape(self):
+        cell = self.ufl_domain().ufl_cell()
+        nfe = cell.num_facet_edges()
+        g = cell.geometric_dimension()
+        return (nfe, g)
+
+    def is_cellwise_constant(self):
+        "Return whether this expression is spatially constant over each cell."
+        # This is always constant for a given cell type
+        return True
+
+
 # --- Determinants (signed or pseudo) of geometry mapping Jacobians
 
 @ufl_type()
@@ -684,6 +756,15 @@ class Circumradius(GeometricCellQuantity):
     __slots__ = ()
     name = "circumradius"
 
+
+ at ufl_type()
+class CellDiameter(GeometricCellQuantity):
+    """UFL geometry representation: The diameter of the cell, i.e.,
+    maximal distance of two points in the cell."""
+    __slots__ = ()
+    name = "diameter"
+
+
 # @ufl_type()
 # class CellSurfaceArea(GeometricCellQuantity):
 #    """UFL geometry representation: The total surface area of the cell."""
diff --git a/ufl/mathfunctions.py b/ufl/mathfunctions.py
index 8dd2e80..ffe7e8c 100644
--- a/ufl/mathfunctions.py
+++ b/ufl/mathfunctions.py
@@ -327,7 +327,7 @@ class BesselFunction(Operator):
         a = self.ufl_operands[1].evaluate(x, mapping, component, index_values)
         try:
             import scipy.special
-        except:
+        except ImportError:
             error("You must have scipy installed to evaluate bessel functions in python.")
         name = self._name[-1]
         if isinstance(self.ufl_operands[0], IntValue):
diff --git a/ufl/objects.py b/ufl/objects.py
index 86de24f..f34c47c 100644
--- a/ufl/objects.py
+++ b/ufl/objects.py
@@ -27,7 +27,7 @@ from ufl.measure import Measure
 from ufl.measure import integral_type_to_measure_name
 
 # Default indices
-i, j, k, l = indices(4)
+i, j, k, l = indices(4)  # noqa: E741
 p, q, r, s = indices(4)
 
 for integral_type, measure_name in integral_type_to_measure_name.items():
diff --git a/ufl/operators.py b/ufl/operators.py
index e58eeff..b7b27c3 100644
--- a/ufl/operators.py
+++ b/ufl/operators.py
@@ -708,7 +708,7 @@ def exterior_derivative(f):
     else:
         try:
             element = f.ufl_element()
-        except:
+        except Exception:
             error("Unable to determine element from %s" % f)
 
     # Extract the family and the geometric dimension
diff --git a/ufl/tensors.py b/ufl/tensors.py
index 532d210..b821177 100644
--- a/ufl/tensors.py
+++ b/ufl/tensors.py
@@ -214,7 +214,7 @@ def from_numpy_to_lists(expressions):
         import numpy
         if isinstance(expressions, numpy.ndarray):
             expressions = numpy2nestedlists(expressions)
-    except:
+    except Exception:
         pass
     return expressions
 
@@ -397,11 +397,11 @@ def dyad(d, *iota):
     "TODO: Develop this concept, can e.g. write A[i,j]*dyad(j,i) for the transpose."
     from ufl.constantvalue import Identity
     from ufl.operators import outer  # a bit of circular dependency issue here
-    I = Identity(d)
+    Id = Identity(d)
     i = iota[0]
-    e = as_vector(I[i, :], i)
+    e = as_vector(Id[i, :], i)
     for i in iota[1:]:
-        e = outer(e, as_vector(I[i, :], i))
+        e = outer(e, as_vector(Id[i, :], i))
     return e
 
 
diff --git a/ufl/utils/formatting.py b/ufl/utils/formatting.py
index c40bf5b..edc18c5 100644
--- a/ufl/utils/formatting.py
+++ b/ufl/utils/formatting.py
@@ -31,7 +31,7 @@ def camel2underscore(name):
             # Don't insert _ between multiple upper case letters
             if lastlower:
                 letters.append("_")
-            l = l.lower()
+            l = l.lower()  # noqa: E741
         lastlower = thislower
         letters.append(l)
     return "".join(letters)

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



More information about the debian-science-commits mailing list