# Solving a nonlinear equation using NonlinearSolve.jl with AutoFiniteDiff() yields errors about dual number

**URL:** <https://discourse.julialang.org/t/solving-a-nonlinear-equation-using-nonlinearsolve-jl-with-autofinitediff-yields-errors-about-dual-number/112988>\
**Category:** Modelling & Simulations\
**Tags:** finitediff, nonlinearsolve\
**Created:** [April 16, 2024, 3:44am UTC](https://discourse.julialang.org/t/solving-a-nonlinear-equation-using-nonlinearsolve-jl-with-autofinitediff-yields-errors-about-dual-number/112988 "2024-04-16T03:44:15Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![LINGXIAO\_QIN](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lingxiao_qin/32/206239_2.png) [@LINGXIAO\_QIN](https://discourse.julialang.org/u/LINGXIAO_QIN)\
**Post date:** [April 16, 2024, 3:44am UTC](https://discourse.julialang.org/t/solving-a-nonlinear-equation-using-nonlinearsolve-jl-with-autofinitediff-yields-errors-about-dual-number/112988/1 "2024-04-16T03:44:16Z")

</div>

I am trying to solve a nonlinear equation, which is constructed using the thermophysical properties of fluids (via [CoolProp package](https://github.com/CoolProp/CoolProp.jl)).

An MWE is shown below.

```julia
using NonlinearSolve, CoolProp

function myfun_P_MWE(p, (T, init_m))
    r_cont_ads = 10e-3
    r_ads_heat = 2.5e-3
    L = 0.5
    row_GGHS = 3
    row_cont = 3
    row_ads = 10
    delta_r_ads = (r_cont_ads - r_ads_heat) / row_ads

    rho_fre = zeros(typeof(p), row_ads)
    for i in eachindex(rho_fre)
        # Obtain the density of nitrogen according to temperature and pressure
        rho_fre[i] = PropsSI("D", "T", T[row_GGHS+row_cont+i], "P", p, "nitrogen")
    end

    # Construct the nonlinear equation
    f = 0.0
    for i in eachindex(rho_fre)
        f = f + rho_fre[i] * ((r_cont_ads - (i - 1) * delta_r_ads)^2 - (r_cont_ads - i * delta_r_ads)^2) / 2 * L
    end
    return f - init_m
end

# Solving the equation
T = collect(range(200.0, 500.0, 19))
p = 1e5
init_m = 2e-4

# myfun_P_MWE(p,(T, init_m))
p_new = solve(
    NonlinearProblem(myfun_P_MWE, p, (T, init_m))
    # RobustMultiNewton(; autodiff=AutoFiniteDiff())
).u

```

In this case, I am trying to solve the pressure (p) corresponding to a given temperature array (T) and mass (init\_m). The error message is as follows.

```julia
ERROR: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.JacobianWrapper{…}, Float64}, Float64, 1})

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.Sqrt2)
   @ IrrationalConstants C:\Users\qlx\.julia\packages\IrrationalConstants\vp5v4\src\macro.jl:112
  ...

Stacktrace:
  [1] convert(::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.JacobianWrapper{…}, Float64}, Float64, 1})
    @ Base .\number.jl:7
  [2] cconvert(T::Type, x::ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.JacobianWrapper{…}, Float64}, Float64, 1})
    @ Base .\essentials.jl:543
  [3] PropsSI(output::String, name1::String, value1::Float64, name2::String, value2::ForwardDiff.Dual{…}, fluid::String)
    @ CoolProp C:\Users\qlx\.julia\packages\CoolProp\RDEcq\src\CoolProp.jl:81
  [4] myfun_P_MWE(p::ForwardDiff.Dual{ForwardDiff.Tag{…}, Float64, 1}, ::Tuple{Vector{…}, Float64})
    @ Main c:\Users\qlx\Desktop\RB4_AP4_multi_stage_Julia_CoolProp\test2.jl:15
  [5] NonlinearFunction
    @ C:\Users\qlx\.julia\packages\SciMLBase\NjslX\src\scimlfunctions.jl:2185 [inlined]
  [6] JacobianWrapper
    @ C:\Users\qlx\.julia\packages\SciMLBase\NjslX\src\function_wrappers.jl:103 [inlined]
  [7] __value_derivative
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\internal\jacobian.jl:186 [inlined]
  [8] JacobianCache
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\internal\jacobian.jl:118 [inlined]
  [9] JacobianCache
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\internal\jacobian.jl:106 [inlined]
 [10] __step!(cache::NonlinearSolve.GeneralizedFirstOrderAlgorithmCache{…}; recompute_jacobian::Nothing, kwargs::@Kwargs{})
    @ NonlinearSolve C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generalized_first_order.jl:208
 [11] __step!
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generalized_first_order.jl:204 [inlined]
 [12] #step!#210
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:55 [inlined]
 [13] step!
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:50 [inlined]
 [14] solve!(cache::NonlinearSolve.GeneralizedFirstOrderAlgorithmCache{…})
    @ NonlinearSolve C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:13
 [15] #__solve#209
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:4 [inlined]
 [16] __solve
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:1 [inlined]
 [17] macro expansion
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\default.jl:278 [inlined]
 [18] __solve(::NonlinearProblem{…}, ::NonlinearSolvePolyAlgorithm{…}; alias_u0::Bool, verbose::Bool, kwargs::@Kwargs{…})
    @ NonlinearSolve C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\default.jl:248
 [19] __solve
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\default.jl:248 [inlined]
 [20] #__solve#329
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\default.jl:511 [inlined]
 [21] __solve
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\default.jl:508 [inlined]
 [22] #__solve#72
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1394 [inlined]
 [23] __solve
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1386 [inlined]
 [24] #solve_call#44
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:612 [inlined]
 [25] solve_call
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:569 [inlined]
 [26] #solve_up#53
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1072 [inlined]
 [27] solve_up
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1066 [inlined]
 [28] #solve#52
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1060 [inlined]
 [29] solve(::NonlinearProblem{…})
    @ DiffEqBase C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1050
 [30] top-level scope
    @ c:\Users\qlx\Desktop\RB4_AP4_multi_stage_Julia_CoolProp\test2.jl:33
Some type information was truncated. Use `show(err)` to see complete types.

```

It looks like the error is because `PropsSI()` cannot accept a dual number as an argument. Following the [FAQ: The solver tried to set a Dual Number in my Vector of Floats. How do I fix that?](https://docs.sciml.ai/NonlinearSolve/stable/basics/faq/) in the NonlinearSolve.jl documentation, I have initialized the `rho_fre` with the same element type as `p`, but that doesn’t help.

I am not familiar with dual number, by google what it is, I think it is used when automatically differentiating the objective function. Therefore, I tried another solution in the [FAQ](https://docs.sciml.ai/NonlinearSolve/stable/basics/faq/), which is to specify the `autodiff` to be `AutoFiniteDiff()`. The revised code is as follows, but it yields the same error message, complaining about the dual number usage in `PropsSI()`.

```julia
using NonlinearSolve, CoolProp

function myfun_P_MWE(p, (T, init_m))
    r_cont_ads = 10e-3
    r_ads_heat = 2.5e-3
    L = 0.5
    row_GGHS = 3
    row_cont = 3
    row_ads = 10
    delta_r_ads = (r_cont_ads - r_ads_heat) / row_ads

    rho_fre = zeros(typeof(p), row_ads)
    for i in eachindex(rho_fre)
        # Obtain the density of nitrogen according to temperature and pressure
        rho_fre[i] = PropsSI("D", "T", T[row_GGHS+row_cont+i], "P", p, "nitrogen")
    end

    # Construct the nonlinear equation
    f = 0.0
    for i in eachindex(rho_fre)
        f = f + rho_fre[i] * ((r_cont_ads - (i - 1) * delta_r_ads)^2 - (r_cont_ads - i * delta_r_ads)^2) / 2 * L
    end
    return f - init_m
end

# Solving the equation
T = collect(range(200.0, 500.0, 19))
p = 1e5
init_m = 2e-4

# myfun_P_MWE(p,(T, init_m))
p_new = solve(
    NonlinearProblem(myfun_P_MWE, p, (T, init_m)),
    RobustMultiNewton(; autodiff=AutoFiniteDiff())
).u

```

```julia
ERROR: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.JacobianWrapper{…}, Float64}, Float64, 1})

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.Sqrt2)
   @ IrrationalConstants C:\Users\qlx\.julia\packages\IrrationalConstants\vp5v4\src\macro.jl:112
  ...

Stacktrace:
  [1] convert(::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.JacobianWrapper{…}, Float64}, Float64, 1})
    @ Base .\number.jl:7
  [2] cconvert(T::Type, x::ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.JacobianWrapper{…}, Float64}, Float64, 1})
    @ Base .\essentials.jl:543
  [3] PropsSI(output::String, name1::String, value1::Float64, name2::String, value2::ForwardDiff.Dual{…}, fluid::String)
    @ CoolProp C:\Users\qlx\.julia\packages\CoolProp\RDEcq\src\CoolProp.jl:81
  [4] myfun_P_MWE(p::ForwardDiff.Dual{ForwardDiff.Tag{…}, Float64, 1}, ::Tuple{Vector{…}, Float64})
    @ Main c:\Users\qlx\Desktop\RB4_AP4_multi_stage_Julia_CoolProp\test2.jl:15
  [5] NonlinearFunction
    @ C:\Users\qlx\.julia\packages\SciMLBase\NjslX\src\scimlfunctions.jl:2185 [inlined]
  [6] JacobianWrapper
    @ C:\Users\qlx\.julia\packages\SciMLBase\NjslX\src\function_wrappers.jl:103 [inlined]
  [7] __value_derivative
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\internal\jacobian.jl:186 [inlined]
  [8] JacobianCache
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\internal\jacobian.jl:118 [inlined]
  [9] JacobianCache
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\internal\jacobian.jl:106 [inlined]
 [10] __step!(cache::NonlinearSolve.GeneralizedFirstOrderAlgorithmCache{…}; recompute_jacobian::Nothing, kwargs::@Kwargs{})
    @ NonlinearSolve C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generalized_first_order.jl:208
 [11] __step!
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generalized_first_order.jl:204 [inlined]
 [12] #step!#210
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:55 [inlined]
 [13] step!
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:50 [inlined]
 [14] solve!(cache::NonlinearSolve.GeneralizedFirstOrderAlgorithmCache{…})
    @ NonlinearSolve C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:13
 [15] #__solve#209
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:4 [inlined]
 [16] __solve
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\core\generic.jl:1 [inlined]
 [17] macro expansion
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\default.jl:278 [inlined]
 [18] __solve(::NonlinearProblem{…}, ::NonlinearSolvePolyAlgorithm{…}; alias_u0::Bool, verbose::Bool, kwargs::@Kwargs{})
    @ NonlinearSolve C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\default.jl:248
 [19] __solve
    @ C:\Users\qlx\.julia\packages\NonlinearSolve\R8LAH\src\default.jl:248 [inlined]
 [20] #solve_call#44
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:612 [inlined]
 [21] solve_call
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:569 [inlined]
 [22] #solve_up#53
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1072 [inlined]
 [23] solve_up
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1066 [inlined]
 [24] #solve#52
    @ C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1060 [inlined]
 [25] solve(prob::NonlinearProblem{…}, args::NonlinearSolvePolyAlgorithm{…})
    @ DiffEqBase C:\Users\qlx\.julia\packages\DiffEqBase\O8cUq\src\solve.jl:1050
 [26] top-level scope
    @ c:\Users\qlx\Desktop\RB4_AP4_multi_stage_Julia_CoolProp\test2.jl:33
Some type information was truncated. Use `show(err)` to see complete types.

```

My questions are:

1. Should the `PropsSI()` function in the [CoolProp package](https://github.com/CoolProp/CoolProp.jl) be modified to accept a dual number as an argument?

2. Why does the `AutoFiniteDiff()` still yield the error about dual number? I expect this error only happens when automatic differentiation is used.

I would greatly appreciate any guidance or workarounds to successfully solve this equation.

Here is my Julia and package version info:

```julia
Julia Version 1.10.2
Commit bd47eca2c8 (2024-03-01 10:14 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 12 × Intel(R) Core(TM) i5-10400F CPU @ 2.90GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, skylake)
Threads: 12 default, 0 interactive, 6 GC (on 12 virtual cores)
Environment:
  JULIA_EDITOR = code

```

```julia
  [6e4b80f9] BenchmarkTools v1.5.0
  [e084ae63] CoolProp v0.2.0
  [0c46a032] DifferentialEquations v7.13.0
  [6a86dc24] FiniteDiff v2.23.0
  [f6369f11] ForwardDiff v0.10.36
  [86223c79] Graphs v1.10.0
  [10e44e05] MATLAB v0.8.4
⌃ [961ee093] ModelingToolkit v9.9.0
  [8913a72c] NonlinearSolve v3.9.1
  [7f7a1694] Optimization v3.24.3
  [4e6fcdb7] OptimizationNLopt v0.2.0
⌃ [91a5bcdd] Plots v1.40.3
Info Packages marked with ⌃ have new versions available and may be upgradable.

```

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [April 16, 2024, 10:44am UTC](https://discourse.julialang.org/t/solving-a-nonlinear-equation-using-nonlinearsolve-jl-with-autofinitediff-yields-errors-about-dual-number/112988/2 "2024-04-16T10:44:17Z")

</div>

This looks like a bug. Report it to NonlinearSolve.jl

---

<div class="post-metadata">

**Author:** ![LINGXIAO\_QIN](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lingxiao_qin/32/206239_2.png) [@LINGXIAO\_QIN](https://discourse.julialang.org/u/LINGXIAO_QIN)\
**Post date:** [April 16, 2024, 12:13pm UTC](https://discourse.julialang.org/t/solving-a-nonlinear-equation-using-nonlinearsolve-jl-with-autofinitediff-yields-errors-about-dual-number/112988/3 "2024-04-16T12:13:18Z")

</div>

Thanks for your reply. I have reported a [github issue](https://github.com/SciML/NonlinearSolve.jl/issues/408) to NonlinearSolve.jl. By the way, I found a similar issue [TrustRegion(radius\_update\_scheme=RadiusUpdateSchemes.Bastin) doesn’t respect autodiff setting](https://github.com/SciML/NonlinearSolve.jl/issues/360) being reported, but using `TrustRegion()` still does not resolve my problem.
