# Constant in dolfinx and ffcx compilation

**URL:** <https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968>\
**Category:** dolfinx\
**Created:** [August 10, 2022, 9:07am UTC](https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968 "2022-08-10T09:07:05Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmaurini](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/cmaurini/32/2812_2.png) [@cmaurini](https://fenicsproject.discourse.group/u/cmaurini)\
**Post date:** [August 10, 2022, 9:07am UTC](https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968/1 "2022-08-10T09:07:05Z")

</div>

In `dolfin-old` when defining a form including a constant, the form was not recompiled when changing its value (I suppose there was a specific signature associated to each constant).

This is not anymore the case in dolfinx. When I redefine a constant, the form is recompiled, which is annoying. Is there a way to avoid this?

I give below a MWE. Of course one can assign the value of the constant, but I cannot do it in my case, because the constant is a function that I call for a parametric analysis, and I do not want to have `dolfinx.fem.Constant` in the launcher of the parameter analysis.

```auto
from dolfinx.fem import (Constant, assemble_scalar, form)
from dolfinx.mesh import create_unit_square
from mpi4py import MPI
from ufl import dx
import numpy as np
from pathlib import Path
import shutil

mesh = create_unit_square(MPI.COMM_WORLD, 1, 1)

cache_dir = f"{str(Path.cwd())}/cache"
shutil.rmtree(cache_dir,ignore_errors=True)
jit_params = {"cache_dir": cache_dir, "cffi_verbose": True}

# this recompiles the form at each iterations (different behavior wrt dolfin-old)
for c in np.linspace(0,1,10):
    cnst = Constant(mesh,c) 
    f = assemble_scalar(form(cnst * dx(domain=mesh),jit_params=jit_params))
    print(f)
    
# this does not recompile (but I need the former)
cnst = Constant(mesh,1.) 
for c in np.linspace(0,.2,10):
    cnst.value = c
    f = assemble_scalar(form(cnst * dx(domain=mesh),jit_params=jit_params))
    print(f)

```

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [August 10, 2022, 9:43am UTC](https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968/2 "2022-08-10T09:43:29Z")

</div>

The whole point with using `form` is that it avoids compilation (and caching) of expressions with the same signature.

I think this is a bug in `ufl`, as ufl does not renumber constants: [ufl/form.py at a7426bd8533f2c819f7f164df9c197e277d058c3 · FEniCS/ufl · GitHub](https://github.com/FEniCS/ufl/blob/a7426bd8533f2c819f7f164df9c197e277d058c3/ufl/form.py#L484-L487) and  
[ufl/form.py at a7426bd8533f2c819f7f164df9c197e277d058c3 · FEniCS/ufl · GitHub](https://github.com/FEniCS/ufl/blob/a7426bd8533f2c819f7f164df9c197e277d058c3/ufl/form.py#L457-L460)

In old dolfin, Constant was not inheriting from `ufl.Constant`, but `ufl.Coefficient`, and thus got renumbered.

I’ll see if I can make a working patch.

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [August 10, 2022, 10:43am UTC](https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968/3 "2022-08-10T10:43:43Z")

</div>

@cmaurini I’ve added a PR to ufl that should fix the issue: [Renumber constants for caching when defined in loops by jorgensd · Pull Request #113 · FEniCS/ufl · GitHub](https://github.com/FEniCS/ufl/pull/113)

Feel free to test it.

---

<div class="post-metadata">

**Author:** ![cmaurini](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/cmaurini/32/2812_2.png) [@cmaurini](https://fenicsproject.discourse.group/u/cmaurini)\
**Post date:** [August 10, 2022, 11:26am UTC](https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968/4 "2022-08-10T11:26:49Z")

</div>

Great, thanks, the fix does the job!

---

<div class="post-metadata">

**Author:** ![cmaurini](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/cmaurini/32/2812_2.png) [@cmaurini](https://fenicsproject.discourse.group/u/cmaurini)\
**Post date:** [August 10, 2022, 1:11pm UTC](https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968/5 "2022-08-10T13:11:40Z")

</div>

Note however the different behaviour between `Constant(mesh.ufl_cell(),c)` and `Constant(mesh,c)`  
when using different meshes. Why `Constant` is defined on the whole mesh and not on the single cell in all the examples? What is the rationale for using `Constant(mesh.ufl_cell(),c)` instead that `Constant(mesh,c)`?

```auto
from dolfinx.fem import (Constant, assemble_scalar, form)
from dolfinx.mesh import create_unit_square
from mpi4py import MPI
from ufl import dx
import numpy as np
from pathlib import Path
import shutil

cache_dir = f"{str(Path.cwd())}/cache"
shutil.rmtree(cache_dir,ignore_errors=True)
jit_params = {"cache_dir": cache_dir, "cffi_verbose": True}

# Does not recompile
for c in np.linspace(0,1,10):
    mesh = create_unit_square(MPI.COMM_WORLD, 1, 1)
    cnst = Constant(mesh.ufl_cell(),c) 
    f = assemble_scalar(form(cnst * dx(domain=mesh),jit_params=jit_params))
    print(f)
    
shutil.rmtree(cache_dir,ignore_errors=True)

# Recompile each time
for c in np.linspace(0,1,10):
    mesh = create_unit_square(MPI.COMM_WORLD, 1, 1)
    cnst = Constant(mesh,c) 
    f = assemble_scalar(form(cnst * dx(domain=mesh),jit_params=jit_params))
    print(f)

```

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [August 10, 2022, 3:01pm UTC](https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968/6 "2022-08-10T15:01:25Z")

</div>

> [@cmaurini](#):
>
> Why `Constant` is defined on the whole mesh and not on the single cell in all the examples?

I guess we haven’t thought about this in the examples. The rationale would be for problems where you use `cnst*ufl.dx` and not `cnst*ufl.dx(domain=mesh)`, as the former will not compile:

```python
for c in np.linspace(0, 1, 10):
    mesh = create_unit_square(MPI.COMM_WORLD, 1, 1)
    cnst = Constant(mesh.ufl_cell(), c)
    f = assemble_scalar(form(cnst * dx), jit_params=jit_params) # (domain=mesh), jit_params=jit_params))
    print(f)

```

returns

```bash
RuntimeError: Expecting to find a Mesh in the form.

```

I’ve now updated the PR in UFL to make sure that we now use the correct signature for both the cases above.

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [August 11, 2022, 4:55am UTC](https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968/7 "2022-08-11T04:55:58Z")

</div>

@cmaurini the issue has now been resolved (if you pull the latest version of ufl main branch)

---

<div class="post-metadata">

**Author:** ![cmaurini](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/cmaurini/32/2812_2.png) [@cmaurini](https://fenicsproject.discourse.group/u/cmaurini)\
**Post date:** [August 11, 2022, 6:51am UTC](https://fenicsproject.discourse.group/t/constant-in-dolfinx-and-ffcx-compilation/8968/8 "2022-08-11T06:51:24Z")

</div>

Thanks a lot. It works also for different meshes, as I was expecting.

```auto
# This does not recompile at each iteration
for c in np.linspace(1,10,10):
    mesh = create_unit_square(MPI.COMM_WORLD, 1, int(c))
    f = assemble_scalar(form(cnst * dx(domain=mesh),jit_params=jit_params))
    print(f)

```

Have a good day.
