Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion FIAT/restricted.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,40 @@ def __init__(self, dual, indices):
for dof in dofs if dof in indices]
nodes = [nodes_old[i] for i in indices]
self._dual = dual
entity_permutations = self._restrict_entity_permutations(dual, entity_ids)

super().__init__(nodes, ref_el, entity_ids)
super().__init__(nodes, ref_el, entity_ids, entity_permutations)

@staticmethod
def _restrict_entity_permutations(dual, entity_ids):
"""Inherit the entity permutations of the dofs kept by the restriction.

An entity whose dofs are all kept keeps their relative order, and so
permutes exactly as it did in ``dual``; an entity whose dofs are all
dropped permutes trivially. An entity that keeps only some of its dofs
has no permutation to inherit, since the dofs it drops may be the ones
the parent permutation maps the others onto, so no permutations are
given at all in that case.

:arg dual: the DualSet being restricted.
:arg entity_ids: the entity ids of the restricted dual set.
:returns: the entity permutations, or None if they cannot be inherited.
"""
permutations_old = dual.entity_permutations
if permutations_old is None:
return None
entity_permutations = {}
for d, entities in dual.get_entity_ids().items():
entity_permutations[d] = {}
for entity, dofs in entities.items():
perms = permutations_old[d][entity]
if len(entity_ids[d][entity]) == len(dofs):
entity_permutations[d][entity] = {o: list(p) for o, p in perms.items()}
elif len(entity_ids[d][entity]) == 0:
entity_permutations[d][entity] = {o: [] for o in perms}
else:
return None
return entity_permutations

def get_indices(self, restriction_domain, take_closure=True):
"""Return the list of dofs with support on a given restriction domain.
Expand Down
31 changes: 31 additions & 0 deletions test/FIAT/unit/test_orientation.py
Comment thread
connorjward marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from FIAT import DiscontinuousLagrange, Lagrange, RestrictedElement
from FIAT.reference_element import Point, UFCInterval, UFCTriangle, UFCQuadrilateral
from FIAT.orientation_utils import make_entity_permutations_tensorproduct

Expand Down Expand Up @@ -69,3 +70,33 @@ def test_orientation_cell_orientation_reflection_map(cell):
(1, 0, 1): 0,
(1, 1, 0): 0,
(1, 1, 1): 1}


@pytest.mark.parametrize("degree", [1, 2, 3, 4, 5])
def test_orientation_restricted_element(degree):
# A restriction keeps the relative order of the dofs on the entities it
# keeps, so those entities must permute exactly as they did before it.
element = Lagrange(UFCTriangle(), degree)
restricted = RestrictedElement(element, restriction_domain="facet")

permutations = element.dual.get_entity_permutations()
restricted_permutations = restricted.dual.get_entity_permutations()

for dim in (0, 1):
for entity in permutations[dim]:
assert restricted_permutations[dim][entity] == permutations[dim][entity]
# The cell is dropped, so it has no dofs left to permute.
for orientation, perm in restricted_permutations[2][0].items():
assert perm == []


def test_orientation_restricted_element_partial_entity():
# An entity that keeps only some of its dofs has no permutation to
# inherit, since the dofs it drops may be where the parent permutation
# sends the ones it keeps, so no permutations are reported at all.
element = DiscontinuousLagrange(UFCTriangle(), 1)
restricted = RestrictedElement(element, indices=[0])

assert restricted.dual.entity_permutations is None
with pytest.raises(NotImplementedError):
restricted.dual.get_entity_permutations()
Loading