[fiat] 01/03: Imported Upstream version 2016.1.0

Johannes Ring johannr-guest at moszumanska.debian.org
Fri Jun 24 11:07:22 UTC 2016


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

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

commit d52fd12dc23c3841b1f5a3d8c6c4b53b6ec5eda8
Author: Johannes Ring <johannr at simula.no>
Date:   Fri Jun 24 12:46:58 2016 +0200

    Imported Upstream version 2016.1.0
---
 .bzrignore                               |   9 +
 .gitignore                               |   5 +
 ChangeLog                                |   5 +-
 FIAT/__init__.py                         |   2 +-
 setup.py                                 |  16 +-
 test/regression/.gitignore               |   1 +
 test/regression/README.rst               |  58 ++++++
 test/regression/fiat-reference-data-id   |   1 +
 test/regression/scripts/download         |  41 ++++
 test/regression/scripts/getdata          |  34 +++
 test/regression/scripts/getreferencerepo |  62 ++++++
 test/regression/scripts/parameters       |   6 +
 test/regression/scripts/upload           |  72 +++++++
 test/{ => regression}/test.py            | 114 ++++++++--
 test/test.py                             | 348 ++++---------------------------
 test/unit/test.py                        |  66 ++++++
 16 files changed, 500 insertions(+), 340 deletions(-)

