Expression depending on another Expression?

Hello all,

I am quite sure this has somewhere been answered but I can’t seem to find it. I want to define a complex user-defined JIT-compiled Expression based on another given (vector-valued) Expression.

from dolfin import Expression

# Some random Expression
f = Expression(('0 <= x[0] <= 1 ? 4 : 5 ', '0 <= x[1] <= 1 ? 6 : 7'), degree=0)

# The Expression below should depend on the upper Expression
char = Expression('f(x)[0] == 42 ? 0 : 1', degree=0)

This doesn’t work though.
I am happy about any kind of help. Thanks in advance!

You can pass one Expression as a keyword argument to another Expression. There is no need to pass the argument x to the first Expression where it is used in the definition of the second one. See the following example:

from dolfin import *
from numpy import array

# Pass g as keyword argument to f:
g = Expression("x[0]",degree=1)
f = Expression("pow(g,2)",g=g,degree=2)

# Check results:
print(f(array([0.5,])))
print(assemble(f*dx(domain=UnitIntervalMesh(1))))
2 Likes

Thank you for your answer!
The first Expression is meant to be the function that has the value 4 if the first component of its argument lies between 0 and 1 and that has the value 5 otherwise. Analogously for the second component. I also just realised that it should be:

f = Expression(('0 <= x[0] & x[0] <= 1 ? 4 : 5 ', '0 <= x[1] & x[1] <= 1 ? 6 : 7'), degree=0)

The question is then whether I can make the if statement in the second Expression dependent on the first Expression. So the second Expression would have to have the value 0 if the first component of f(x) has the value 42 and else it would have to have the value 1.
I am really sorry if the answer to this question follows from what you have wrote but I can’t figure it out so far.

Maybe the following example is clearer:

from dolfin import *
from numpy import array

# Simplified for a clear demonstration:
f = Expression(('x[0] < 0.5 ? 42 : 0 ', '0'), degree=0)

# Removed the "(x)" after f and added f as a
# keyword argument.
char = Expression('f[0] == 42 ? 0 : 1', degree=0, f=f)

# Demonstrate:

# Should be 0, because x[0] < 0.5, so f[0]==42.
print(char(array([0.25,])))

# Should be 1, because x[0] > 0.5, so f[0]==0.
print(char(array([0.75,])))

# Note: If char is used in an integrand for a Form, it
# will be interpolated in a DG0 space (or, generally,
# in an FE space of the specified degree) rather than
# evaluated pointwise at quadrature points.  

Thank you very much. This did help a lot!