Skip to content

Commit

Permalink
Update UFL element (#2784)
Browse files Browse the repository at this point in the history
* update UFL interface

* branches

* remove impossible conversion to string

* "

* I -> i

* add line to README

* Revert "add line to README"

This reverts commit 26ade98.

* rerun CI

* Revert "rerun CI"

This reverts commit 636a0f9.

* RERUN CI

* ()

* branches

---------

Co-authored-by: Jack S. Hale <[email protected]>
  • Loading branch information
mscroggs and jhale authored Oct 16, 2023
1 parent fdbc308 commit adde58a
Show file tree
Hide file tree
Showing 11 changed files with 23 additions and 33 deletions.
1 change: 0 additions & 1 deletion .github/workflows/ccpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ jobs:
if: github.event_name != 'workflow_dispatch'
run: |
python3 -m pip install git+https://github.com/FEniCS/ufl.git
# python3 -m pip install git+https://github.com/FEniCS/basix.git@garth/nanobind
python3 -m pip install git+https://github.com/FEniCS/basix.git
python3 -m pip install git+https://github.com/FEniCS/ffcx.git
- name: Install FEniCS Python components
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ To contribute code DOLFINx, create a pull request. If you want to
contribute, but are unsure where to start, have a look at the [issues
labelled "good first
issue"](https://github.com/FEniCS/dolfinx/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).
For substantial changes/contributions, please start with an Issue or
For substantial changes/contributions, please start with an issue or
start a discussion on Slack.

On opening a pull request, unit tests will run on GitHub CI. You can
Expand Down
17 changes: 6 additions & 11 deletions cpp/dolfinx/fem/FiniteElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ _extract_sub_element(const FiniteElement<T>& finite_element,
//-----------------------------------------------------------------------------
template <std::floating_point T>
FiniteElement<T>::FiniteElement(const ufcx_finite_element& e)
: _signature(e.signature), _family(e.family), _space_dim(e.space_dimension),
: _signature(e.signature), _space_dim(e.space_dimension),
_value_shape(e.value_shape, e.value_shape + e.value_rank),
_bs(e.block_size)
{
Expand Down Expand Up @@ -306,20 +306,21 @@ FiniteElement<T>::FiniteElement(const basix::FiniteElement<T>& element,
_needs_dof_permutations
= !_element->dof_transformations_are_identity()
and _element->dof_transformations_are_permutations();
std::string family;
switch (_element->family())
{
case basix::element::family::P:
_family = "Lagrange";
family = "Lagrange";
break;
case basix::element::family::DPC:
_family = "Discontinuous Lagrange";
family = "Discontinuous Lagrange";
break;
default:
_family = "unknown";
family = "unknown";
break;
}

_signature = "Basix element " + _family + " " + std::to_string(_bs);
_signature = "Basix element " + family + " " + std::to_string(_bs);
}
//-----------------------------------------------------------------------------
template <std::floating_point T>
Expand Down Expand Up @@ -385,12 +386,6 @@ std::span<const std::size_t> FiniteElement<T>::value_shape() const noexcept
}
//-----------------------------------------------------------------------------
template <std::floating_point T>
std::string FiniteElement<T>::family() const noexcept
{
return _family;
}
//-----------------------------------------------------------------------------
template <std::floating_point T>
void FiniteElement<T>::tabulate(std::span<T> values, std::span<const T> X,
std::array<std::size_t, 2> shape,
int order) const
Expand Down
6 changes: 1 addition & 5 deletions cpp/dolfinx/fem/FiniteElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ class FiniteElement
/// `value_shape`.
std::span<const std::size_t> value_shape() const noexcept;

/// The finite element family
/// @return The string of the finite element family
std::string family() const noexcept;

/// @brief Evaluate derivatives of the basis functions up to given order
/// at points in the reference cell.
/// @param[in,out] values Array that will be filled with the tabulated
Expand Down Expand Up @@ -672,7 +668,7 @@ class FiniteElement
bool scalar_element = false) const;

private:
std::string _signature, _family;
std::string _signature;

mesh::CellType _cell_shape;

Expand Down
2 changes: 1 addition & 1 deletion python/dolfinx/fem/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def form(form: typing.Union[ufl.Form, typing.Iterable[ufl.Form]],
raise NotImplementedError(f"Type {dtype} not supported.")

def _form(form):
""""Compile a single UFL form"""
"""Compile a single UFL form"""
# Extract subdomain data from UFL form
sd = form.subdomain_data()
domain, = list(sd.keys()) # Assuming single domain
Expand Down
10 changes: 5 additions & 5 deletions python/dolfinx/fem/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ def eval(self, x: npt.ArrayLike, cells: npt.ArrayLike, u=None) -> np.ndarray:

# Allocate memory for return value if not provided
if u is None:
value_size = ufl.product(self.ufl_element().value_shape())
value_size = ufl.product(self.ufl_element().value_shape)
u = np.empty((num_points, value_size), self.dtype)

self._cpp_object.eval(_x, _cells, u)
Expand Down Expand Up @@ -524,7 +524,7 @@ def functionspace(mesh: Mesh,
ufl_e = element # type: ignore

# Check that element and mesh cell types match
if ufl_e.cell() != mesh.ufl_domain().ufl_cell():
if ufl_e.cell != mesh.ufl_domain().ufl_cell():
raise ValueError("Non-matching UFL cell and mesh cell shapes.")

# Compile dofmap and element and create DOLFIN objects
Expand Down Expand Up @@ -645,8 +645,8 @@ def sub(self, i: int) -> FunctionSpaceBase:
A subspace
"""
assert self.ufl_element().num_sub_elements() > i
sub_element = self.ufl_element().sub_elements()[i]
assert self.ufl_element().num_sub_elements > i
sub_element = self.ufl_element().sub_elements[i]
cppV_sub = self._cpp_object.sub([i])
return FunctionSpaceBase(self._mesh, sub_element, cppV_sub)

Expand Down Expand Up @@ -744,7 +744,7 @@ def VectorFunctionSpace(mesh: Mesh,
DeprecationWarning, stacklevel=2)
ed = ElementMetaData(*element)
e = basix.ufl.element(ed.family, mesh.basix_cell(), ed.degree, gdim=mesh.geometry.dim)
if len(e.value_shape()) != 0:
if len(e.value_shape) != 0:
raise ValueError("Cannot create vector element containing a non-scalar.")
ufl_e = basix.ufl.element(ed.family, mesh.basix_cell(), ed.degree,
shape=(mesh.geometry.dim,) if dim is None else (dim,),
Expand Down
2 changes: 1 addition & 1 deletion python/dolfinx/jit.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def ffcx_jit(ufl_object, form_compiler_options: Optional[dict] = None,
# Switch on type and compile, returning cffi object
if isinstance(ufl_object, ufl.Form):
r = ffcx.codegeneration.jit.compile_forms([ufl_object], options=p_ffcx, **p_jit)
elif isinstance(ufl_object, ufl.FiniteElementBase):
elif isinstance(ufl_object, ufl.AbstractFiniteElement):
r = ffcx.codegeneration.jit.compile_elements([ufl_object], options=p_ffcx, **p_jit)
elif isinstance(ufl_object, ufl.Mesh):
r = ffcx.codegeneration.jit.compile_coordinate_maps([ufl_object], options=p_ffcx, **p_jit)
Expand Down
4 changes: 2 additions & 2 deletions python/dolfinx/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ def create_mesh(comm: _MPI.Comm, cells: typing.Union[np.ndarray, _cpp.graph.Adja
partitioner = _cpp.mesh.create_cell_partitioner(GhostMode.none)

ufl_element = domain.ufl_coordinate_element()
cell_shape = ufl_element.cell().cellname()
cell_degree = ufl_element.degree()
cell_shape = ufl_element.cell.cellname()
cell_degree = ufl_element.degree
try:
variant = int(ufl_element.lagrange_variant)
except AttributeError:
Expand Down
4 changes: 2 additions & 2 deletions python/dolfinx/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ def _(V: fem.FunctionSpaceBase, entities=None):
Topology, type for each cell, and geometry in VTK-ready format.
"""
if not (V.ufl_element().family() in ['Discontinuous Lagrange', "Lagrange", "DQ", "Q", "DP", "P"]):
if not (V.ufl_element().family_name in ['Discontinuous Lagrange', "Lagrange", "DQ", "Q", "DP", "P"]):
raise RuntimeError("Can only create meshes from continuous or discontinuous Lagrange spaces")

degree = V.ufl_element().degree()
degree = V.ufl_element().degree
if degree == 0:
raise RuntimeError("Cannot create topology from cellwise constants.")

Expand Down
2 changes: 1 addition & 1 deletion python/test/unit/fem/test_function_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def test_vector_function_space_cell_type():
# Create functions space over mesh, and check element cell
# is correct
V = FunctionSpace(mesh, ('Lagrange', 1, (gdim,)))
assert V.ufl_element().cell() == cell
assert V.ufl_element().cell == cell


@pytest.mark.skip_in_parallel
Expand Down
6 changes: 3 additions & 3 deletions python/test/unit/fem/test_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,8 @@ def f(x):
assert np.allclose(u.x.array, v.x.array, atol=atol)

# Test with wrong shape
V0 = FunctionSpace(mesh, P.sub_elements()[0])
V1 = FunctionSpace(mesh, P.sub_elements()[1])
V0 = FunctionSpace(mesh, P.sub_elements[0])
V1 = FunctionSpace(mesh, P.sub_elements[1])
v0, v1 = Function(V0), Function(V1)
with pytest.raises(RuntimeError):
v0.interpolate(U.sub(1))
Expand Down Expand Up @@ -644,7 +644,7 @@ def test_interpolate_callable_subset(bound):
])
def test_vector_element_interpolation(scalar_element):
"""Test interpolation into a range of vector elements."""
mesh = create_unit_square(MPI.COMM_WORLD, 10, 10, getattr(CellType, scalar_element.cell().cellname()))
mesh = create_unit_square(MPI.COMM_WORLD, 10, 10, getattr(CellType, scalar_element.cell.cellname()))
V = FunctionSpace(mesh, blocked_element(scalar_element, shape=(2, )))
u = Function(V)
u.interpolate(lambda x: (x[0], x[1]))
Expand Down

0 comments on commit adde58a

Please sign in to comment.