[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