Search code examples
julianonlinear-functionsmodelingtoolkit

Julia throws MethodError: no method matching, with CoolProp using NonlinearSystem


I'm trying to get Julia's NonlinearSolve to play well with CoolProp. I am very new at Julia, coming from many years of Python, so I am still learning the ropes.

This is the code that is giving me trouble:

using ModelingToolkit, NonlinearSolve, CoolProp


@variables dm ρ1
@parameters a1 T1 P1

# Define a nonlinear system
eqs = [
    ρ1 ~ PropsSI("D","T",T1,"P",P1,"AIR"),
    k1 ~ PropsSI("ISENTROPIC_EXPANSION_COEFFICIENT","T",T1,"P",P1,"AIR"),
    dm ~ a1 * sqrt(k1*ρ1*P1*(2/(k1+1))^((k1+1)/(k1-1)))
    ]
@mtkbuild ns = NonlinearSystem(eqs, [dm, ρ1], [a1, T1, P1])


d1 = 0.15e-3

guess = [
    dm => 0.5e-3,
    ρ1 => 20 
    ]

ps = [
        P1 => 20e5,
        a1 => (d1/2)^2 * pi,
        T1 => 293.0
    ]

prob = NonlinearProblem(ns, guess, ps)
sol = solve(prob, NewtonRaphson())

And it returns this error:

MethodError: no method matching Float64(::Num)

Closest candidates are:
  (::Type{T})(::Real, ::RoundingMode) where T<:AbstractFloat
   @ Base rounding.jl:207
  (::Type{T})(::T) where T<:Number
   @ Core boot.jl:792
  Float64(::IrrationalConstants.Logtwo)
   @ IrrationalConstants ~/.julia/packages/IrrationalConstants/vp5v4/src/macro.jl:112
  ...


Stacktrace:
 [1] convert(::Type{Float64}, x::Num)
   @ Base ./number.jl:7
 [2] cconvert(T::Type, x::Num)
   @ Base ./essentials.jl:543
 [3] PropsSI(output::String, name1::String, value1::Num, name2::String, value2::Num, fluid::String)
   @ CoolProp ~/.julia/packages/CoolProp/RDEcq/src/CoolProp.jl:81
 [4] top-level scope
   @ In[81]:8

I would expect this to just work but clearly there's something here that I misunderstand. I also know that I could solve this system analytically, but this is a baby step before building a bigger system.

I think I understand that it is the wrong type being passed to the PropsSI function, but I don't understand how to troubleshoot this any further, and methoderror seems quite common for newbies with Julia. Can I simply convert the types?

I have based my example on the documentation for NonlinearSolve, and it seems clear to me that it's CoolProp giving the issue.

I can pass variables to CoolProp and get meaningful returns, as I would in Python, just fine, but I don't understand why it breaks when I try to use in in a system of equations here.


Solution

  • The solution was found in @register_symbolic

    The code below works as I want it to.

    using ModelingToolkit, NonlinearSolve, CoolProp
    
    air_density_tp(t,p) = PropsSI("D", "T", t, "P", p, "AIR")
    air_isentropic_coef_tp(t,p) = PropsSI("ISENTROPIC_EXPANSION_COEFFICIENT", "T", t, "P", p, "AIR")
    
    @variables dm r1 k1
    @parameters a1 T1 P1
    @register_symbolic air_density_tp(t,p) 
    @register_symbolic air_isentropic_coef_tp(t,p)
    
    # Define a nonlinear system
    eqs = [
        r1 ~ air_density_tp(T1,P1),
        k1 ~ air_isentropic_coef_tp(T1,P1),
        dm ~ a1 * sqrt(k1*r1*P1*(2/(k1+1))^((k1+1)/(k1-1)))
        ]
    @mtkbuild ns = NonlinearSystem(eqs, [dm, r1, k1], [a1, T1, P1])
    
    
    d1 = 0.15e-3
    
    guess = [
        dm => 0.5e-3,
        r1 => 20,
        k1 => 1.4
        ]
    
    ps = [
        a1 => (d1/2)^2 * pi,
        T1 => 293.0,
        P1 => 20e5
        ]
    
    prob = NonlinearProblem(ns, guess, ps)
    sol = solve(prob, NewtonRaphson())