Ryan
Ryan

Reputation: 16

odeint -(TypeError: can't convert expression to float ) - Importing expression into a function to perform odeint

This is the error I get

Traceback (most recent call last):

  File "C:\Users\user\.spyder-py3\Numerical Methods Problems\FreeFall.py", line 40, in <module>
    ans=odeint(vel,0,t)

  File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\integrate\odepack.py", line 245, in odeint
    int(bool(tfirst)))

  File "C:\ProgramData\Anaconda3\lib\site-packages\sympy\core\expr.py", line 325, in __float__
    raise TypeError("can't convert expression to float")

TypeError: can't convert expression to float

And Here is my code - I am pretty new to coding and am learning to use it for numerical computation:

from scipy.integrate import odeint
from sympy import *
import numpy as np
import math

def diff_cd(re_no):
    Re=Symbol('Re')
    expr=(24/Re)+(6/(1+(Re**0.5)))+0.4
    ans=diff(expr,Re).subs(Re,re_no)    
    return ans

def diff_re(k,u_no):
    u=Symbol('u')
    expr=k*u
    ans=diff(expr,u).subs(u,u_no)
    return ans    

ans = [diff_cd(20),diff_re(11,15)]

rhog=1.2
mug=1.872*(10**(-5))
a=0.3

u=Symbol('u')
pi=math.pi

k=(2*rhog*a/mug)
Re=k*u

p1=(rhog*pi*(a**2)*u*Re*((24/Re)+(6/(1+(Re**0.5)))+0.4))+(0.5*rhog*pi*(a**2)*(u**2)*diff_cd(Re)*diff_re(k,u))

ansfu=p1*(-1/24)


def vel(y,t):
    dudt = ansfu
    return dudt

t=np.linspace(1,100,100)
ans=odeint(vel,0,t)


print(ans)

I just need is to get an answer without this error. Also is there a way to do all this in a single function

Upvotes: 0

Views: 488

Answers (2)

Tim
Tim

Reputation: 6671

Old question but it seems you could've solved this problem using sympy's lambdify function. You'd do it like this:

f = lambdify(x, x**2, modules=['scipy'])

now f is a lambda that you can use with scipy.

Upvotes: 1

hpaulj
hpaulj

Reputation: 231738

If I add a print(vel(0,0)) before the ode call I get

-271.868595022194*u**2*(-3.97723522060237e-7*u**(-0.5)/(u**0.5 +
0.00509901951359279)**2 - 1.6224e-8/u**2) - 
543.737190044387*u**2*(0.4 + 6/(196.116135138184*u**0.5 + 1) + 0.000624/u)

That is, a sympy expression, not a number. odeint cannot work with that!

u is defined as Symbol, and thus any python expression using it will also be a sympy expression.

Especially if you are new to coding, you should stick with one package or the other. If defining the function symbolically, then use sympy and its own solvers. But if a numeric solution of the kind that scipy produces is important, then define the function with python/numpy. Don't try to mix sympy and numpy (without a lot more experience).

Upvotes: 1

Related Questions