[fiat] 01/01: New upstream version 2017.2.0.0
Drew Parsons
dparsons at moszumanska.debian.org
Fri Jan 19 15:53:29 UTC 2018
This is an automated email from the git hooks/post-receive script.
dparsons pushed a commit to annotated tag upstream/2017.2.0.0
in repository fiat.
commit 64926666e24980325d4f5522de527be37fe3075f
Author: Drew Parsons <dparsons at debian.org>
Date: Fri Jan 19 23:40:39 2018 +0800
New upstream version 2017.2.0.0
---
.circleci/config.yml | 20 ++++++++
FIAT/dual_set.py | 1 +
FIAT/gauss_legendre.py | 4 +-
FIAT/gauss_lobatto_legendre.py | 4 +-
FIAT/hdiv_trace.py | 4 ++
FIAT/reference_element.py | 24 ++++++++++
README.rst | 4 +-
doc/sphinx/source/releases.rst | 1 +
doc/sphinx/source/releases/v2017.2.0.rst | 2 +-
test/unit/test_fiat.py | 78 +++++++++++++++++++++++++++++---
test/unit/test_reference_element.py | 48 ++++++++++++++++++++
11 files changed, 176 insertions(+), 14 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..2fffb99
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,20 @@
+version: 2
+jobs:
+ build:
+ docker:
+ - image: circleci/python:3.6
+ working_directory: ~/fiat-test
+ steps:
+ - checkout
+ - run:
+ name: Install dependencies # Install with sudo as tests not run as superuser in circleci/python
+ command: sudo pip install flake8 pytest six numpy sympy --upgrade
+ - run:
+ name: Install FIAT
+ command: pip install . --user
+ - run:
+ name: Run flake8 tests
+ command: python -m flake8 .
+ - run:
+ name: Run unit tests
+ command: DATA_REPO_GIT="" python -m pytest -v test/
diff --git a/FIAT/dual_set.py b/FIAT/dual_set.py
index 13b268e..577baad 100644
--- a/FIAT/dual_set.py
+++ b/FIAT/dual_set.py
@@ -37,6 +37,7 @@ class DualSet(object):
for d, se in sub_entities:
ids += self.entity_ids[d][se]
+ ids.sort()
self.entity_closure_ids[d][e] = ids
def get_nodes(self):
diff --git a/FIAT/gauss_legendre.py b/FIAT/gauss_legendre.py
index ae0272a..42b39aa 100644
--- a/FIAT/gauss_legendre.py
+++ b/FIAT/gauss_legendre.py
@@ -28,8 +28,8 @@ class GaussLegendreDualSet(dual_set.DualSet):
def __init__(self, ref_el, degree):
entity_ids = {0: {0: [], 1: []},
1: {0: list(range(0, degree+1))}}
- l = quadrature.GaussLegendreQuadratureLineRule(ref_el, degree+1)
- nodes = [functional.PointEvaluation(ref_el, x) for x in l.pts]
+ lr = quadrature.GaussLegendreQuadratureLineRule(ref_el, degree+1)
+ nodes = [functional.PointEvaluation(ref_el, x) for x in lr.pts]
super(GaussLegendreDualSet, self).__init__(nodes, ref_el, entity_ids)
diff --git a/FIAT/gauss_lobatto_legendre.py b/FIAT/gauss_lobatto_legendre.py
index ecbe015..b8fd6af 100644
--- a/FIAT/gauss_lobatto_legendre.py
+++ b/FIAT/gauss_lobatto_legendre.py
@@ -29,8 +29,8 @@ class GaussLobattoLegendreDualSet(dual_set.DualSet):
def __init__(self, ref_el, degree):
entity_ids = {0: {0: [0], 1: [degree]},
1: {0: list(range(1, degree))}}
- l = quadrature.GaussLobattoLegendreQuadratureLineRule(ref_el, degree+1)
- nodes = [functional.PointEvaluation(ref_el, x) for x in l.pts]
+ lr = quadrature.GaussLobattoLegendreQuadratureLineRule(ref_el, degree+1)
+ nodes = [functional.PointEvaluation(ref_el, x) for x in lr.pts]
super(GaussLobattoLegendreDualSet, self).__init__(nodes, ref_el, entity_ids)
diff --git a/FIAT/hdiv_trace.py b/FIAT/hdiv_trace.py
index a59e051..af5b375 100644
--- a/FIAT/hdiv_trace.py
+++ b/FIAT/hdiv_trace.py
@@ -275,6 +275,10 @@ class HDivTrace(FiniteElement):
"""Return number of members of the expansion set."""
raise NotImplementedError("get_num_members not implemented for the trace element.")
+ @staticmethod
+ def is_nodal():
+ return True
+
def construct_dg_element(ref_el, degree):
"""Constructs a discontinuous galerkin element of a given degree
diff --git a/FIAT/reference_element.py b/FIAT/reference_element.py
index 786c671..412936f 100644
--- a/FIAT/reference_element.py
+++ b/FIAT/reference_element.py
@@ -130,8 +130,24 @@ class Cell(object):
if vertices.issuperset(vertices_):
sub_entities.append((dim_, e_))
+ # Sort for the sake of determinism and by UFC conventions
self.sub_entities[dim][e] = sorted(sub_entities)
+ # Build connectivity dictionary for easier queries
+ self.connectivity = {}
+ for dim0, sub_entities in iteritems(self.sub_entities):
+
+ # Skip tensor product entities
+ # TODO: Can we do something better?
+ if isinstance(dim0, tuple):
+ continue
+
+ for entity, sub_sub_entities in sorted(iteritems(sub_entities)):
+ for dim1 in range(dim0+1):
+ d01_entities = filter(lambda x: x[0] == dim1, sub_sub_entities)
+ d01_entities = tuple(x[1] for x in d01_entities)
+ self.connectivity.setdefault((dim0, dim1), []).append(d01_entities)
+
def _key(self):
"""Hashable object key data (excluding type)."""
# Default: only type matters
@@ -166,6 +182,14 @@ class Cell(object):
and each value is a dictionary mapping."""
return self.topology
+ def get_connectivity(self):
+ """Returns a dictionary encoding the connectivity of the element.
+
+ The dictionary's keys are the spatial dimensions pairs ((1, 0),
+ (2, 0), (2, 1), ...) and each value is a list with entities
+ of second dimension ordered by local dim0-dim1 numbering."""
+ return self.connectivity
+
def get_vertices_of_subcomplex(self, t):
"""Returns the tuple of vertex coordinates associated with the labels
contained in the iterable t."""
diff --git a/README.rst b/README.rst
index 6014d29..9853fd1 100644
--- a/README.rst
+++ b/README.rst
@@ -36,8 +36,8 @@ testing.
:target: https://bitbucket.org/fenics-project/fiat/addon/pipelines/home
:alt: Pipelines Build Status
-.. image:: http://fenics-bamboo.simula.no:8085/plugins/servlet/wittified/build-status/FIAT-FD
- :target: http://fenics-bamboo.simula.no:8085/browse/FIAT-FD/latest
+.. image:: http://magpie.bpi.cam.ac.uk:8085/plugins/servlet/wittified/build-status/FIAT-FD
+ :target: http://magpie.bpi.cam.ac.uk:8085/browse/FIAT-FD
:alt: Bamboo Build Status
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/v2017.2.0.rst b/doc/sphinx/source/releases/v2017.2.0.rst
index 62eb734..a7111bb 100644
--- a/doc/sphinx/source/releases/v2017.2.0.rst
+++ b/doc/sphinx/source/releases/v2017.2.0.rst
@@ -2,7 +2,7 @@
Changes in version 2017.2.0
===========================
-FIAT 2017.2.0 was released on 2017-09-19.
+FIAT 2017.2.0 was released on 2017-11-30.
Summary of changes
==================
diff --git a/test/unit/test_fiat.py b/test/unit/test_fiat.py
index 9c53af8..6deac7a 100644
--- a/test/unit/test_fiat.py
+++ b/test/unit/test_fiat.py
@@ -35,7 +35,7 @@ from FIAT.mixed import MixedElement
from FIAT.nedelec import Nedelec # noqa: F401
from FIAT.nedelec_second_kind import NedelecSecondKind # noqa: F401
from FIAT.regge import Regge # noqa: F401
-from FIAT.hdiv_trace import HDivTrace # noqa: F401
+from FIAT.hdiv_trace import HDivTrace, map_to_reference_facet # noqa: F401
from FIAT.hellan_herrmann_johnson import HellanHerrmannJohnson # noqa: F401
from FIAT.brezzi_douglas_fortin_marini import BrezziDouglasFortinMarini # noqa: F401
from FIAT.gauss_legendre import GaussLegendre # noqa: F401
@@ -52,7 +52,7 @@ from FIAT.enriched import EnrichedElement # noqa: F401
from FIAT.nodal_enriched import NodalEnrichedElement
-I = UFCInterval()
+I = UFCInterval() # noqa: E741
T = UFCTriangle()
S = UFCTetrahedron()
@@ -226,6 +226,14 @@ elements = [
"Hcurl(TensorProductElement(DiscontinuousLagrange(I, 0), Lagrange(I, 1)))"
")"),
# Following elements are checked using tabulate
+ xfail_impl("HDivTrace(T, 0)"),
+ xfail_impl("HDivTrace(T, 1)"),
+ xfail_impl("HDivTrace(T, 2)"),
+ xfail_impl("HDivTrace(T, 3)"),
+ xfail_impl("HDivTrace(S, 0)"),
+ xfail_impl("HDivTrace(S, 1)"),
+ xfail_impl("HDivTrace(S, 2)"),
+ xfail_impl("HDivTrace(S, 3)"),
xfail_impl("TensorProductElement(Lagrange(I, 1), Lagrange(I, 1))"),
xfail_impl("TensorProductElement(Lagrange(I, 2), Lagrange(I, 2))"),
xfail_impl("TensorProductElement(TensorProductElement(Lagrange(I, 1), Lagrange(I, 1)), Lagrange(I, 1))"),
@@ -347,24 +355,80 @@ def test_mixed_is_not_nodal():
"FlattenedDimensions(TensorProductElement(FlattenedDimensions(TensorProductElement(Lagrange(I, 1), Lagrange(I, 1))), Lagrange(I, 1)))",
"FlattenedDimensions(TensorProductElement(FlattenedDimensions(TensorProductElement(Lagrange(I, 2), Lagrange(I, 2))), Lagrange(I, 2)))",
])
-def test_nodality_tpe(element):
- """Check that generated TensorProductElements are nodal, i.e. nodes evaluated
- on basis functions give Kronecker delta
+def test_nodality_tabulate(element):
+ """Check that certain elements (which do no implement
+ get_nodal_basis) are nodal too, by tabulating at nodes
+ (assuming nodes are point evaluation)
"""
# Instantiate element
element = eval(element)
# Get nodes coordinates
- nodes_coord = list(next(iter(f.get_point_dict().keys())) for f in element.dual_basis())
+ nodes_coords = []
+ for node in element.dual_basis():
+ # Assume point evaluation
+ (coords, weights), = node.get_point_dict().items()
+ assert weights == [(1.0, ())]
+
+ nodes_coords.append(coords)
# Check nodality
- for j, x in enumerate(nodes_coord):
+ for j, x in enumerate(nodes_coords):
table = element.tabulate(0, (x,))
basis = table[list(table.keys())[0]]
for i in range(len(basis)):
assert np.isclose(basis[i], 1.0 if i == j else 0.0)
+ at pytest.mark.parametrize('element', [
+ "HDivTrace(T, 0)",
+ "HDivTrace(T, 1)",
+ "HDivTrace(T, 2)",
+ "HDivTrace(T, 3)",
+ "HDivTrace(S, 0)",
+ "HDivTrace(S, 1)",
+ "HDivTrace(S, 2)",
+ "HDivTrace(S, 3)",
+])
+def test_facet_nodality_tabulate(element):
+ """Check that certain elements (which do no implement get_nodal_basis)
+ are nodal too, by tabulating facet-wise at nodes (assuming nodes
+ are point evaluation)
+ """
+ # Instantiate element
+ element = eval(element)
+
+ # Dof/Node coordinates and respective facet
+ nodes_coords = []
+
+ # Iterate over facet degrees of freedom
+ entity_dofs = element.dual.entity_ids
+ facet_dim = sorted(entity_dofs.keys())[-2]
+ facet_dofs = entity_dofs[facet_dim]
+ dofs = element.dual_basis()
+ vertices = element.ref_el.vertices
+
+ for (facet, indices) in facet_dofs.items():
+ for i in indices:
+ node = dofs[i]
+ # Assume point evaluation
+ (coords, weights), = node.get_point_dict().items()
+ assert weights == [(1.0, ())]
+
+ # Map dof coordinates to reference element due to
+ # HdivTrace interface peculiarity
+ ref_coords = map_to_reference_facet((coords,), vertices, facet)
+ assert len(ref_coords) == 1
+ nodes_coords.append((facet, ref_coords[0]))
+
+ # Check nodality
+ for j, (facet, x) in enumerate(nodes_coords):
+ table = element.tabulate(0, (x,), entity=(facet_dim, facet))
+ basis = table[list(table.keys())[0]]
+ for i in range(len(basis)):
+ assert np.isclose(basis[i], 1.0 if i == j else 0.0)
+
+
if __name__ == '__main__':
import os
pytest.main(os.path.abspath(__file__))
diff --git a/test/unit/test_reference_element.py b/test/unit/test_reference_element.py
index 56501a2..b9b6b9c 100644
--- a/test/unit/test_reference_element.py
+++ b/test/unit/test_reference_element.py
@@ -19,6 +19,8 @@ from __future__ import absolute_import, print_function, division
import pytest
import numpy as np
+import six
+from six.moves import range
from FIAT.reference_element import UFCInterval, UFCTriangle, UFCTetrahedron
from FIAT.reference_element import Point, TensorProductCell, UFCQuadrilateral, UFCHexahedron
@@ -33,6 +35,52 @@ interval_x_interval = TensorProductCell(interval, interval)
triangle_x_interval = TensorProductCell(triangle, interval)
quadrilateral_x_interval = TensorProductCell(quadrilateral, interval)
+ufc_tetrahedron_21connectivity = [(0, 1, 2), (0, 3, 4), (1, 3, 5), (2, 4, 5)]
+ufc_hexahedron_21connectivity = [(0, 1, 4, 5), (2, 3, 6, 7), (0, 2, 8, 9),
+ (1, 3, 10, 11), (4, 6, 8, 10), (5, 7, 9, 11)]
+
+
+ at pytest.mark.parametrize(('cell', 'connectivity'),
+ [(tetrahedron, ufc_tetrahedron_21connectivity),
+ (hexahedron, ufc_hexahedron_21connectivity),
+ pytest.mark.xfail((triangle_x_interval, [])),
+ pytest.mark.xfail((quadrilateral_x_interval, []))])
+def test_ufc_connectivity_21(cell, connectivity):
+ """Check face-edge connectivity builds what UFC expects.
+ This is only non-trivial case ; the rest is x-0 and D-x,
+ see below."""
+ assert cell.get_connectivity()[(2, 1)] == connectivity
+
+
+ at pytest.mark.parametrize('cell',
+ [point, interval, triangle, tetrahedron,
+ quadrilateral, hexahedron,
+ pytest.mark.xfail(interval_x_interval),
+ pytest.mark.xfail(triangle_x_interval),
+ pytest.mark.xfail(quadrilateral_x_interval)])
+def test_ufc_connectivity_x0(cell):
+ """Check x-0 connectivity is just what get_topology gives"""
+ for dim0 in range(cell.get_spatial_dimension()+1):
+ connectivity = cell.get_connectivity()[(dim0, 0)]
+ topology = cell.get_topology()[dim0]
+ assert len(connectivity) == len(topology)
+ assert all(connectivity[i] == t for i, t in six.iteritems(topology))
+
+
+ at pytest.mark.parametrize('cell',
+ [point, interval, triangle, tetrahedron,
+ quadrilateral, hexahedron,
+ pytest.mark.xfail(interval_x_interval),
+ pytest.mark.xfail(triangle_x_interval),
+ pytest.mark.xfail(quadrilateral_x_interval)])
+def test_ufc_connectivity_Dx(cell):
+ """Check D-x connectivity is just [(0,1,2,...)]"""
+ D = cell.get_spatial_dimension()
+ for dim1 in range(D+1):
+ connectivity = cell.get_connectivity()[(D, dim1)]
+ assert len(connectivity) == 1
+ assert connectivity[0] == tuple(range(len(connectivity[0])))
+
@pytest.mark.parametrize(('cell', 'volume'),
[pytest.mark.xfail((point, 1)),
--
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