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

BUG: failing to assemble expression HCurl element on a tensor product mesh when part of a mixed functionspace #3243

Closed
stephankramer opened this issue Nov 20, 2023 · 3 comments · Fixed by FInAT/FInAT#113
Assignees
Labels

Comments

@stephankramer
Copy link
Contributor

Describe the bug
In the below reproducer it fails to assemble expressions on a tensor product domain, if they involve a mixed function space where the "velocity" uses a HCurl element and the pressure is a plain tensor product element. This seems to be because a HCurlElement of a tensor product element reports their embedded_superdegree as a tuple, whereas a plain tensor product element reports it as an integer. I notice that in finat/ufl/hdivcurl.py the HDivElement has a specific implementation of embedded_superdegree which calls the underlying element, whereas HCurlElement does not; Should it?

I also notice that these elements have been moved recently as "ufl legacy elements" into finat. Is this a deprecated way of constructing this element for Firedrake as well? Should I be constructing it in a different way?

Steps to Reproduce
Reproducer:

from firedrake import *
base_mesh = UnitIntervalMesh(2)
mesh2d = ExtrudedMesh(base_mesh, 2)
V = FunctionSpace(mesh2d, "RTCE", 2)
u = Function(V)
hcell, vcell = mesh2d.ufl_cell().sub_cells()
W = FunctionSpace(mesh2d, "Q", 2)
Z = V * W 
z = Function(Z)
u, p = split(z)
print(assemble(dot(u, u)*dx))

fails with

$ python failure.py
Traceback (most recent call last):
  File "/home/skramer/fdb/src/PyOP2/pyop2/caching.py", line 205, in __new__
    return cls._cache_lookup(key)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/firedrake/firedrake/tsfc_interface.py", line 73, in _cache_lookup
    return cls._cache.get((key, commkey)) or cls._read_from_disk(key, comm)
                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/firedrake/firedrake/tsfc_interface.py", line 94, in _read_from_disk
    raise KeyError(f"Object with key {key} not found")
