Skip to content

Commit

Permalink
Merged in miklos1/fix-firedrake-py3 (pull request #78)
Browse files Browse the repository at this point in the history
Python 3 fixes for Firedrake

Approved-by: Jan Blechta <blechta@karlin.mff.cuni.cz>
  • Loading branch information
miklos1 committed Jul 26, 2017
2 parents 89a0b92 + 3c1744d commit 2f4e1f1
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 18 deletions.
3 changes: 2 additions & 1 deletion ufl/algorithms/compute_form_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from itertools import chain

from ufl.log import error, info
from ufl.utils.sequences import max_degree

from ufl.classes import GeometricFacetQuantity, Coefficient, Form
from ufl.corealg.traversal import traverse_unique_terminals
Expand Down Expand Up @@ -55,7 +56,7 @@ def _auto_select_degree(elements):
"""
# Use max degree of all elements, at least 1 (to work with
# Lagrange elements)
return max({e.degree() for e in elements} - {None} | {1})
return max_degree({e.degree() for e in elements} - {None} | {1})


def _compute_element_mapping(form):
Expand Down
9 changes: 7 additions & 2 deletions ufl/algorithms/domain_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# along with UFL. If not, see <http://www.gnu.org/licenses/>.

from collections import defaultdict
from six import iteritems
from six.moves import zip

import ufl
Expand All @@ -27,7 +28,7 @@
from ufl.integral import Integral
from ufl.form import Form
from ufl.sorting import cmp_expr, sorted_expr
from ufl.utils.sorting import canonicalize_metadata, sorted_by_key, sorted_by_tuple_key
from ufl.utils.sorting import canonicalize_metadata, sorted_by_key
import numbers


Expand Down Expand Up @@ -275,8 +276,12 @@ def build_integral_data(integrals):

# Build list with canonical ordering, iteration over dicts
# is not deterministic across python versions
def keyfunc(item):
(d, itype, sid), integrals = item
return (d._ufl_sort_key_(), itype, (type(sid).__name__, sid))

integral_datas = []
for (d, itype, sid), integrals in sorted_by_tuple_key(itgs):
for (d, itype, sid), integrals in sorted(iteritems(itgs), key=keyfunc):
integral_datas.append(IntegralData(d, itype, sid, integrals, {}))
return integral_datas

Expand Down
6 changes: 4 additions & 2 deletions ufl/finiteelement/elementlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

from __future__ import print_function

from numpy import asarray

from ufl.log import warning, error
from ufl.sobolevspace import L2, H1, H2, HDiv, HCurl, HEin, HDivDiv
from ufl.utils.formatting import istr
Expand Down Expand Up @@ -354,10 +356,10 @@ def canonical_element_description(family, cell, order, form_degree):
error('Order "%s" invalid for "%s" finite element, '
'should be None.' % (order, family))
kmin, kmax = krange
if not (kmin is None or order >= kmin):
if not (kmin is None or (asarray(order) >= kmin).all()):
error('Order "%s" invalid for "%s" finite element.' %
(order, family))
if not (kmax is None or order <= kmax):
if not (kmax is None or (asarray(order) <= kmax).all()):
error('Order "%s" invalid for "%s" finite element.' %
(istr(order), family))

Expand Down
4 changes: 2 additions & 2 deletions ufl/finiteelement/mixedelement.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from ufl.log import error
from ufl.utils.py23 import as_native_strings
from ufl.permutation import compute_indices
from ufl.utils.sequences import product
from ufl.utils.sequences import product, max_degree
from ufl.utils.dicts import EmptyDict
from ufl.utils.indexflattening import flatten_multiindex, unflatten_index, shape_to_strides
from ufl.cell import as_cell
Expand Down Expand Up @@ -101,7 +101,7 @@ def __init__(self, *elements, **kwargs):

# Initialize element data
degrees = {e.degree() for e in self._sub_elements} - {None}
degree = max(degrees) if degrees else None
degree = max_degree(degrees) if degrees else None
FiniteElementBase.__init__(self, "Mixed", cell, degree, quad_scheme,
value_shape, reference_value_shape)

Expand Down
3 changes: 2 additions & 1 deletion ufl/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from collections import defaultdict

from ufl.log import error, warning
from ufl.domain import sort_domains
from ufl.integral import Integral
from ufl.checks import is_scalar_constant_expression
from ufl.equation import Equation
Expand Down Expand Up @@ -57,7 +58,7 @@ def _sorted_integrals(integrals):
all_integrals = []

# Order integrals canonically to increase signature stability
for d in sorted(integrals_dict): # Assuming Domain is sortable
for d in sort_domains(integrals_dict):
for it in sorted(integrals_dict[d]): # str is sortable
for si in sorted(integrals_dict[d][it],
key=lambda x: (type(x).__name__, x)): # int/str are sortable
Expand Down
18 changes: 17 additions & 1 deletion ufl/utils/sequences.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@
# You should have received a copy of the GNU Lesser General Public License
# along with UFL. If not, see <http://www.gnu.org/licenses/>.

from six.moves import zip
from functools import reduce

from six.moves import map, zip
from six import string_types

import numpy


def product(sequence):
"Return the product of all elements in a sequence."
Expand Down Expand Up @@ -67,3 +71,15 @@ def recursive_chain(lists):
else:
for s in recursive_chain(l):
yield s


def max_degree(degrees):
"""Maximum degree for mixture of scalar and tuple degrees."""
# numpy.maximum broadcasts scalar degrees to tuple degrees if
# necessary. reduce applies numpy.maximum pairwise.
degree = reduce(numpy.maximum, map(numpy.asarray, degrees))
if degree.ndim:
degree = tuple(map(int, degree)) # tuple degree
else:
degree = int(degree) # scalar degree
return degree
9 changes: 0 additions & 9 deletions ufl/utils/sorting.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,6 @@ def _key(x):
return sorted(iteritems(mapping), key=_key)


def sorted_by_tuple_key(mapping):
"Sort dict items by tuple valued keys, allowing different types as items of the key tuples."
# Python3 doesn't allow comparing builtins of different type,
# therefore the typename trick here
def _tuple_key(x):
return tuple((type(k).__name__, k) for k in x[0])
return sorted(iteritems(mapping), key=_tuple_key)


def canonicalize_metadata(metadata):
"""Assuming metadata to be a dict with string keys and builtin python types as values.
Expand Down

0 comments on commit 2f4e1f1

Please sign in to comment.