diff --git a/.bzrignore b/.bzrignore
new file mode 100644
index 0000000..4da66d2
--- /dev/null
+++ b/.bzrignore
@@ -0,0 +1,9 @@
+(^|/)CVS($|/)
+(^|/)\.hg($|/)
+(^|/)\.hgtags($|/)
+^project.log$
+^tailor.state$
+^tailor.state.old$
+^tailor.state.journal$
+syntax: glob
+FIAT/*.pyc
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..613b484
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.pyc
+
+build/
+dist/
+FIAT.egg-info/
diff --git a/ChangeLog b/ChangeLog
index 2e22deb..c19e185 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
+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 [2014-01-12]
+1.5.0 [2015-01-12]
  - Require Python 2.7
  - Python 3 support
  - Remove ScientificPython dependency and add dependency on SymPy
diff --git a/FIAT/__init__.py b/FIAT/__init__.py
index 9a58b54..77fc657 100644
--- a/FIAT/__init__.py
+++ b/FIAT/__init__.py
@@ -2,7 +2,7 @@
 evaluating arbitrary order Lagrange and many other elements.
 Simplices in one, two, and three dimensions are supported."""
 
-__version__ = "1.6.0dev"
+__version__ = "2016.1.0"
 
 # Import finite element classes
 from FIAT.finite_element import FiniteElement
diff --git a/setup.py b/setup.py
index 2dd0e27..70a9937 100755
--- a/setup.py
+++ b/setup.py
@@ -15,12 +15,18 @@ if sys.version_info < (2, 7):
 version = re.findall('__version__ = "(.*)"',
                      open('FIAT/__init__.py', 'r').read())[0]
 
+url = "https://bitbucket.org/fenics-project/fiat/"
+tarball = None
+if not 'dev' in version:
+    tarball = url + "downloads/fiat-%s.tar.gz" % version
+
 setup(name="FIAT",
-      version=version,
       description="FInite element Automatic Tabulator",
-      author="Robert C. Kirby",
-      author_email="robert.c.kirby at gmail.com",
-      url="http://www.math.ttu.edu/~kirby",
+      version=version,
+      author="Robert C. Kirby et al.",
+      author_email="fenics-dev at googlegroups.com",
+      url=url,
+      download_url=tarball,
       license="LGPL v3 or later",
       packages=["FIAT"],
-      install_requires=["sympy"])
+      install_requires=["numpy", "sympy"])
diff --git a/test/regression/.gitignore b/test/regression/.gitignore
new file mode 100644
index 0000000..56d0de7
--- /dev/null
+++ b/test/regression/.gitignore
@@ -0,0 +1 @@
+fiat-reference-data/
diff --git a/test/regression/README.rst b/test/regression/README.rst
new file mode 100644
index 0000000..db9f519
--- /dev/null
+++ b/test/regression/README.rst
@@ -0,0 +1,58 @@
+How to run regression tests
+===========================
+
+To run regression tests with default parameters, simply run:
+
+  cd <fiatdir>/test/regression/
+  python test.py
+
+Look at test.py for more options.
+
+
+How to update references
+========================
+
+To update the references for the FIAT regression tests, first commit
+your changes, then run the regression test (to generate the new
+references) and finally run the script upload:
+
+  <commit your changes>
+  cd <fiatdir>/test/regression/
+  python test.py
+  ./scripts/upload
+
+Note: You may be asked for your *Bitbucket* username and password when
+uploading the reference data, if use of ssh keys fails.
+
+Note: The upload script will push the new references to the
+fiat-reference-data repository. This is harmless even if these
+references are not needed later.
+
+Note: The upload script will update the file fiat-regression-data-id
+and commit this change to the currently active branch, remember to
+include this commit when merging or pushing your changes elsewhere.
+
+Note: You can cherry-pick the commit that updated
+fiat-regression-data-id into another branch to use the same set of
+references there.
+
+Note: If you ever get merge conflicts in the fiat-regression-data-id,
+always pick one version of the file. Most likely you'll need to update
+the references again.
+
+
+How to run regression tests against a different set of regression data
+======================================================================
+
+To run regression tests and compare to a different set of regression
+data, perhaps to see what has changed in generated code since a
+certain version, check out the fiat-regression-data-id file you want
+and run tests as usual
+
+  cd <fiatdir>/test/regression/
+  git checkout <fiat-commit-id> fiat-regression-data-id
+  python test.py
+
+The test.py script will run scripts/download which will check out the
+regression data with the commit id from fiat-regression-data-id in
+fiat-regression-data/.
diff --git a/test/regression/fiat-reference-data-id b/test/regression/fiat-reference-data-id
new file mode 100644
index 0000000..b7cbaae
--- /dev/null
+++ b/test/regression/fiat-reference-data-id
@@ -0,0 +1 @@
+8ceb724ba33419e412aa30ae8d23c2f8c7ab3b84
diff --git a/test/regression/scripts/download b/test/regression/scripts/download
new file mode 100755
index 0000000..054a309
--- /dev/null
+++ b/test/regression/scripts/download
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+# Copyright (C) 2013 Anders Logg and Martin Sandve Alnaes
+#
+# This file is part of FIAT.
+#
+# FIAT is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# FIAT is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with FIAT. If not, see <http://www.gnu.org/licenses/>.
+#
+# Modified by Johannes Ring, 2013-04-23
+#
+# First added:  2013-04-22
+# Last changed: 2013-08-20
+#
+# This script downloads the reference data for the FIAT regression tests
+# and updates to the reference data version specified by the data id file.
+
+# Parameters
+source ./scripts/parameters
+
+# Get updated reference repository
+./scripts/getreferencerepo
+if [ $? -ne 0 ]; then
+    exit 1
+fi
+
+# Checkout data referenced by id file
+./scripts/getdata
+if [ $? -ne 0 ]; then
+    exit 1
+fi
diff --git a/test/regression/scripts/getdata b/test/regression/scripts/getdata
new file mode 100755
index 0000000..9eacdac
--- /dev/null
+++ b/test/regression/scripts/getdata
@@ -0,0 +1,34 @@
+#!/bin/bash
+#
+# Copyright (C) 2013 Anders Logg and Martin Sandve Alnaes
+#
+# This file is part of FIAT.
+#
+# FIAT is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# FIAT is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with FIAT. If not, see <http://www.gnu.org/licenses/>.
+#
+# First added:  2013-04-22
+# Last changed: 2013-08-21
+#
+# This script checks out reference data by the given commit id,
+# or if none given using the commit id found in data id file.
+
+# Parameters
+source scripts/parameters
+
+# Take data id as optional argument or get from file
+DATA_ID=$1 && [ -z "$DATA_ID" ] && DATA_ID=`cat $DATA_ID_FILE`
+
+# Checkout data referenced by id
+(cd $DATA_DIR && git checkout -B auto $DATA_ID)
+exit $?
diff --git a/test/regression/scripts/getreferencerepo b/test/regression/scripts/getreferencerepo
new file mode 100755
index 0000000..ae971c7
--- /dev/null
+++ b/test/regression/scripts/getreferencerepo
@@ -0,0 +1,62 @@
+#!/bin/bash
+#
+# Copyright (C) 2013 Anders Logg and Martin Sandve Alnaes
+#
+# This file is part of FIAT.
+#
+# FIAT is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# FIAT is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with FIAT. If not, see <http://www.gnu.org/licenses/>.
+#
+# First added:  2013-04-22
+# Last changed: 2013-08-21
+#
+# This script overwrites the reference data with the current output
+# and stores the new reference data as part of the FIAT reference data
+# repository.
+
+# Parameters
+source ./scripts/parameters
+
+# Get reference repository
+if [ ! -d "$DATA_DIR" ]; then
+    echo "Cloning reference data repository"
+    git clone $DATA_REPO_GIT
+    if [ ! -d "$DATA_DIR" ]; then
+        git clone $DATA_REPO_HTTPS
+    fi
+else
+    pushd $DATA_DIR
+    echo "Found existing reference data repository, pulling new data"
+    git checkout master
+    if [ $? -ne 0 ]; then
+        echo "Failed to checkout master, check state of reference data directory."
+        exit 1
+    fi
+    git fetch
+    if [ $? -ne 0 ]; then
+        echo "WARNING: Failed to fetch latest reference data from server."
+    else
+        git pull
+        if [ $? -ne 0 ]; then
+            echo "Failed to pull latest reference data from server, possibly a merge situation."
+            exit 1
+        fi
+    fi
+    popd
+fi
+
+# Check that we had success with getting reference repository
+if [ ! -d "$DATA_DIR" ]; then
+    echo "Failed to update reference data directory '$DATA_DIR'."
+    exit 1
+fi
diff --git a/test/regression/scripts/parameters b/test/regression/scripts/parameters
new file mode 100755
index 0000000..dbd307d
--- /dev/null
+++ b/test/regression/scripts/parameters
@@ -0,0 +1,6 @@
+#OUTPUT_DIR="output"
+DATA_REPO_GIT="git at bitbucket.org:fenics-project/fiat-reference-data.git"
+DATA_REPO_HTTPS="https://bitbucket.org/fenics-project/fiat-reference-data.git"
+DATA_DIR="fiat-reference-data"
+DATA_ID_FILE="fiat-reference-data-id"
+OUTPUT_DIR="$DATA_DIR"
diff --git a/test/regression/scripts/upload b/test/regression/scripts/upload
new file mode 100755
index 0000000..50ed684
--- /dev/null
+++ b/test/regression/scripts/upload
@@ -0,0 +1,72 @@
+#!/bin/bash
+#
+# Copyright (C) 2013 Anders Logg and Martin Sandve Alnaes
+#
+# This file is part of FIAT.
+#
+# FIAT is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# FIAT is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with FIAT. If not, see <http://www.gnu.org/licenses/>.
+#
+# First added:  2013-04-22
+# Last changed: 2013-08-21
+#
+# This script overwrites the reference data with the current output
+# and stores the new reference data as part of the FIAT reference data
+# repository. The commit id of the stored reference data is commited
+# to a file in the main repo.
+
+# Parameters
+source ./scripts/parameters
+
+# Get updated reference repository
+./scripts/getreferencerepo
+if [ $? -ne 0 ]; then
+    exit 1
+fi
+
+# Check that we have any data
+if [ ! -d "$OUTPUT_DIR" ]; then
+    echo "Missing data directory '$OUTPUT_DIR'."
+    exit 1
+fi
+
+# Copy references
+echo "Copying new reference data to $DATA_DIR"
+rsync -r  --exclude='README.rst' --exclude='*.bin' --exclude='*.cpp' $OUTPUT_DIR/ $DATA_DIR
+echo ""
+
+# Get current id for main repo (does not include dirty files, so not quite trustworthy!)
+REPO_ID=`git rev-list --max-count 1 HEAD`
+
+# Commit new data to reference repository
+pushd $DATA_DIR
+git add *
+git commit -m "Update reference data, current project head is ${REPO_ID}." | grep -v "create mode"
+if [ $? -ne 0 ]; then
+    echo "Failed to commit reference data."
+    exit 1
+fi
+DATA_ID=`git rev-list --max-count 1 HEAD`
+popd
+
+# Commit reference data commit id to file in main repo
+echo $DATA_ID > $DATA_ID_FILE
+git commit $DATA_ID_FILE -m"Update reference data pointer to ${DATA_ID}."
+
+# Push references to server
+pushd $DATA_DIR
+git push
+if [ $? -ne 0 ]; then
+    echo "WARNING: Failed to push new reference data to server."
+fi
+popd
diff --git a/test/test.py b/test/regression/test.py
similarity index 73%
copy from test/test.py
copy to test/regression/test.py
index a37df8b..26b3c85 100644
--- a/test/test.py
+++ b/test/regression/test.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Anders Logg
+# Copyright (C) 2010 Anders Logg, 2015 Jan Blechta
 #
 # This file is part of FIAT.
 #
@@ -18,10 +18,8 @@
 # First added:  2010-01-31
 # Last changed: 2014-06-30
 
-import nose
-import sys
-import json
-import numpy
+from __future__ import print_function
+import nose, json, numpy, warnings, os, sys
 
 from FIAT import supported_elements, make_quadrature, ufc_simplex, \
     newdubiner, expansions, reference_element, polynomial_set
@@ -29,6 +27,9 @@ from FIAT import supported_elements, make_quadrature, ufc_simplex, \
 # Parameters
 tolerance = 1e-8
 
+# Directory with reference data
+prefix = 'fiat-reference-data'
+
 
 class NumpyEncoder(json.JSONEncoder):
     def default(self, obj):
@@ -58,10 +59,13 @@ def test_polynomials():
         return ps.dmats
 
     # Try reading reference values
-    filename = "reference-polynomials.json"
+    filename = os.path.join(prefix, "reference-polynomials.json")
     try:
         reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
     except IOError:
+        warnings.warn('Reference file "%s" could not be loaded! '
+                      'Creating a new reference file!' % filename,
+                      RuntimeWarning)
         reference = create_data()
         # Store the data for the future
         json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
@@ -81,10 +85,13 @@ def test_polynomials_1D():
         return ps.dmats
 
     # Try reading reference values
-    filename = "reference-polynomials_1D.json"
+    filename = os.path.join(prefix, "reference-polynomials_1D.json")
     try:
         reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
     except IOError:
+        warnings.warn('Reference file "%s" could not be loaded! '
+                      'Creating a new reference file!' % filename,
+                      RuntimeWarning)
         reference = create_data()
         # Store the data for the future
         json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
@@ -107,10 +114,13 @@ def test_expansions():
         return phis, dphis
 
     # Try reading reference values
-    filename = "reference-expansions.json"
+    filename = os.path.join(prefix, "reference-expansions.json")
     try:
         reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
     except IOError:
+        warnings.warn('Reference file "%s" could not be loaded! '
+                      'Creating a new reference file!' % filename,
+                       RuntimeWarning)
         reference = create_data()
         # Convert reference to list of int
         json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
@@ -144,10 +154,13 @@ def test_expansions_jet():
         F = expansions.TetrahedronExpansionSet(E)
         return F.tabulate_jet(n, pts, order)
 
-    filename = "reference-expansions-jet.json"
+    filename = os.path.join(prefix, "reference-expansions-jet.json")
     try:
         reference_jet = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
     except IOError:
+        warnings.warn('Reference file "%s" could not be loaded! '
+                      'Creating a new reference file!' % filename,
+                       RuntimeWarning)
         reference_jet = create_data()
         # Store the data for the future
         json.dump(reference_jet, open(filename, "w"), cls=NumpyEncoder)
@@ -170,10 +183,13 @@ def test_newdubiner():
         return newdubiner.tabulate_tetrahedron_derivatives(D, pts, float)
 
     # Try reading reference values
-    filename = "reference-newdubiner.json"
+    filename = os.path.join(prefix, "reference-newdubiner.json")
     try:
         reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
     except IOError:
+        warnings.warn('Reference file "%s" could not be loaded! '
+                      'Creating a new reference file!' % filename,
+                       RuntimeWarning)
         reference = create_data()
         # Convert reference to list of int
         json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
@@ -198,10 +214,13 @@ def test_newdubiner_jet():
         pts = newdubiner.make_tetrahedron_lattice(latticeK, float)
         return newdubiner.tabulate_jet(D, n, pts, order, float)
 
-    filename = "reference-newdubiner-jet.json"
+    filename = os.path.join(prefix, "reference-newdubiner-jet.json")
     try:
         reference_jet = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
     except IOError:
+        warnings.warn('Reference file "%s" could not be loaded! '
+                      'Creating a new reference file!' % filename,
+                       RuntimeWarning)
         reference_jet = create_data()
         # Store the data for the future
         json.dump(reference_jet, open(filename, "w"), cls=NumpyEncoder)
@@ -221,12 +240,18 @@ def test_quadrature():
     max_derivative = 3
     # Combinations of (family, dim, degree) to test
     test_cases = (
+        ("Lagrange", 1, 1),
+        ("Lagrange", 1, 2),
+        ("Lagrange", 1, 3),
         ("Lagrange", 2, 1),
         ("Lagrange", 2, 2),
         ("Lagrange", 2, 3),
         ("Lagrange", 3, 1),
         ("Lagrange", 3, 2),
         ("Lagrange", 3, 3),
+        ("Discontinuous Lagrange", 1, 0),
+        ("Discontinuous Lagrange", 1, 1),
+        ("Discontinuous Lagrange", 1, 2),
         ("Discontinuous Lagrange", 2, 0),
         ("Discontinuous Lagrange", 2, 1),
         ("Discontinuous Lagrange", 2, 2),
@@ -264,12 +289,13 @@ def test_quadrature():
         ("Nedelec 2nd kind H(curl)", 3, 1),
         ("Nedelec 2nd kind H(curl)", 3, 2),
         ("Nedelec 2nd kind H(curl)", 3, 3),
+        ("Crouzeix-Raviart", 1, 1),
         ("Crouzeix-Raviart", 2, 1),
         ("Crouzeix-Raviart", 3, 1),
-        ("Regge", 2, 0),        
+        ("Regge", 2, 0),
         ("Regge", 2, 1),
         ("Regge", 2, 2),
-        ("Regge", 3, 0),        
+        ("Regge", 3, 0),
         ("Regge", 3, 1),
         ("Regge", 3, 2)
         )
@@ -280,7 +306,7 @@ def test_quadrature():
         # Get domain and element class
         domain = ufc_simplex(dim)
         ElementClass = supported_elements[family]
-        # Create element|
+        # Create element
         element = ElementClass(domain, degree)
         # Create quadrature points
         quad_rule = make_quadrature(domain, num_points)
@@ -301,12 +327,26 @@ def test_quadrature():
             assert (abs(diff) < tolerance).all()
         return
 
-    # Try reading reference values
-    filename = "reference.json"
+    filename = os.path.join(prefix, "reference.json")
 
+    # Try comparing against references
     try:
         reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
-    except IOError:
+        for test_case in test_cases:
+            family, dim, degree = test_case
+            yield _perform_test, family, dim, degree, reference[str(test_case)]
+
+    # Update references if missing
+    except (IOError, KeyError) as e:
+        if isinstance(e, IOError):
+            warnings.warn('Reference file "%s" could not be loaded! '
+                          'Creating a new reference file!' % filename,
+                          RuntimeWarning)
+        else:
+            assert isinstance(e, KeyError) and len(e.args) == 1
+            warnings.warn('Reference file "%s" does not contain reference "%s"! '
+                          'Creating a new reference file!'
+                          % (filename, e.args[0]), RuntimeWarning)
         reference = {}
         for test_case in test_cases:
             family, dim, degree = test_case
@@ -315,10 +355,42 @@ def test_quadrature():
         # Store the data for the future
         json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
 
-    for test_case in test_cases:
-        family, dim, degree = test_case
-        yield _perform_test, family, dim, degree, reference[str(test_case)]
+
+
+def main(args):
+    # Download reference data
+    skip_download = "--skip-download" in args
+    if skip_download:
+        print("Skipping reference data download")
+        args.remove("--skip-download")
+        if not os.path.exists(prefix):
+            os.makedirs(prefix)
+    else:
+        failure = os.system("./scripts/download")
+        if failure:
+            print("Download reference data failed")
+            return 1
+        else:
+            print("Download reference data ok")
+
+    # Run the test
+    with warnings.catch_warnings(record=True) as warns:
+        result = nose.run()
+
+    # Handle failed test
+    if not result:
+        return 1
+
+    # Handle missing references
+    for w in warns:
+        warnings.showwarning(w.message, w.category, w.filename,
+                             w.lineno, w.line)
+    if len(warns) > 0:
+        print("References missing. New references stored into '%s'" % prefix)
+        return 1
+
+    return 0
 
 
 if __name__ == "__main__":
-    nose.main()
+    sys.exit(main(sys.argv))
diff --git a/test/test.py b/test/test.py
index a37df8b..e658e52 100644
--- a/test/test.py
+++ b/test/test.py
@@ -1,324 +1,48 @@
-# Copyright (C) 2010 Anders Logg
+"""Run all tests, including unit tests and regression tests"""
+
+# Copyright (C) 2007 Anders Logg
 #
-# This file is part of FIAT.
+# This file is part of fiat.
 #
-# FIAT is free software: you can redistribute it and/or modify
+# fiat is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
-# FIAT is distributed in the hope that it will be useful,
+# fiat is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU Lesser General Public License for more details.
 #
 # You should have received a copy of the GNU Lesser General Public License
-# along with FIAT. If not, see <http://www.gnu.org/licenses/>.
+# along with fiat. If not, see <http://www.gnu.org/licenses/>.
 #
-# First added:  2010-01-31
-# Last changed: 2014-06-30
-
-import nose
-import sys
-import json
-import numpy
-
-from FIAT import supported_elements, make_quadrature, ufc_simplex, \
-    newdubiner, expansions, reference_element, polynomial_set
-
-# Parameters
-tolerance = 1e-8
-
-
-class NumpyEncoder(json.JSONEncoder):
-    def default(self, obj):
-        # If numpy array, convert it to a list and store it in a dict.
-        if isinstance(obj, numpy.ndarray):
-            data = obj.tolist()
-            return dict(__ndarray__=data,
-                        dtype=str(obj.dtype),
-                        shape=obj.shape)
-        # Let the base class default method raise the TypeError
-        return json.JSONEncoder(self, obj)
-
-
-def json_numpy_obj_hook(dct):
-    # If dict and have '__ndarray__' as a key, convert it back to ndarray.
-    if isinstance(dct, dict) and '__ndarray__' in dct:
-        return numpy.asarray(dct['__ndarray__']).reshape(dct['shape'])
-    return dct
-
-
-def test_polynomials():
-    def create_data():
-        ps = polynomial_set.ONPolynomialSet(
-            ref_el=reference_element.DefaultTetrahedron(),
-            degree=3
-            )
-        return ps.dmats
-
-    # Try reading reference values
-    filename = "reference-polynomials.json"
-    try:
-        reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
-    except IOError:
-        reference = create_data()
-        # Store the data for the future
-        json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
-
-    dmats = create_data()
-
-    for dmat, reference_dmat in zip(dmats, reference):
-        assert (abs(dmat - reference_dmat) < tolerance).all()
-    return
-
-def test_polynomials_1D():
-    def create_data():
-        ps = polynomial_set.ONPolynomialSet(
-            ref_el=reference_element.DefaultLine(),
-            degree=3
-            )
-        return ps.dmats
-
-    # Try reading reference values
-    filename = "reference-polynomials_1D.json"
-    try:
-        reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
-    except IOError:
-        reference = create_data()
-        # Store the data for the future
-        json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
-
-    dmats = create_data()
-
-    for dmat, reference_dmat in zip(dmats, reference):
-        assert (abs(dmat - reference_dmat) < tolerance).all()
-    return
-
-
-def test_expansions():
-    def create_data():
-        E = reference_element.DefaultTriangle()
-        k = 3
-        pts = E.make_lattice(k)
-        Phis = expansions.get_expansion_set(E)
-        phis = Phis.tabulate(k, pts)
-        dphis = Phis.tabulate_derivatives(k, pts)
-        return phis, dphis
-
-    # Try reading reference values
-    filename = "reference-expansions.json"
-    try:
-        reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
-    except IOError:
-        reference = create_data()
-        # Convert reference to list of int
-        json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
-
-    table_phi, table_dphi = create_data()
-    reference_table_phi, reference_table_dphi = reference
-
-    # Test raw point data
-    diff = numpy.array(table_phi) - numpy.array(reference_table_phi)
-    assert (abs(diff) < tolerance).all()
-
-    # Test derivative values
-    for entry, reference_entry in zip(table_dphi, reference_table_dphi):
-        for point, reference_point in zip(entry, reference_entry):
-            value, gradient = point[0], point[1]
-            reference_value, reference_gradient = \
-                reference_point[0], reference_point[1]
-            assert abs(value - reference_value) < tolerance
-            diff = numpy.array(gradient) - numpy.array(reference_gradient)
-            assert (abs(diff) < tolerance).all()
-    return
-
-
-def test_expansions_jet():
-    def create_data():
-        latticeK = 2
-        n = 1
-        order = 2
-        E = reference_element.DefaultTetrahedron()
-        pts = E.make_lattice(latticeK)
-        F = expansions.TetrahedronExpansionSet(E)
-        return F.tabulate_jet(n, pts, order)
-
-    filename = "reference-expansions-jet.json"
-    try:
-        reference_jet = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
-    except IOError:
-        reference_jet = create_data()
-        # Store the data for the future
-        json.dump(reference_jet, open(filename, "w"), cls=NumpyEncoder)
-
-    # Test jet data
-    data = create_data()
-    reference_data = reference_jet
-    for datum, reference_datum in zip(data, reference_data):
-        diff = numpy.array(datum) - numpy.array(reference_datum)
-        assert (abs(diff) < tolerance).all()
-
-    return
-
-
-def test_newdubiner():
-    def create_data():
-        latticeK = 2
-        D = 3
-        pts = newdubiner.make_tetrahedron_lattice(latticeK, float)
-        return newdubiner.tabulate_tetrahedron_derivatives(D, pts, float)
-
-    # Try reading reference values
-    filename = "reference-newdubiner.json"
-    try:
-        reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
-    except IOError:
-        reference = create_data()
-        # Convert reference to list of int
-        json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
-
-    # Actually perform the test
-    table = create_data()
-
-    for data, reference_data in zip(table, reference):
-        for point, reference_point in zip(data, reference_data):
-            for k in range(2):
-                diff = numpy.array(point[k]) - numpy.array(reference_point[k])
-                assert (abs(diff) < tolerance).all()
-    return
-
-
-def test_newdubiner_jet():
-    def create_data():
-        latticeK = 2
-        D = 3
-        n = 1
-        order = 2
-        pts = newdubiner.make_tetrahedron_lattice(latticeK, float)
-        return newdubiner.tabulate_jet(D, n, pts, order, float)
-
-    filename = "reference-newdubiner-jet.json"
-    try:
-        reference_jet = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
-    except IOError:
-        reference_jet = create_data()
-        # Store the data for the future
-        json.dump(reference_jet, open(filename, "w"), cls=NumpyEncoder)
-
-    table_jet = create_data()
-    for datum, reference_datum in zip(table_jet, reference_jet):
-        for entry, reference_entry in zip(datum, reference_datum):
-            for k in range(3):
-                diff = numpy.array(entry[k]) - numpy.array(reference_entry[k])
-                assert (abs(diff) < tolerance).all()
-
-    return
-
-
-def test_quadrature():
-    num_points = 3
-    max_derivative = 3
-    # Combinations of (family, dim, degree) to test
-    test_cases = (
-        ("Lagrange", 2, 1),
-        ("Lagrange", 2, 2),
-        ("Lagrange", 2, 3),
-        ("Lagrange", 3, 1),
-        ("Lagrange", 3, 2),
-        ("Lagrange", 3, 3),
-        ("Discontinuous Lagrange", 2, 0),
-        ("Discontinuous Lagrange", 2, 1),
-        ("Discontinuous Lagrange", 2, 2),
-        ("Discontinuous Lagrange", 3, 0),
-        ("Discontinuous Lagrange", 3, 1),
-        ("Discontinuous Lagrange", 3, 2),
-        ("Brezzi-Douglas-Marini", 2, 1),
-        ("Brezzi-Douglas-Marini", 2, 2),
-        ("Brezzi-Douglas-Marini", 2, 3),
-        ("Brezzi-Douglas-Marini", 3, 1),
-        ("Brezzi-Douglas-Marini", 3, 2),
-        ("Brezzi-Douglas-Marini", 3, 3),
-        ("Brezzi-Douglas-Fortin-Marini", 2, 2),
-        ("Raviart-Thomas", 2, 1),
-        ("Raviart-Thomas", 2, 2),
-        ("Raviart-Thomas", 2, 3),
-        ("Raviart-Thomas", 3, 1),
-        ("Raviart-Thomas", 3, 2),
-        ("Raviart-Thomas", 3, 3),
-        ("Discontinuous Raviart-Thomas", 2, 1),
-        ("Discontinuous Raviart-Thomas", 2, 2),
-        ("Discontinuous Raviart-Thomas", 2, 3),
-        ("Discontinuous Raviart-Thomas", 3, 1),
-        ("Discontinuous Raviart-Thomas", 3, 2),
-        ("Discontinuous Raviart-Thomas", 3, 3),
-        ("Nedelec 1st kind H(curl)", 2, 1),
-        ("Nedelec 1st kind H(curl)", 2, 2),
-        ("Nedelec 1st kind H(curl)", 2, 3),
-        ("Nedelec 1st kind H(curl)", 3, 1),
-        ("Nedelec 1st kind H(curl)", 3, 2),
-        ("Nedelec 1st kind H(curl)", 3, 3),
-        ("Nedelec 2nd kind H(curl)", 2, 1),
-        ("Nedelec 2nd kind H(curl)", 2, 2),
-        ("Nedelec 2nd kind H(curl)", 2, 3),
-        ("Nedelec 2nd kind H(curl)", 3, 1),
-        ("Nedelec 2nd kind H(curl)", 3, 2),
-        ("Nedelec 2nd kind H(curl)", 3, 3),
-        ("Crouzeix-Raviart", 2, 1),
-        ("Crouzeix-Raviart", 3, 1),
-        ("Regge", 2, 0),        
-        ("Regge", 2, 1),
-        ("Regge", 2, 2),
-        ("Regge", 3, 0),        
-        ("Regge", 3, 1),
-        ("Regge", 3, 2)
-        )
-
-    def create_data(family, dim, degree):
-        '''Create the reference data.
-        '''
-        # Get domain and element class
-        domain = ufc_simplex(dim)
-        ElementClass = supported_elements[family]
-        # Create element|
-        element = ElementClass(domain, degree)
-        # Create quadrature points
-        quad_rule = make_quadrature(domain, num_points)
-        points = quad_rule.get_points()
-        # Tabulate at quadrature points
-        table = element.tabulate(max_derivative, points)
-        return table
-
-    def _perform_test(family, dim, degree, reference_table):
-        '''Test against reference data.
-        '''
-        table = create_data(family, dim, degree)
-        # Check against reference
-        for dtuple in reference_table:
-            assert eval(dtuple) in table
-            assert table[eval(dtuple)].shape == reference_table[dtuple].shape
-            diff = table[eval(dtuple)] - reference_table[dtuple]
-            assert (abs(diff) < tolerance).all()
-        return
-
-    # Try reading reference values
-    filename = "reference.json"
-
-    try:
-        reference = json.load(open(filename, "r"), object_hook=json_numpy_obj_hook)
-    except IOError:
-        reference = {}
-        for test_case in test_cases:
-            family, dim, degree = test_case
-            ref = dict([(str(k), v) for k, v in create_data(family, dim, degree).items()])
-            reference[str(test_case)] = ref
-        # Store the data for the future
-        json.dump(reference, open(filename, "w"), cls=NumpyEncoder)
-
-    for test_case in test_cases:
-        family, dim, degree = test_case
-        yield _perform_test, family, dim, degree, reference[str(test_case)]
-
-
-if __name__ == "__main__":
-    nose.main()
+# First added:  2007-06-09
+# Last changed: 2014-05-15
+
+import os, sys
+
+# Name of log file
+pwd = os.path.dirname(os.path.abspath(__file__))
+logfile = os.path.join(pwd, "test.log")
+os.system("rm -f %s" % logfile)
+
+# Tests to run
+tests = ["unit", "regression"]
+
+# Run tests
+failed = []
+for test in tests:
+    print("Running tests: %s" % test)
+    print("----------------------------------------------------------------------")
+    os.chdir(os.path.join(pwd, test))
+    #failure = os.system("python test.py | tee -a %s" % logfile)
+    failure = os.system("python test.py")
+    if failure:
+        print("Test FAILED")
+        failed.append(test)
+    print("")
+
+#print("To view the test log, use the following command: less -R test.log")
+
+sys.exit(len(failed))
diff --git a/test/unit/test.py b/test/unit/test.py
new file mode 100644
index 0000000..7b962d7
--- /dev/null
+++ b/test/unit/test.py
@@ -0,0 +1,66 @@
+# Copyright (C) 2015 Jan Blechta
+#
+# This file is part of FIAT.
+#
+# FIAT is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# FIAT is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with FIAT. If not, see <http://www.gnu.org/licenses/>.
+
+import nose
+import numpy
+
+
+def test_basis_derivatives_scaling():
+    import random
+    from FIAT.reference_element import LINE, ReferenceElement
+    from FIAT.lagrange import Lagrange
+
+    class Interval(ReferenceElement):
+        def __init__(self, a, b):
+            verts = ( (a,), (b,) )
+            edges = { 0 : ( 0, 1 ) }
+            topology = { 0 : { 0 : (0,) , 1: (1,) } , \
+                         1 : edges }
+            ReferenceElement.__init__( self, LINE, verts, topology )
+
+    random.seed(42)
+    for i in range(26):
+        a = 1000.0*(random.random() - 0.5)
+        b = 1000.0*(random.random() - 0.5)
+        a, b = min(a, b), max(a, b)
+
+        interval = Interval(a, b)
+        element = Lagrange(interval, 1)
+
+        points = [(a,), (0.5*(a+b),), (b,)]
+        tab = element.get_nodal_basis().tabulate(points, 2)
+
+        # first basis function
+        nose.tools.assert_almost_equal(tab[(0,)][0][0], 1.0)
+        nose.tools.assert_almost_equal(tab[(0,)][0][1], 0.5)
+        nose.tools.assert_almost_equal(tab[(0,)][0][2], 0.0)
+        # second basis function
+        nose.tools.assert_almost_equal(tab[(0,)][1][0], 0.0)
+        nose.tools.assert_almost_equal(tab[(0,)][1][1], 0.5)
+        nose.tools.assert_almost_equal(tab[(0,)][1][2], 1.0)
+
+        # first and second derivatives
+        D = 1.0 / (b - a)
+        for p in range(len(points)):
+            nose.tools.assert_almost_equal(tab[(1,)][0][p], -D)
+            nose.tools.assert_almost_equal(tab[(1,)][1][p], +D)
+            nose.tools.assert_almost_equal(tab[(2,)][0][p], 0.0)
+            nose.tools.assert_almost_equal(tab[(2,)][1][p], 0.0)
+
+
+if __name__ == "__main__":
+    nose.main()

-- 
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