KeyError: 'Object with key 9203fddfeada692eb774a1d08665d1e9 not found'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/skramer/fdb/src/thwaites/failure.py", line 11, in <module>
    print(assemble(dot(u, u)*dx))
          ^^^^^^^^^^^^^^^^^^^^^^
  File "petsc4py/PETSc/Log.pyx", line 188, in petsc4py.PETSc.Log.EventDecorator.decorator.wrapped_func
  File "petsc4py/PETSc/Log.pyx", line 189, in petsc4py.PETSc.Log.EventDecorator.decorator.wrapped_func
  File "/home/skramer/fdb/src/firedrake/firedrake/adjoint_utils/assembly.py", line 19, in wrapper
    output = assemble(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/firedrake/firedrake/assemble.py", line 104, in assemble
    return assemble_base_form(expr, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/firedrake/firedrake/assemble.py", line 191, in assemble_base_form
    visited[e] = base_form_assembly_visitor(e, tensor, bcs, diagonal,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/firedrake/firedrake/assemble.py", line 276, in base_form_assembly_visitor
    return _assemble_form(expr, tensor=tensor, bcs=bcs,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/firedrake/firedrake/assemble.py", line 545, in _assemble_form
    return assembler.assemble()
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/firedrake/firedrake/assemble.py", line 682, in assemble
    self.execute_parloops()
  File "/home/skramer/fdb/src/firedrake/firedrake/assemble.py", line 702, in execute_parloops
    for parloop in self.parloops:
                   ^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/PyOP2/pyop2/utils.py", line 62, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
                                           ^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/firedrake/firedrake/assemble.py", line 761, in parloops
    self.local_kernels, self.global_kernels
    ^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/PyOP2/pyop2/utils.py", line 62, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
                                           ^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/firedrake/firedrake/assemble.py", line 726, in local_kernels
    kernels = tsfc_interface.compile_form(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "petsc4py/PETSc/Log.pyx", line 188, in petsc4py.PETSc.Log.EventDecorator.decorator.wrapped_func
  File "petsc4py/PETSc/Log.pyx", line 189, in petsc4py.PETSc.Log.EventDecorator.decorator.wrapped_func
  File "/home/skramer/fdb/src/firedrake/firedrake/tsfc_interface.py", line 261, in compile_form
    kinfos = TSFCKernel(f, prefix, parameters,
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/PyOP2/pyop2/caching.py", line 207, in __new__
    obj = make_obj()
          ^^^^^^^^^^
  File "/home/skramer/fdb/src/PyOP2/pyop2/caching.py", line 197, in make_obj
    obj.__init__(*args, **kwargs)
  File "/home/skramer/fdb/src/firedrake/firedrake/tsfc_interface.py", line 146, in __init__
    tree = tsfc_compile_form(form, prefix=name, parameters=parameters,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/tsfc/tsfc/driver.py", line 79, in compile_form
    fd = ufl_utils.compute_form_data(form, complex_mode=complex_mode)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/tsfc/tsfc/ufl_utils.py", line 56, in compute_form_data
    fd = ufl_compute_form_data(
         ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/ufl/ufl/algorithms/compute_form_data.py", line 281, in compute_form_data
    form = attach_estimated_degrees(form)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/ufl/ufl/algorithms/compute_form_data.py", line 207, in attach_estimated_degrees
    degree = estimate_total_polynomial_degree(integral.integrand())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/ufl/ufl/algorithms/estimate_degrees.py", line 380, in estimate_total_polynomial_degree
    degrees = map_expr_dags(de, [e])
              ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/ufl/ufl/corealg/map_dag.py", line 98, in map_expr_dags
    r = handlers[v._ufl_typecode_](v)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/ufl/ufl/algorithms/estimate_degrees.py", line 87, in coefficient
    d = e.embedded_superdegree  # FIXME: Use component to improve accuracy for mixed elements
        ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/skramer/fdb/src/FInAT/finat/ufl/mixedelement.py", line 264, in embedded_superdegree
    return max(e.embedded_superdegree for e in self.sub_elements)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '>' not supported between instances of 'int' and 'tuple'
stephankramer added a commit to thwaitesproject/thwaites that referenced this issue Nov 20, 2023
*** Makes thwaites depend on g-adopt ***
Any bit of code that required fixing but is duplicated in g-adopt is now
imported from g-adopt, specifically: extend_function_to_3d,
is_continuous, normal_is_continuous. VertexBasedP1DGLimiter is
subclassed to add special treatment of squeezed triangles.

In test_*.py files please do not add any code that's run when imported
as a module, as pytest will automatically import all of these to
discover what files there are, and thus that code will already be run
before pytest itself runs any tests. If you want to add code when the
test file is run as a script, add a `if __name__ == "__main__"` guard.

One of the UFL changes seems to have broken RTCE on tensor product
meshes (firedrakeproject/firedrake#3243). Have
implemented a fix in a fork of FInAT
(https://github.com/thwaitesproject/FInAT) that should now be pulled in
the CI.
@connorjward
Copy link
Contributor

Was this an issue introduced by the recent UFL update? Also it looks like you have submitted related fixes elsewhere, I assume that this issue is still valid?

I also notice that these elements have been moved recently as "ufl legacy elements" into finat. Is this a deprecated way of constructing this element for Firedrake as well? Should I be constructing it in a different way?

AIUI apart from the namespace change the API is currently unchanged and is one step along the road to improving the finite element infrastructure in Firedrake/FEniCS. This was described a little here.

@connorjward
Copy link
Contributor

I've found the fix. It was exactly as you suggested with those missing properties!

@stephankramer
Copy link
Contributor Author

Ah thanks, Connor, yeah wasn't entirely sure whether this was correct - as I don't actually know much about the interface at that level. The fix I submitted "elsewhere" was just on a temporary finat fork to unbreak the CI of a project that uses this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants