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

Add check of element hash #3186

Merged
merged 15 commits into from
May 2, 2024
2 changes: 1 addition & 1 deletion .github/workflows/oneapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ jobs:
- name: Build DOLFINx Python interface
run: |
. /opt/intel/oneapi/setvars.sh
pip -v install --check-build-dependencies --no-build-isolation python/
pip -v install --check-build-dependencies --no-build-isolation --config-settings=cmake.build-type="Developer" python/
- name: Set default DOLFINx JIT options
run: |
mkdir -p ~/.config/dolfinx
Expand Down
10 changes: 7 additions & 3 deletions cpp/dolfinx/fem/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,13 +360,17 @@ Form<T, U> create_form_factory(
}

// Check argument function spaces
#ifndef NDEBUG
for (std::size_t i = 0; i < spaces.size(); ++i)
{
assert(spaces[i]->element());
// TODO: Hash check of element
if (auto element_hash = ufcx_form.finite_element_hashes[i];
element_hash != 0
and element_hash != spaces[i]->element()->basix_element().hash())
{
throw std::runtime_error("Cannot create form. Elements are different to "
"those used to compile the form.");
}
}
#endif

// Extract mesh from FunctionSpace, and check they are the same
if (!mesh and !spaces.empty())
Expand Down
61 changes: 61 additions & 0 deletions python/test/unit/fem/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@

import pytest

import basix
import basix.ufl
import dolfinx
from dolfinx.fem import extract_function_spaces, form, functionspace
from dolfinx.fem.forms import form_cpp_class
from dolfinx.mesh import create_unit_square
from ufl import TestFunction, TrialFunction, dx, inner

Expand Down Expand Up @@ -48,3 +52,60 @@ def test_extract_forms():
assert Vr[1] is V1._cpp_object
with pytest.raises(AssertionError):
extract_function_spaces(a, 1)


def test_incorrect_element():
"""Test that an error is raised if an incorrect element is used."""
mesh = create_unit_square(MPI.COMM_WORLD, 32, 31)
element = basix.ufl.element(
"Lagrange",
"triangle",
4,
lagrange_variant=basix.LagrangeVariant.gll_warped,
dtype=dolfinx.default_real_type,
)
incorrect_element = basix.ufl.element(
"Lagrange",
"triangle",
4,
lagrange_variant=basix.LagrangeVariant.equispaced,
dtype=dolfinx.default_real_type,
)

space = functionspace(mesh, element)
incorrect_space = functionspace(mesh, incorrect_element)

u = TrialFunction(space)
v = TestFunction(space)

a = inner(u, v) * dx

dtype = dolfinx.default_scalar_type
ftype = form_cpp_class(dtype)

ufcx_form, module, code = dolfinx.jit.ffcx_jit(
mesh.comm, a, form_compiler_options={"scalar_type": dtype}
)

f = ftype(
module.ffi.cast("uintptr_t", module.ffi.addressof(ufcx_form)),
[space._cpp_object, space._cpp_object],
[],
[],
{dolfinx.cpp.fem.IntegralType.cell: []},
{},
mesh._cpp_object,
)
dolfinx.fem.Form(f, ufcx_form, code)

with pytest.raises(RuntimeError):
f = ftype(
module.ffi.cast("uintptr_t", module.ffi.addressof(ufcx_form)),
[incorrect_space._cpp_object, incorrect_space._cpp_object],
[],
[],
{dolfinx.cpp.fem.IntegralType.cell: []},
{},
mesh._cpp_object,
)
dolfinx.fem.Form(f, ufcx_form, code)
Loading