Skip to content

Commit c690175

Browse files
Fix interpretation of nonlinear system overdetermined defaults
```julia using ModelingToolkit, NonlinearSolve # Define the nonlinear system @variables x=1.0 y z=0.0 @parameters σ=10.0 ρ=26.0 β=8 / 3 eqs = [0 ~ σ * (y - x), 0 ~ x * (ρ - z) - y, 0 ~ x * y - β * z] @mtkbuild ns = NonlinearSystem(eqs, [x, y, z], [σ, ρ, β]) # Convert the symbolic system into a numerical system prob = NonlinearProblem(ns, []) # Solve the numerical problem sol = solve(prob, NewtonRaphson()) ``` This failed because of an initialization failure. This is because those conditions cannot be satisfied with the nonlinear system. But that doesn't make sense: the purpose of a nonlinear system is to find the set of values that satisfies the system. So this case should not be building initialization problems, there is no reason to assume that the user's initial guess satisfies the system, and in fact, you should assume if basically never does as the point is to solve the system. There can be an argument to have the initialization specifically for the parameters, but that can be added in the future. For now, this is fixing a major regression and adding a test to make sure this doesn't regress again. OptimizationSystem should be similarly checked as its initial conditions should be handled similarly.
1 parent f497ae0 commit c690175

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

src/systems/nonlinear/nonlinearsystem.jl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ function DiffEqBase.NonlinearProblem{iip}(sys::NonlinearSystem, u0map,
539539
end
540540
end
541541
f, u0, p = process_SciMLProblem(NonlinearFunction{iip}, sys, u0map, parammap;
542-
check_length, kwargs...)
542+
check_length, build_initializeprob = false, kwargs...)
543543
pt = something(get_metadata(sys), StandardNonlinearProblem())
544544
NonlinearProblem{iip}(f, u0, p, pt; filter_kwargs(kwargs)...)
545545
end
@@ -568,7 +568,7 @@ function DiffEqBase.NonlinearLeastSquaresProblem{iip}(sys::NonlinearSystem, u0ma
568568
error("A completed `NonlinearSystem` is required. Call `complete` or `structural_simplify` on the system before creating a `NonlinearLeastSquaresProblem`")
569569
end
570570
f, u0, p = process_SciMLProblem(NonlinearFunction{iip}, sys, u0map, parammap;
571-
check_length, kwargs...)
571+
check_length, build_initializeprob = false, kwargs...)
572572
pt = something(get_metadata(sys), StandardNonlinearProblem())
573573
NonlinearLeastSquaresProblem{iip}(f, u0, p; filter_kwargs(kwargs)...)
574574
end
@@ -681,7 +681,8 @@ function SciMLBase.SCCNonlinearProblem{iip}(sys::NonlinearSystem, u0map,
681681
obs = observed(sys)
682682

683683
_, u0, p = process_SciMLProblem(
684-
EmptySciMLFunction, sys, u0map, parammap; eval_expression, eval_module, kwargs...)
684+
EmptySciMLFunction, sys, u0map, parammap; eval_expression, eval_module,
685+
build_initializeprob = false, kwargs...)
685686

686687
explicitfuns = []
687688
nlfuns = []
@@ -832,7 +833,8 @@ function DiffEqBase.IntervalNonlinearProblem(sys::NonlinearSystem, uspan::NTuple
832833
error("`IntervalNonlinearProblem` only supports with a single equation and a single unknown.")
833834
end
834835
f, u0, p = process_SciMLProblem(
835-
IntervalNonlinearFunction, sys, unknowns(sys) .=> uspan[1], parammap; kwargs...)
836+
IntervalNonlinearFunction, sys, unknowns(sys) .=> uspan[1], parammap;
837+
build_initializeprob = false, kwargs...)
836838

837839
return IntervalNonlinearProblem(f, uspan, p; filter_kwargs(kwargs)...)
838840
end
@@ -865,7 +867,7 @@ function NonlinearProblemExpr{iip}(sys::NonlinearSystem, u0map,
865867
error("A completed `NonlinearSystem` is required. Call `complete` or `structural_simplify` on the system before creating a `NonlinearProblemExpr`")
866868
end
867869
f, u0, p = process_SciMLProblem(NonlinearFunctionExpr{iip}, sys, u0map, parammap;
868-
check_length, kwargs...)
870+
check_length, build_initializeprob = false, kwargs...)
869871
linenumbers = get(kwargs, :linenumbers, true)
870872

871873
ex = quote
@@ -905,7 +907,7 @@ function NonlinearLeastSquaresProblemExpr{iip}(sys::NonlinearSystem, u0map,
905907
error("A completed `NonlinearSystem` is required. Call `complete` or `structural_simplify` on the system before creating a `NonlinearProblemExpr`")
906908
end
907909
f, u0, p = process_SciMLProblem(NonlinearFunctionExpr{iip}, sys, u0map, parammap;
908-
check_length, kwargs...)
910+
check_length, build_initializeprob = false, kwargs...)
909911
linenumbers = get(kwargs, :linenumbers, true)
910912

911913
ex = quote
@@ -933,7 +935,8 @@ function IntervalNonlinearProblemExpr(sys::NonlinearSystem, uspan::NTuple{2},
933935
error("`IntervalNonlinearProblemExpr` only supports with a single equation and a single unknown.")
934936
end
935937
f, u0, p = process_SciMLProblem(
936-
IntervalNonlinearFunctionExpr, sys, unknowns(sys) .=> uspan[1], parammap; kwargs...)
938+
IntervalNonlinearFunctionExpr, sys, unknowns(sys) .=> uspan[1], parammap;
939+
build_initializeprob = false, kwargs...)
937940
linenumbers = get(kwargs, :linenumbers, true)
938941

939942
ex = quote

test/nonlinearsystem.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,3 +380,22 @@ end
380380
@test_throws ["single equation", "unknown"] IntervalNonlinearFunctionExpr(
381381
sys, (0.0, 1.0))
382382
end
383+
384+
@testset "Overconditioned Initial Conditions" begin
385+
# Define the nonlinear system
386+
@variables x=1.0 y=0.0 z=0.0
387+
@parameters σ=10.0 ρ=26.0 β=8 / 3
388+
389+
eqs = [0 ~ σ * (y - x),
390+
0 ~ x *- z) - y,
391+
0 ~ x * y - β * z]
392+
@mtkbuild ns = NonlinearSystem(eqs, [x, y, z], [σ, ρ, β])
393+
394+
# Convert the symbolic system into a numerical system
395+
prob = NonlinearProblem(ns, [])
396+
397+
# Solve the numerical problem
398+
sol = solve(prob, NewtonRaphson())
399+
@test SciMLBase.successful_retcode(sol)
400+
@test norm(sol.resid) < 1e-12
401+
end

0 commit comments

Comments
 (0)