Search code examples
pythonsympysolvernonlinear-functions

Non-linear equation solving Sympy Python for hydraulics - Need resolve TypeError("can't convert expression to float")


I am trying to write a piece of python script to automate a quite time consuming task in some hydraulics problems, that occur in civil engineering.

The equation is from Colebrook-White, and is the following:

I have written the following code:

from math  import *
from sympy import *

e    = 0.2
d    = 0.2
v    = 0.00000131
q    = 10
s    = ( pi * d ** 2 ) / 4
u    = q / s
re   = u * d / v

lamb = symbols( 'lamb' )

solve(   1 / sqrt( lamb )                               \
       + 2 * log10(   e / ( 3.7 * d )                   \
                    + 2.51 / ( re * sqrt( lamb ) )      \
                  ),                                    \
         lamb                                           \
     )

But it gives the error:

   File "hg.py", line 12, in <module>
   solve(1/sqrt(lamb) + 2*log10(k/(3.7*d) + 2.51/(re*sqrt(lamb))),lamb)
   File "/home/luis/Documents/sympy/sympy/core/expr.py", line 211, in __float__
   raise TypeError("can't convert expression to float")
   TypeError: can't convert expression to float

I couldn't post a picture of how the equation looks, as im new.

Since sqrt(lambda) is in both sides of the equation, I think it has to be solved by an iterative method, but I don't know how to do it... On my calculator (TI-Voyage 200) I usually use nSolve() and it does the job.

Thanks in advance!


Solution

  • You are still using log10 instead of log( expr, 10 ). Correcting that and using bisection with nsolve works:

    >>> eq = 1/sqrt(lamb) + 2*log(e/(3.7*d) + 2.51/(re*sqrt(lamb)), 10)
    >>> nsolve(eq,lamb, (.1, 1.1), method='bisect')
    mpf('0.77434599870454337')
    

    See help( mpmath.findroot ) for other solver options besides bisect.