How to solve a nonlinear problem

I have the following code and I am trying to solve a nonlinear problem

using MAT
using NonlinearSolve
using FiniteDifferences
include("../src/Tether_quasistatic.jl")

function get_init_cond(filename)
    vars = matread(filename); 
    stateVec = vec(get(vars,"stateVec", 0));
    kitePos = vec(get(vars,"kitePos", 0));
    kiteVel = vec(get(vars,"kiteVel", 0));
    windVel = get(vars,"windVel", 0);
    tetherLength = get(vars,"tetherLength", 0);

    ENVMT = get(vars,"ENVMT", 0) 
    rho_air = get(ENVMT, "rhos", 0) 
    g_earth = [0; 0; -abs(get(ENVMT, "g", 0))]      # in this way g_earth is a vector [0; 0; -9.81]

        T = get(vars,"T", 0);
    cd_tether = get(T, "CD_tether", 0) 
    d_tether = get(T, "d_tether", 0)*1000           # tether diameter                  [mm]
    rho_tether = get(T, "rho_t", 0) 
    E = get(T, "E", 0) 
    A = get(T, "A", 0)
    c_spring = E*A 

    settings = Settings(rho_air, g_earth, cd_tether, d_tether, rho_tether, c_spring)

    return stateVec, kitePos, kiteVel, windVel, tetherLength, settings
end

function get_output_objfun(filename)
    vars        = matread(filename); 
    Fobj        = vec(get(vars,"Fobj", 0))
    p0          = vec(get(vars,"p0", 0))
    pj          = get(vars,"pj", 0)
    T0          = vec(get(vars,"T0", 0)) 
    return Fobj, p0, pj, T0
end

# Get information from the .mat
stateVec, kitePos, kiteVel, windVel, tetherLength, settings = get_init_cond("test/data/input_basic_test.mat")

Fobj, p0, pj, T0 = get_output_objfun("test/data/basic_test_results.mat")

function nlfun!(resid, stateVec, p)
    # Unpack parameters
    kitePos, kiteVel, windVel, tetherLength, settings = p  

    # Call objFun and extract only Fobj
    Fobj, _, _, _ = objFun(stateVec, kitePos, kiteVel, windVel, tetherLength, settings)

    # Update resid in-place
    resid .= Fobj;  # Ensure this matches the expected size of resid
    nothing
end
p = (kitePos, kiteVel, windVel, tetherLength, settings)

nlfun!([0.0, 0, 0], stateVec, p)

prob = NonlinearProblem(nlfun!, stateVec, p)

# Solve the problem
sol = solve(prob; show_trace = Val(true), trace_level = TraceAll(10))

If I run the code I get the following error:

ERROR: LoadError: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{DifferentiationInterface.FixTail{NonlinearFunction{…}, Tuple{…}}, Float64}, Float64, 3})

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.Twoinvπ)
   @ IrrationalConstants C:\Users\andre\.julia\packages\IrrationalConstants\lWTip\src\macro.jl:131
  ...

