python-3.xphysicssolverequation-solving

Fluid Mechanic Python Solve 4 equations 4 unknown variable


I am solving a fluid mechanic problem where the flow rate is to be determined.

I have the following sets of 4 eqs with 4 unknown variables (v, dot_v, Re,f):

v = dot_v / 0.0113

Re = v* 0.12 / 1.10**-6

1/sqrt(f) = -2*log10(2.51/(Re * sqrt(f))

8 = f* 800/0.12 * v**2 / (2*9.81)

I tried the following code:

import sympy as sym
import numpy as np

Ac = 3.14*0.12*0.12/4

v, dot_v, Re, f = sym.symbols('v, dot_v, Re, f')
eq1 = sym.Eq(dot_v/Ac,v)

eq2 = sym.Eq(v*0.12/(1*10**-6),Re)
eq3 = sym.Eq(-2*np.log10(2.51/(Re*np.sqrt(f))),1/np.sqrt(f))
eq4 = sym.Eq(f*800/0.12*v**2/(2*9.81),8)

result = sym.solve([eq1,eq2,eq3,eq4],(v, dot_v, Re, f))

I have the following errors: TypeError: loop of ufunc does not support argument 0 of type Mul which has no callable log10 method

How can I get the solution ? The solver itself is not my main focus (setting the set of equations was) but I still need to get the numerical solution. Google did not provide me any solution in Python. In past exercices, the flow rate was known thus Re, and I used the bissection method to get f but here flow rate is not known.

Thank you and happy new year


Solution

  • The TypeError likely occurred because sym.Eq did not like np.log10 inside eq3. On the other hand, your purpose would require the use of a numerical solver, since you want to get a numerical solution and sym.solve is rather an analytical solver for symbolic solutions and performs less well for providing numerical solutions. For your purpose, scipy.optimize can potentially be a better tool like in:

    import numpy as np
    from scipy.optimize import fsolve
    
    # Constants
    Ac = 3.14 * 0.12 * 0.12 / 4
    mu = 1 * 10**-6 
    rho = 800  
    D = 0.12  
    
    def equations(var):
        v, dot_v, Re, f = var
        eq1 = dot_v / Ac - v
        eq2 = v * D / mu - Re
        eq3 = -2 * np.log10(2.51 / (Re * np.sqrt(f))) - 1 / np.sqrt(f)
        eq4 = f * rho / D * v**2 / (2 * 9.81) - 8
        return [eq1, eq2, eq3, eq4]
    
    #initial guesses for the solver
    initial_guess = [1, 1, 1e5, 0.02]
    
    solution = fsolve(equations, initial_guess)
    
    v, dot_v, Re, f = solution
    
    print(f"v = {v}")
    print(f"dot_v = {dot_v}")
    print(f"Re = {Re}")
    print(f"f = {f}")
    

    Note that the initial guesses must be more or less good estimates of the solutions to get reliable results.