diff --git a/doc/sphinx/source/index.rst b/doc/sphinx/source/index.rst index 2ad218d27..9e577342d 100644 --- a/doc/sphinx/source/index.rst +++ b/doc/sphinx/source/index.rst @@ -24,32 +24,58 @@ Compiler (FFC) and in combination with the problem solving environment DOLFIN. -Preliminaries -============= Installation ------------- +============ -Ubuntu package -^^^^^^^^^^^^^^ +Debian/Ubuntu packages +---------------------- -UFL may be installed directly from source, but the Debian (Ubuntu) -package ``python-ufl`` is also available for UFL, as for other FEniCS -components. +Debian/Ubuntu +^^^^^^^^^^^^^ -Manual from source -^^^^^^^^^^^^^^^^^^ +A Debian/Ubuntu package ``python-ufl`` is available for UFL: -To retrieve the latest development version of UFL:: + sudo apt-get install python-ufl - git clone https://bitbucket.org/fenics-project/ufl -To install UFL:: +Ubuntu PPA +^^^^^^^^^^ + +UFL is available in the FEniCS Project PPA. The version of UFL +available in the PPA will generally more recent than the Debian/Ubuntu +package. To install UFL from the PPA: + + sudo add-apt-repository ppa:fenics-packages/fenics + sudo apt-get update + sudo apt-get install fenics + + +From source +----------- + +Dependencies +^^^^^^^^^^^^ + +UFL depends on the Python packages ``numpy`` and ``six``, and +``setuptools`` is recommended. If ``setuptools`` is available, the UFL +installer will install missing dependencies automatically. + + +Installation +^^^^^^^^^^^^ + +The source for UFL releases can be downloaded from +http://fenicsproject.org/pub/software/ufl/. To install UFL +system-wide, from the source directory use: python setup.py install +To install into a specified directory, use the ``--prefix`` option. + + Help and support ----------------- +================ Send help requests and questions to fenics-support@googlegroups.com. @@ -61,23 +87,24 @@ Development and reporting bugs The git source repository for UFL is located at https://bitbucket.org/fenics-project/ufl. For general UFL development -questions and to make feature requests, use fenics-dev@googlegroups.com +questions and to make feature requests, use +fenics-dev@googlegroups.com. Bugs can be registered at https://bitbucket.org/fenics-project/ufl/issues. -Manual and API Reference + +Manual and API reference ======================== .. toctree:: :titlesonly: User Manual - API Reference + API Reference Releases - * :ref:`modindex` * :ref:`genindex` * :ref:`search` diff --git a/setup.py b/setup.py index e4f17ed6b..b55409783 100755 --- a/setup.py +++ b/setup.py @@ -1,7 +1,12 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import print_function -from distutils.core import setup + +try: + from setuptools import setup +except ImportError: + from distutils.core import setup + from os.path import join as pjoin, split as psplit import re import sys @@ -59,6 +64,7 @@ "ufl.formatting", ], package_dir = {"ufl": "ufl"}, + install_requires = ["numpy", "six"], data_files = [(pjoin("share", "man", "man1"), [pjoin("doc", "man", "man1", "ufl-analyse.1.gz"), pjoin("doc", "man", "man1", "ufl-convert.1.gz"), diff --git a/ufl/algorithms/domain_analysis.py b/ufl/algorithms/domain_analysis.py index cebf40120..1a8ffa500 100644 --- a/ufl/algorithms/domain_analysis.py +++ b/ufl/algorithms/domain_analysis.py @@ -23,16 +23,13 @@ from six import iteritems import ufl -from ufl.utils.sorting import sorted_by_key from ufl.log import error from ufl.assertions import ufl_assert from ufl.measure import Measure from ufl.integral import Integral from ufl.form import Form - -from ufl.sorting import cmp_expr -from ufl.sorting import sorted_expr -from ufl.utils.sorting import canonicalize_metadata +from ufl.sorting import cmp_expr, sorted_expr +from ufl.utils.sorting import canonicalize_metadata, sorted_by_key, sorted_by_tuple_key class IntegralData(object): @@ -228,6 +225,7 @@ def accumulate_integrands_with_same_metadata(integrals): # Sort integrands canonically by integrand first then compiler data return sorted(by_cdid.values(), key=ExprTupleKey) + def build_integral_data(integrals): """Build integral data given a list of integrals. @@ -251,8 +249,12 @@ def build_integral_data(integrals): # possibly different metadata). itgs[(domain, integral_type, subdomain_id)].append(integral) - return tuple(IntegralData(d, itype, sid, integrals, {}) for - (d, itype, sid), integrals in itgs.items()) + # Build list with canonical ordering, iteration over dicts + # is not deterministic across python versions + integral_datas = [] + for (d, itype, sid), integrals in sorted_by_tuple_key(itgs): + integral_datas.append(IntegralData(d, itype, sid, integrals, {})) + return integral_datas def group_form_integrals(form, domains): @@ -262,11 +264,9 @@ def group_form_integrals(form, domains): :arg domains: an iterable of :class:`~.Domain`\s. :returns: A new :class:`~.Form` with gathered integrands. """ - integrals = form.integrals() - # Group integrals by domain and type integrals_by_domain_and_type = \ - group_integrals_by_domain_and_type(integrals, domains) + group_integrals_by_domain_and_type(form.integrals(), domains) integrals = [] for domain in domains: diff --git a/ufl/utils/sorting.py b/ufl/utils/sorting.py index eaa1b968f..f7b9a469a 100644 --- a/ufl/utils/sorting.py +++ b/ufl/utils/sorting.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- "Utilites for sorting." -# Copyright (C) 2008-2015 Johan Hake +# Copyright (C) 2008-2016 Johan Hake # # This file is part of UFL. # @@ -56,18 +56,31 @@ def topological_sorting(nodes, edges): return L + def sorted_by_count(seq): "Sort a sequence by the item.count()." return sorted(seq, key=lambda x: x.count()) + def sorted_by_ufl_id(seq): "Sort a sequence by the item.ufl_id()." return sorted(seq, key=lambda x: x.ufl_id()) + def sorted_by_key(mapping): "Sort dict items by key, allowing different key types." # Python3 doesn't allow comparing builtins of different type, therefore the typename trick here - return sorted(iteritems(mapping), key=lambda x: (type(x[0]).__name__, x[0])) + def _key(x): + return (type(x[0]).__name__, x[0]) + 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):