Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update element interface #365

Merged
merged 14 commits into from
Jun 23, 2021
2 changes: 1 addition & 1 deletion .github/workflows/dolfin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
with:
path: ./dolfinx
repository: FEniCS/dolfinx
ref: main
ref: mscrogs/entity_dofs
- name: Clone and install DOLFINx
run: |
cmake -G Ninja -DCMAKE_BUILD_TYPE=Developer -B build -S dolfinx/cpp/
Expand Down
4 changes: 2 additions & 2 deletions ffcx/codegeneration/access.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def cell_vertices(self, e, mt, tabledata, num_points):
assert ufl_scalar_element.family() in ("Lagrange", "Q", "S")

basix_scalar_element = create_element(ufl_scalar_element)
vertex_scalar_dofs = basix_scalar_element.entity_dof_numbers[0]
vertex_scalar_dofs = basix_scalar_element.entity_dofs[0]
num_scalar_dofs = basix_scalar_element.dim

# Get dof and component
Expand Down Expand Up @@ -293,7 +293,7 @@ def cell_edge_vectors(self, e, mt, tabledata, num_points):
assert ufl_scalar_element.family() in ("Lagrange", "Q", "S")

basix_scalar_element = create_element(ufl_scalar_element)
vertex_scalar_dofs = basix_scalar_element.entity_dof_numbers[0]
vertex_scalar_dofs = basix_scalar_element.entity_dofs[0]
num_scalar_dofs = basix_scalar_element.dim

# Get edge vertices
Expand Down
46 changes: 18 additions & 28 deletions ffcx/element_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ def value_shape(self):
raise NotImplementedError

@property
def entity_dofs(self):
def num_entity_dofs(self):
"""Get the number of DOFs associated with each entity."""
raise NotImplementedError

@property
def entity_dof_numbers(self):
def entity_dofs(self):
"""Get the DOF numbers associated with each entity."""
raise NotImplementedError

Expand Down Expand Up @@ -232,23 +232,14 @@ def value_shape(self):
return self.element.value_shape

@property
def entity_dofs(self):
def num_entity_dofs(self):
"""Get the number of DOFs associated with each entity."""
return self.element.entity_dofs
return self.element.num_entity_dofs

@property
def entity_dof_numbers(self):
def entity_dofs(self):
"""Get the DOF numbers associated with each entity."""
# TODO: move this to basix, then remove this wrapper class
start_dof = 0
entity_dofs = []
for i in self.entity_dofs:
dofs_list = []
for j in i:
dofs_list.append([start_dof + k for k in range(j)])
start_dof += j
entity_dofs.append(dofs_list)
return entity_dofs
return self.element.entity_dofs

@property
def num_global_support_dofs(self):
Expand Down Expand Up @@ -412,19 +403,19 @@ def value_shape(self):
return (sum(e.value_size for e in self.sub_elements), )

@property
def entity_dofs(self):
def num_entity_dofs(self):
"""Get the number of DOFs associated with each entity."""
data = [e.entity_dofs for e in self.sub_elements]
data = [e.num_entity_dofs for e in self.sub_elements]
return [[sum(d[tdim][entity_n] for d in data) for entity_n, _ in enumerate(entities)]
for tdim, entities in enumerate(data[0])]

@property
def entity_dof_numbers(self):
def entity_dofs(self):
"""Get the DOF numbers associated with each entity."""
dofs = [[[] for i in entities] for entities in self.sub_elements[0].entity_dof_numbers]
dofs = [[[] for i in entities] for entities in self.sub_elements[0].entity_dofs]
start_dof = 0
for e in self.sub_elements:
for tdim, entities in enumerate(e.entity_dof_numbers):
for tdim, entities in enumerate(e.entity_dofs):
for entity_n, entity_dofs in enumerate(entities):
dofs[tdim][entity_n] += [start_dof + i for i in entity_dofs]
start_dof += e.dim
Expand Down Expand Up @@ -528,16 +519,16 @@ def value_shape(self):
return (self.value_size, )

@property
def entity_dofs(self):
def num_entity_dofs(self):
"""Get the number of DOFs associated with each entity."""
return [[j * self.block_size for j in i] for i in self.sub_element.entity_dofs]
return [[j * self.block_size for j in i] for i in self.sub_element.num_entity_dofs]

@property
def entity_dof_numbers(self):
def entity_dofs(self):
"""Get the DOF numbers associated with each entity."""
# TODO: should this return this, or should it take blocks into account?
return [[[k * self.block_size + b for k in j for b in range(self.block_size)]
for j in i] for i in self.sub_element.entity_dof_numbers]
for j in i] for i in self.sub_element.entity_dofs]

@property
def num_global_support_dofs(self):
Expand Down Expand Up @@ -626,7 +617,7 @@ def value_shape(self):
return [1]

@property
def entity_dofs(self):
def num_entity_dofs(self):
"""Get the number of DOFs associated with each entity."""
dofs = []
tdim = self._ufl_element.cell().topological_dimension()
Expand All @@ -644,12 +635,11 @@ def entity_dofs(self):
return dofs

@property
def entity_dof_numbers(self):
def entity_dofs(self):
"""Get the DOF numbers associated with each entity."""
# TODO: move this to basix, then remove this wrapper class
start_dof = 0
entity_dofs = []
for i in self.entity_dofs:
for i in self.num_entity_dofs:
dofs_list = []
for j in i:
dofs_list.append([start_dof + k for k in range(j)])
Expand Down
10 changes: 6 additions & 4 deletions ffcx/ir/representation.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def _compute_element_ir(ufl_element, element_numbers, finite_element_names):
else:
ir["block_size"] = 1

ir["entity_dofs"] = basix_element.entity_dof_numbers
ir["entity_dofs"] = basix_element.entity_dofs

return ir_element(**ir)

Expand Down Expand Up @@ -171,14 +171,16 @@ def _compute_dofmap_ir(ufl_element, element_numbers, dofmap_names):
ir["block_size"] = 1

# Precompute repeatedly used items
for i in basix_element.entity_dofs:
for i in basix_element.num_entity_dofs:
# FIXME: this assumes the same number of DOFs on each entity of the same dim: this
# assumption will not be true for prisms and pyramids
if max(i) != min(i):
raise RuntimeError("Elements with different numbers of DOFs on subentities of the same dimension"
" are not yet supported in FFCx.")
num_dofs_per_entity = [i[0] for i in basix_element.entity_dofs]

num_dofs_per_entity = [i[0] for i in basix_element.num_entity_dofs]
ir["num_entity_dofs"] = num_dofs_per_entity
ir["tabulate_entity_dofs"] = (basix_element.entity_dof_numbers, num_dofs_per_entity)
ir["tabulate_entity_dofs"] = (basix_element.entity_dofs, num_dofs_per_entity)

ir["num_global_support_dofs"] = basix_element.num_global_support_dofs
ir["num_element_support_dofs"] = basix_element.dim - ir["num_global_support_dofs"]
Expand Down
Empty file added test/__init__.py
Empty file.