Expression Boundary Condition - Polar Coordinate System

Hey there.

I’d like to use the typical Expression command to specify an expression to be applied on my boundaries, as boundary conditions. I recieve this expressions in the (r,theta) coordinates system. Now, notice these are large expressions: it’s non-viable to change from the (r,theta) coordinates system to the cartesian system by hand. So, if I had an expression like u = r*cos(theta), could I implement this in FEniCS quickly? Something like:

disp_x0 = Expression('r*cos(theta)', r=sqrt(x[0]*x[0]+x[1]*x[1]), theta=atan2(x[1],x[0]), degree=3)

(This implementation resulted in:)

NameError: name 'atan2' is not defined

But atan2 should be defined, as it is part of the C++ language, if I’m not mistaken.


It seems that the problem with atan2 was the fact that I forgot to import math library. Now, the problem moved to:

NameError: name 'x' is not defined

Thanks in advance.

A trick like Incorrect Values Creating Expression From Other Expressions - #2 by francesco-ballarin may be of help. Define two symbols x0 = sympy.var("x[0]") and x1 = sympy.var("x[1]"), use sympy to compute theta and r starting from x0 and x1, write your expression in theta and r, and finally convert them to a C++ code with sympy.printing.ccode.

My implementation:

x0 = sympy.var("x[0]")
x1 = sympy.var("x[1]")
theta = sympy.atan2(x1, x0)
r = sympy.sqrt(x0*x0 + x1*x1)

disp_x0_nod = Expression('cos(theta)*0.5*sin(theta) + pi/4*log(r)*power(r,2)', degree=3)
disp_x0 = sympy.printing.ccode(disp_x0_nod)

Resulted in

 error: ‘theta’ was not declared in this scope

(later on)

raise RuntimeError("Unable to compile C++ code with dijitso")
RuntimeError: Unable to compile C++ code with dijitso

Thanks again!

You need to send theta into expression, i.e.

disp_x0_nod = Expression(f'cos({theta})*0.5*sin({theta}) + pi/4*log(r)*power(r,2)', degree=3)

I guess.
Please make the example reproducible, i.e. all imports and minimal code to reproduce the error message you are seeing.

I guess it should be something like

x0 = sympy.var("x[0]")
x1 = sympy.var("x[1]")
theta = sympy.atan2(x1, x0)
r = sympy.sqrt(x0*x0 + x1*x1)

disp_x0_sym = cos(theta)*0.5*sin(theta) + sympy.pi/4*sympy.log(r)*r**2
disp_x0_ccode = sympy.printing.ccode(disp_x0_sym)
disp_x0_nod = Expression(disp_x0_ccode, degree=3)

but, as @dokken says, we can’t be more precise unless you give us a minimal example which we can run ourselves.