# Sympy to Fenics - Unable to compile

**URL:** <https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669>\
**Category:** General\
**Created:** [February 20, 2024, 5:10pm UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669 "2024-02-20T17:10:19Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![egomezp](https://avatars.discourse-cdn.com/v4/letter/e/d78d45/32.png) [@egomezp](https://fenicsproject.discourse.group/u/egomezp)\
**Post date:** [February 20, 2024, 5:10pm UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/1 "2024-02-20T17:10:19Z")

</div>

Hey, there.

I’m using a previous script programmed in sympy to obtain a 2x1 vector that, to my understanding, should represent a displacements boundary condition programmed in sympy. Here I add this code:

```auto
from sympy import symbols, atan2, sqrt, pi, log, sin, cos, Matrix

def calculate_displacements():
    x, y = symbols('x[0] x[1]')

    r_expr = sqrt(x **2 + y** 2)

    theta_expr = atan2(y, x)

    gr = 1
    a_expr = cos(theta_expr)
    b_expr = -sin(theta_expr)
    c_expr = sin(theta_expr)
    d_expr = cos(theta_expr)
    u_r_expr = -1/2*cos(theta_expr)-gr*r_expr/(4*pi)*(-1+2*log(r_expr)+cos(2*theta_expr)*(1+2*log(r_expr))+2*(pi-theta_expr)*sin(2*theta_expr))
    u_theta_expr = 1/2*sin(theta_expr)+gr*r_expr/(4*pi)*(2*(theta_expr-pi)*(2-2*cos(2*theta_expr))-(1+2*log(r_expr))*sin(2*theta_expr))

    matriz_2x2 = Matrix([[a_expr, b_expr], [c_expr, d_expr]])
    matriz_2x1 = Matrix([u_r_expr, u_theta_expr])

    displacements = matriz_2x2 * matriz_2x1

    return displacements

```

Later, I’m calling this script in another code, and trying to import from sympy to a fenics expression that can be applied on boundaries:

```auto
disp = calculate_displacements() #vector 2d with python symbolic    
disp_0 = dolfin.Expression(sympy.printing.ccode(disp[0]), degree=1)
disp_1 = dolfin.Expression(sympy.printing.ccode(disp[1]), degree=1)

---------------------------------------------
RuntimeError: Unable to compile C++ code with dijitso

------------------- Start compiler output ------------------------
/tmp/tmpub49mgm6/dolfin_expression_dcc992add57a69e21eb4916509aef08b.cpp: In member function ‘virtual void dolfin::dolfin_expression_dcc992add57a69e21eb4916509aef08b::eval(Eigen::Ref<Eigen::Matrix<double, -1, 1> >, Eigen::Ref<const Eigen::Matrix<double, -1, 1> >) const’:
/tmp/tmpub49mgm6/dolfin_expression_dcc992add57a69e21eb4916509aef08b.cpp:61:158: error: too few arguments to function ‘void dolfin::log(int, std::string, ...)’

```

I don’t understand the error so, my question is, is this properly programmed? Can you actually import from sympy to fenics as I did with this implementation, or does it have to be with me writing bad expressions (I revised them several times)?

Thanks in advance.

Full error

```auto
------------------- Start compiler output ------------------------
/tmp/tmp_13w9miu/dolfin_expression_dcc992add57a69e21eb4916509aef08b.cpp: In member function ‘virtual void dolfin::dolfin_expression_dcc992add57a69e21eb4916509aef08b::eval(Eigen::Ref<Eigen::Matrix<double, -1, 1> >, Eigen::Ref<const Eigen::Matrix<double, -1, 1> >) const’:
/tmp/tmp_13w9miu/dolfin_expression_dcc992add57a69e21eb4916509aef08b.cpp:61:158: error: too few arguments to function ‘void dolfin::log(int, std::string, ...)’
   61 | values[0] = x[0]*(-0.5*x[0]/sqrt(pow(x[0], 2) + pow(x[1], 2)) - 1.0/4.0*sqrt(pow(x[0], 2) + pow(x[1], 2))*((2*log(sqrt(pow(x[0], 2) + pow(x[1], 2))) + 1)*cos(2*atan2(x[1], x[0])) + (-2*atan2(x[1], x[0]) + 2*M_PI)*sin(2*atan2(x[1], x[0])) + 2*log(sqrt(pow(x[0], 2) + pow(x[1], 2))) - 1)/M_PI)/sqrt(pow(x[0], 2) + pow(x[1], 2)) - x[1]*(0.5*x[1]/sqrt(pow(x[0], 2) + pow(x[1], 2)) + (1.0/4.0)*sqrt(pow(x[0], 2) + pow(x[1], 2))*((2 - 2*cos(2*atan2(x[1], x[0])))*(2*atan2(x[1], x[0]) - 2*M_PI) - (2*log(sqrt(pow(x[0], 2) + pow(x[1], 2))) + 1)*sin(2*atan2(x[1], x[0])))/M_PI)/sqrt(pow(x[0], 2) + pow(x[1], 2));
      |
         ^
In file included from /usr/include/dolfin/common/Array.h:32,
                 from /usr/include/dolfin/function/Expression.h:27,
                 from /tmp/tmp_13w9miu/dolfin_expression_dcc992add57a69e21eb4916509aef08b.cpp:13:
/usr/include/dolfin/log/log.h:103:8: note: declared here
  103 | void log(int debug_level, std::string msg, ...);
      | ^~~
/tmp/tmp_13w9miu/dolfin_expression_dcc992add57a69e21eb4916509aef08b.cpp:61:290: error: too few arguments to function ‘void dolfin::log(int, std::string, ...)’
   61 | values[0] = x[0]*(-0.5*x[0]/sqrt(pow(x[0], 2) + pow(x[1], 2)) - 1.0/4.0*sqrt(pow(x[0], 2) + pow(x[1], 2))*((2*log(sqrt(pow(x[0], 2) + pow(x[1], 2))) + 1)*cos(2*atan2(x[1], x[0])) + (-2*atan2(x[1], x[0]) + 2*M_PI)*sin(2*atan2(x[1], x[0])) + 2*log(sqrt(pow(x[0], 2) + pow(x[1], 2))) - 1)/M_PI)/sqrt(pow(x[0], 2) + pow(x[1], 2)) - x[1]*(0.5*x[1]/sqrt(pow(x[0], 2) + pow(x[1], 2)) + (1.0/4.0)*sqrt(pow(x[0], 2) + pow(x[1], 2))*((2 - 2*cos(2*atan2(x[1], x[0])))*(2*atan2(x[1], x[0]) - 2*M_PI) - (2*log(sqrt(pow(x[0], 2) + pow(x[1], 2))) + 1)*sin(2*atan2(x[1], x[0])))/M_PI)/sqrt(pow(x[0], 2) + pow(x[1], 2));
      |
                                                                                                                                             ^
In file included from /usr/include/dolfin/common/Array.h:32,
                 from /usr/include/dolfin/function/Expression.h:27,
                 from /tmp/tmp_13w9miu/dolfin_expression_dcc992add57a69e21eb4916509aef08b.cpp:13:
/usr/include/dolfin/log/log.h:103:8: note: declared here
  103 | void log(int debug_level, std::string msg, ...);
      | ^~~
/tmp/tmp_13w9miu/dolfin_expression_dcc992add57a69e21eb4916509aef08b.cpp:61:541: error: too few arguments to function ‘void dolfin::log(int, std::string, ...)’
   61 | values[0] = x[0]*(-0.5*x[0]/sqrt(pow(x[0], 2) + pow(x[1], 2)) - 1.0/4.0*sqrt(pow(x[0], 2) + pow(x[1], 2))*((2*log(sqrt(pow(x[0], 2) + pow(x[1], 2))) + 1)*cos(2*atan2(x[1], x[0])) + (-2*atan2(x[1], x[0]) + 2*M_PI)*sin(2*atan2(x[1], x[0])) + 2*log(sqrt(pow(x[0], 2) + pow(x[1], 2))) - 1)/M_PI)/sqrt(pow(x[0], 2) + pow(x[1], 2)) - x[1]*(0.5*x[1]/sqrt(pow(x[0], 2) + pow(x[1], 2)) + (1.0/4.0)*sqrt(pow(x[0], 2) + pow(x[1], 2))*((2 - 2*cos(2*atan2(x[1], x[0])))*(2*atan2(x[1], x[0]) - 2*M_PI) - (2*log(sqrt(pow(x[0], 2) + pow(x[1], 2))) + 1)*sin(2*atan2(x[1], x[0])))/M_PI)/sqrt(pow(x[0], 2) + pow(x[1], 2));
      |

                                                                                ^
In file included from /usr/include/dolfin/common/Array.h:32,
                 from /usr/include/dolfin/function/Expression.h:27,
                 from /tmp/tmp_13w9miu/dolfin_expression_dcc992add57a69e21eb4916509aef08b.cpp:13:
/usr/include/dolfin/log/log.h:103:8: note: declared here
  103 | void log(int debug_level, std::string msg, ...);
      | ^~~

------------------- End compiler output ------------------------
Compilation failed! Sources, command, and errors have been written to: /mnt/c/fenics_cracks/Dirichlet_Robin_M2/jitfailure-dolfin_expression_dcc992add57a69e21eb4916509aef08b
Traceback (most recent call last):
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/jit/jit.py", line 168, in compile_class
    module, signature = dijitso_jit(cpp_data, module_name, params,
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/jit/jit.py", line 50, in mpi_jit
    return local_jit(*args, **kwargs)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/jit/jit.py", line 106, in dijitso_jit
    return dijitso.jit(*args, **kwargs)
  File "/home/edu/.local/lib/python3.8/site-packages/dijitso/jit.py", line 216, in jit
    raise DijitsoError("Dijitso JIT compilation failed, see '%s' for details"
dijitso.jit.DijitsoError: Dijitso JIT compilation failed, see '/mnt/c/fenics_cracks/Dirichlet_Robin_M2/jitfailure-dolfin_expression_dcc992add57a69e21eb4916509aef08b' for details

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "Dirichlet_Robin_M2.py", line 69, in <module>
    disp_0 = dolfin.Expression(sympy.printing.ccode(disp[0]), degree=1)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/function/expression.py", line 400, in __init__
    self._cpp_object = jit.compile_expression(cpp_code, params)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/function/jit.py", line 158, in compile_expression
    expression = compile_class(cpp_data, mpi_comm=mpi_comm)
  File "/usr/lib/petsc/lib/python3/dist-packages/dolfin/jit/jit.py", line 173, in compile_class
    raise RuntimeError("Unable to compile C++ code with dijitso")
RuntimeError: Unable to compile C++ code with dijitso

```

---

<div class="post-metadata">

**Author:** ![nate](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/nate/32/17_2.png) [@nate](https://fenicsproject.discourse.group/u/nate)\
**Post date:** [February 20, 2024, 5:54pm UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/2 "2024-02-20T17:54:57Z")

</div>

It’s not scoping the `log` function correctly with `std::log`. It’s instead calling old DOLFIN’s `log` function which traces the codes operation. If you read through the sympy documentation there’s probably some information on how to scope out functions in code generation. Otherwise you could try the ugly hack of just replacing `log` with `std::log` in the generated code. Something like

```python
code = code.replace("log", "std::log")

```

---

<div class="post-metadata">

**Author:** ![egomezp](https://avatars.discourse-cdn.com/v4/letter/e/d78d45/32.png) [@egomezp](https://fenicsproject.discourse.group/u/egomezp)\
**Post date:** [February 26, 2024, 7:16am UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/3 "2024-02-26T07:16:15Z")

</div>

Hello Nate,

Thank you for your answer. If I am getting it right, the code where I am generating my symbolic expressions should remain as it is, and the code where I’m implementing my FEM solution should be:

```auto
disp = calculate_displacements() #vector 2d with python symbolic    
disp = disp.replace("log", "std::log") #change log to std log
disp_0 = dolfin.Expression(sympy.printing.ccode(disp[0]), degree=1)
disp_1 = dolfin.Expression(sympy.printing.ccode(disp[1]), degree=1

```

Should it work like this? Is this what you meant? What if, in my original sympy code, I just wrote std::log instead of log?  
Thanks again

---

<div class="post-metadata">

**Author:** ![nate](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/nate/32/17_2.png) [@nate](https://fenicsproject.discourse.group/u/nate)\
**Post date:** [February 26, 2024, 3:28pm UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/4 "2024-02-26T15:28:04Z")

</div>

Something along these lines yes. I’d expect you’d just have to replace the `log` with `std::log` in your C/C++ code string. Since you haven’t provided a minimal working example I doubt I can help further.

---

<div class="post-metadata">

**Author:** ![egomezp](https://avatars.discourse-cdn.com/v4/letter/e/d78d45/32.png) [@egomezp](https://fenicsproject.discourse.group/u/egomezp)\
**Post date:** [February 27, 2024, 8:11am UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/5 "2024-02-27T08:11:23Z")

</div>

The way I tried to implement your solution was with the lines above, using `replace`, instead of manually replacing `log` with `std::log`. It didn’t work: `TypeError: first argument to replace() must be a type, an expression or a callable`. As far as I know, `log` a string (sympy documentation) and I doubt replace can be used here. Could you help me any further? Are there any other options?

Thanks again.

---

<div class="post-metadata">

**Author:** ![nate](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/nate/32/17_2.png) [@nate](https://fenicsproject.discourse.group/u/nate)\
**Post date:** [February 27, 2024, 3:07pm UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/6 "2024-02-27T15:07:00Z")

</div>

`str.replace` is a method of the string class. I don’t know what the type of the object that you’re calling `.replace` on is. As I said, without a MWE I can’t really provide much help. My advice was to call `.replace` on the code string that you’re producing from sympy’s code generation.

---

<div class="post-metadata">

**Author:** ![egomezp](https://avatars.discourse-cdn.com/v4/letter/e/d78d45/32.png) [@egomezp](https://fenicsproject.discourse.group/u/egomezp)\
**Post date:** [February 29, 2024, 9:29am UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/7 "2024-02-29T09:29:16Z")

</div>

If you check my original post, you will find there the code that I’m using to generate my sympy expressions, full code displayed. That, I think, could be a MWE. Later on, I implemented

```auto
disp = calculate_displacements() #vector 2d with python symbolic    
disp = disp.replace("log", "std::log") #change log to std log
disp_0 = dolfin.Expression(sympy.printing.ccode(disp[0]), degree=1)
disp_1 = dolfin.Expression(sympy.printing.ccode(disp[1]), degree=1

```

This is where the `first argument to replace() must be a type, an expression or a callable` arose.

Thanks again.

---

<div class="post-metadata">

**Author:** ![francesco-ballarin](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@francesco-ballarin](https://fenicsproject.discourse.group/u/francesco-ballarin)\
**Post date:** [February 29, 2024, 9:34am UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/8 "2024-02-29T09:34:44Z")

</div>

@egomezp Please be considerate of the users answering your questions, as they do so in their own free time, on top of any work, teaching or other activity which is already going on in their life.

@nate asked you twice to provide a MWE. It’s true you posted an example in the first post, but that example surely has changed due to the intermediate replies. It won’t take you more than a minute to copy and paste it again in a further reply, updating it where needed, and doing so may help clarify the question for people who have already replied to you, or people who haven’t replied yet but may be willing to help.

---

<div class="post-metadata">

**Author:** ![egomezp](https://avatars.discourse-cdn.com/v4/letter/e/d78d45/32.png) [@egomezp](https://fenicsproject.discourse.group/u/egomezp)\
**Post date:** [February 29, 2024, 9:39am UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/9 "2024-02-29T09:39:48Z")

</div>

Okay. This is my MWE:

I’m using this code to generate my sympy expressions:

```auto
from sympy import symbols, atan2, sqrt, pi, log, sin, cos, Matrix

def calculate_displacements():
    # Definir símbolos
    x, y = symbols('x[0] x[1]')

    # Definir r en términos de x e y
    r_expr = sqrt(x **2 + y** 2)

    # Definir theta en términos de x e y
    theta_expr = atan2(y, x)

    # Definir expresiones analíticas
    gr = 1
    a_expr = cos(theta_expr)
    b_expr = -sin(theta_expr)
    c_expr = sin(theta_expr)
    d_expr = cos(theta_expr)
    u_r_expr = -1/2*cos(theta_expr)-gr*r_expr/(4*pi)*(-1+2*log(r_expr)+cos(2*theta_expr)*(1+2*log(r_expr))+2*(pi-theta_expr)*sin(2*theta_expr))
    u_theta_expr = 1/2*sin(theta_expr)+gr*r_expr/(4*pi)*(2*(theta_expr-pi)*(2-2*cos(2*theta_expr))-(1+2*log(r_expr))*sin(2*theta_expr))

    # Definir las matrices con expresiones
    matriz_2x2 = Matrix([[a_expr, b_expr], [c_expr, d_expr]])
    matriz_2x1 = Matrix([u_r_expr, u_theta_expr])

    # Realizar la multiplicación de matrices con expresiones 
    displacements = matriz_2x2 * matriz_2x1
    return displacements

```

And later on, following @nate 's guide, I want to import this expressions to my FEniCs program using

```auto
disp = calculate_displacements()
disp = disp.replace("log", "std::log") #change log to std log
disp_x0 = dolfin.Expression(sympy.printing.ccode(disp[0]), degree=1)
disp_x1 = dolfin.Expression(sympy.printing.ccode(disp[1]), degree=1)

```

As @nate mentioned, I can’t use disp.replace because replace needs a type, expression or callable in order to replace, but sympy is working with strings. That’s where I am right now, my actual code.

Thanks!

---

<div class="post-metadata">

**Author:** ![francesco-ballarin](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@francesco-ballarin](https://fenicsproject.discourse.group/u/francesco-ballarin)\
**Post date:** [February 29, 2024, 9:46am UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/10 "2024-02-29T09:46:35Z")

</div>

The following works for me

```auto
import dolfin
import sympy
from sympy import symbols, atan2, sqrt, pi, log, sin, cos, Matrix

def calculate_displacements():
    # Definir símbolos
    x, y = symbols('x[0] x[1]')

    # Definir r en términos de x e y
    r_expr = sqrt(x **2 + y** 2)

    # Definir theta en términos de x e y
    theta_expr = atan2(y, x)

    # Definir expresiones analíticas
    gr = 1
    a_expr = cos(theta_expr)
    b_expr = -sin(theta_expr)
    c_expr = sin(theta_expr)
    d_expr = cos(theta_expr)
    u_r_expr = -1/2*cos(theta_expr)-gr*r_expr/(4*pi)*(-1+2*log(r_expr)+cos(2*theta_expr)*(1+2*log(r_expr))+2*(pi-theta_expr)*sin(2*theta_expr))
    u_theta_expr = 1/2*sin(theta_expr)+gr*r_expr/(4*pi)*(2*(theta_expr-pi)*(2-2*cos(2*theta_expr))-(1+2*log(r_expr))*sin(2*theta_expr))

    # Definir las matrices con expresiones
    matriz_2x2 = Matrix([[a_expr, b_expr], [c_expr, d_expr]])
    matriz_2x1 = Matrix([u_r_expr, u_theta_expr])

    # Realizar la multiplicación de matrices con expresiones
    displacements = matriz_2x2 * matriz_2x1
    return displacements

disp = calculate_displacements()
disp_ccode = [sympy.printing.ccode(disp[i]).replace("log", "std::log") for i in (0, 1)]
disp_x0 = dolfin.Expression(disp_ccode[0], degree=1)
disp_x1 = dolfin.Expression(disp_ccode[1], degree=1)

```

---

<div class="post-metadata">

**Author:** ![egomezp](https://avatars.discourse-cdn.com/v4/letter/e/d78d45/32.png) [@egomezp](https://fenicsproject.discourse.group/u/egomezp)\
**Post date:** [February 29, 2024, 9:49am UTC](https://fenicsproject.discourse.group/t/sympy-to-fenics-unable-to-compile/13669/11 "2024-02-29T09:49:10Z")

</div>

Now it seems to be fixed. I’m working on another part of the code which is not working, but this seems fixed.

Thanks again to both of you, and sorry.