Stacktrace:
  [1] convert(::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{DifferentiationInterface.FixTail{NonlinearFunction{…}, Tuple{…}}, Float64}, Float64, 3})
    @ Base .\number.jl:7
  [2] setindex!
    @ .\array.jl:1024 [inlined]
  [3] macro expansion
    @ .\multidimensional.jl:960 [inlined]
  [4] macro expansion
    @ .\cartesian.jl:64 [inlined]
  [5] _unsafe_setindex!
    @ .\multidimensional.jl:955 [inlined]
  [6] _setindex!
    @ .\multidimensional.jl:944 [inlined]
  [7] setindex!
    @ .\abstractarray.jl:1395 [inlined]
  [8] objFun(stateVec::Vector{ForwardDiff.Dual{…}}, kitePos::Vector{Float64}, kiteVel::Vector{Float64}, windVel::Matrix{Float64}, tetherLength::Float64, settings::Settings)
    @ Main C:\Users\andre\repos\Tethers.jl\src\Tether_quasistatic.jl:44
  [9] nlfun!(resid::Vector{ForwardDiff.Dual{…}}, stateVec::Vector{ForwardDiff.Dual{…}}, p::Tuple{Vector{…}, Vector{…}, Matrix{…}, Float64, Settings})
    @ Main C:\Users\andre\repos\Tethers.jl\examples\run_catenary.jl:51
 [10] NonlinearFunction
    @ C:\Users\andre\.julia\packages\SciMLBase\sYmAV\src\scimlfunctions.jl:2469 [inlined]
 [11] FixTail
    @ C:\Users\andre\.julia\packages\DifferentiationInterface\qrWdQ\src\utils\context.jl:7 [inlined]
 [12] vector_mode_dual_eval!
    @ C:\Users\andre\.julia\packages\ForwardDiff\UBbGT\src\apiutils.jl:31 [inlined]
 [13] vector_mode_jacobian(f!::DifferentiationInterface.FixTail{…}, y::Vector{…}, x::Vector{…}, cfg::ForwardDiff.JacobianConfig{…})
    @ ForwardDiff C:\Users\andre\.julia\packages\ForwardDiff\UBbGT\src\jacobian.jl:139
 [14] jacobian
    @ C:\Users\andre\.julia\packages\ForwardDiff\UBbGT\src\jacobian.jl:40 [inlined]
 [15] jacobian(f!::NonlinearFunction{…}, y::Vector{…}, prep::DifferentiationInterfaceForwardDiffExt.ForwardDiffTwoArgJacobianPrep{…}, backend::AutoForwardDiff{…}, x::Vector{…}, contexts::DifferentiationInterface.Constant{…})
    @ DifferentiationInterfaceForwardDiffExt C:\Users\andre\.julia\packages\DifferentiationInterface\qrWdQ\ext\DifferentiationInterfaceForwardDiffExt\twoarg.jl:433        
 [16] NonlinearSolve.JacobianCache(prob::NonlinearProblem{…}, alg::GeneralizedFirstOrderAlgorithm{…}, f::NonlinearFunction{…}, fu_::Vector{…}, u::Vector{…}, p::Tuple{…}; stats::SciMLBase.NLStats, autodiff::Nothing, vjp_autodiff::Nothing, jvp_autodiff::Nothing, linsolve::Nothing)
    @ NonlinearSolve C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\internal\jacobian.jl:89
 [17] JacobianCache
    @ C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\internal\jacobian.jl:47 [inlined]
 [18] __init(::NonlinearProblem{…}, ::GeneralizedFirstOrderAlgorithm{…}; stats::SciMLBase.NLStats, alias_u0::Bool, maxiters::Int64, abstol::Nothing, reltol::Nothing, maxtime::Nothing, termination_condition::Nothing, internalnorm::Function, linsolve_kwargs::@NamedTuple{}, kwargs::@Kwargs{…})
    @ NonlinearSolve C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\core\generalized_first_order.jl:175
 [19] __init
    @ C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\core\generalized_first_order.jl:156 [inlined]
 [20] __solve(::NonlinearProblem{…}, ::GeneralizedFirstOrderAlgorithm{…}; stats::SciMLBase.NLStats, kwargs::@Kwargs{…})
    @ NonlinearSolve C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\core\generic.jl:3
 [21] __solve
    @ C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\core\generic.jl:1 [inlined]
 [22] macro expansion
    @ C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\default.jl:282 [inlined]
 [23] __solve(::NonlinearProblem{…}, ::NonlinearSolvePolyAlgorithm{…}; stats::SciMLBase.NLStats, alias_u0::Bool, verbose::Bool, kwargs::@Kwargs{…})
    @ NonlinearSolve C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\default.jl:255
 [24] __solve
    @ C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\default.jl:255 [inlined]
 [25] #__solve#251
    @ C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\default.jl:527 [inlined]
 [26] __solve
    @ C:\Users\andre\.julia\packages\NonlinearSolve\sBl1H\src\default.jl:524 [inlined]
 [27] #__solve#63
    @ C:\Users\andre\.julia\packages\DiffEqBase\PbBEl\src\solve.jl:1437 [inlined]
 [28] __solve
    @ C:\Users\andre\.julia\packages\DiffEqBase\PbBEl\src\solve.jl:1428 [inlined]
 [29] solve_call(::NonlinearProblem{…}; merge_callbacks::Bool, kwargshandle::Nothing, kwargs::@Kwargs{…})
    @ DiffEqBase C:\Users\andre\.julia\packages\DiffEqBase\PbBEl\src\solve.jl:635
 [30] solve_call
    @ C:\Users\andre\.julia\packages\DiffEqBase\PbBEl\src\solve.jl:592 [inlined]
 [31] #solve_up#44
    @ C:\Users\andre\.julia\packages\DiffEqBase\PbBEl\src\solve.jl:1112 [inlined]
 [32] solve_up
    @ C:\Users\andre\.julia\packages\DiffEqBase\PbBEl\src\solve.jl:1106 [inlined]
 [33] #solve#43
    @ C:\Users\andre\.julia\packages\DiffEqBase\PbBEl\src\solve.jl:1100 [inlined]
 [34] top-level scope
    @ C:\Users\andre\repos\Tethers.jl\examples\run_catenary.jl:71
 [35] include(fname::String)
    @ Base.MainInclude .\client.jl:494
 [36] top-level scope
    @ REPL[4]:1
in expression starting at C:\Users\andre\repos\Tethers.jl\examples\run_catenary.jl:71
Some type information was truncated. Use `show(err)` to see complete types.

How can I use FiniteDifferences to avoid this error?

Welcome to the Julia community! I mainly used NLSolve.jl in the past and did not learn yet how to use NonlinearSolve.jl instead.

1 Like
using ADTypes
sol = solve(prob, TrustRegion(autodiff=AutoFiniteDiff()); show_trace = Val(true), trace_level = TraceAll(10))
2 Likes

Alternatively, you could use a derivative-free root-finding algorithm, like Broyden or Anderson acceleration.

2 Likes
sol = solve(prob, Broyden(); show_trace = Val(true), trace_level = TraceAll(10))

or one of Fixed Point Solvers · NonlinearSolve.jl for reference.

1 Like

Thank you! I am now using

sol = solve(prob, LevenbergMarquardt(autodiff=AutoFiniteDiff()); show_trace = Val(true)) 

and it works!

1 Like