1+ " Abstract supertype of all differential equation solvers."
2+ abstract type DiffSolver end
3+
4+ " Empty solver for nonlinear discrete-time models."
5+ struct EmptySolver <: DiffSolver
6+ ni:: Int # number of intermediate stages
7+ EmptySolver () = new (- 1 )
8+ end
9+
10+ " Call `f!` function directly for discrete-time models (no solver)."
11+ function solver_f! (xnext, _ , f!:: F , _ , :: EmptySolver , x, u, d, p) where F
12+ return f! (xnext, x, u, d, p)
13+ end
14+
15+ Base. show (io:: IO , :: EmptySolver ) = print (io, " Empty differential equation solver." )
16+
117struct NonLinModel{
218 NT<: Real ,
3- F<: Function ,
4- H<: Function ,
5- PT<: Any ,
619 DS<: DiffSolver ,
20+ F <: Function ,
21+ H <: Function ,
22+ PT<: Any ,
723 JB<: AbstractADType ,
824 LF<: Function
925} <: SimModel{NT}
1026 x0:: Vector{NT}
11- solver_f!:: F
12- solver_h!:: H
13- p:: PT
1427 solver:: DS
28+ f!:: F
29+ h!:: H
30+ p:: PT
1531 Ts:: NT
1632 t:: Vector{NT}
1733 nu:: Int
@@ -32,14 +48,14 @@ struct NonLinModel{
3248 linfunc!:: LF
3349 buffer:: SimModelBuffer{NT}
3450 function NonLinModel {NT} (
35- solver_f !:: F , solver_h !:: H , Ts, nu, nx, ny, nd,
36- p:: PT , solver :: DS , jacobian:: JB , linfunc!:: LF
51+ solver :: DS , f !:: F , h !:: H , Ts, nu, nx, ny, nd,
52+ p:: PT , jacobian:: JB , linfunc!:: LF
3753 ) where {
3854 NT<: Real ,
55+ DS<: DiffSolver ,
3956 F<: Function ,
4057 H<: Function ,
4158 PT<: Any ,
42- DS<: DiffSolver ,
4359 JB<: AbstractADType ,
4460 LF<: Function
4561 }
@@ -58,11 +74,11 @@ struct NonLinModel{
5874 ni = solver. ni
5975 nk = nx* (ni+ 1 )
6076 buffer = SimModelBuffer {NT} (nu, nx, ny, nd, ni)
61- return new {NT, F, H, PT, DS , JB, LF} (
77+ return new {NT, DS, F, H, PT, JB, LF} (
6278 x0,
63- solver_f!, solver_h! ,
64- p ,
65- solver ,
79+ solver ,
80+ f!, h! ,
81+ p ,
6682 Ts, t,
6783 nu, nx, ny, nd, nk,
6884 uop, yop, dop, xop, fop,
@@ -136,7 +152,7 @@ julia> f!(ẋ, x, u, _ , p) = (ẋ .= p*x .+ u; nothing);
136152julia> h!(y, x, _ , _ ) = (y .= 0.1x; nothing);
137153
138154julia> model1 = NonLinModel(f!, h!, 5.0, 1, 1, 1, p=-0.2) # continuous dynamics
139- NonLinModel with a sample time Ts = 5.0 s, RungeKutta(4) solver and:
155+ NonLinModel with a sample time Ts = 5.0 s, RungeKutta{4} solver and:
140156 1 manipulated inputs u
141157 1 states x
142158 1 outputs y
@@ -176,12 +192,11 @@ function NonLinModel{NT}(
176192) where {NT<: Real }
177193 isnothing (solver) && (solver= EmptySolver ())
178194 f!, h! = get_mutating_functions (NT, f, h)
179- solver_f!, solver_h! = get_solver_functions (NT, solver, f!, h!, Ts, nu, nx, ny, nd)
180195 linfunc! = get_linearization_func (
181- NT, solver_f !, solver_h! , nu, nx, ny, nd, p, solver, jacobian
196+ NT, f !, h!, Ts , nu, nx, ny, nd, p, solver, jacobian
182197 )
183198 return NonLinModel {NT} (
184- solver_f !, solver_h !, Ts, nu, nx, ny, nd, p, solver , jacobian, linfunc!
199+ solver, f !, h !, Ts, nu, nx, ny, nd, p, jacobian, linfunc!
185200 )
186201end
187202
@@ -270,22 +285,27 @@ Call [`linearize(model; x, u, d)`](@ref) and return the resulting linear model.
270285"""
271286LinModel (model:: NonLinModel ; kwargs... ) = linearize (model; kwargs... )
272287
288+
273289"""
274290 f!(x0next, k0, model::NonLinModel, x0, u0, d0, p)
275291
276- Call `model.solver_f!( x0next, k0, x0, u0, d0, p)` for [`NonLinModel `](@ref).
292+ Compute ` x0next` using the [`DiffSolver `](@ref) in `model.solver` and `model.f!` .
277293
278- The method mutate `x0next` and `k0` arguments in-place. The latter is used to store the
279- intermediate stage values of `model.solver` [`DiffSolver`](@ref) .
294+ The method mutates `x0next` and `k0` arguments in-place. The latter is used to store the
295+ intermediate stage values of the solver .
280296"""
281- f! (x0next, k0, model:: NonLinModel , x0, u0, d0, p) = model. solver_f! (x0next, k0, x0, u0, d0, p)
297+ function f! (x0next, k0, model:: NonLinModel , x0, u0, d0, p)
298+ return solver_f! (x0next, k0, model. f!, model. Ts, model. solver, x0, u0, d0, p)
299+ end
282300
283301"""
284302 h!(y0, model::NonLinModel, x0, d0, p)
285303
286- Call `model.solver_h!(y0, x0, d0, p)` for [`NonLinModel`](@ref).
304+ Compute `y0` by calling `model.h!` directly for [`NonLinModel`](@ref).
287305"""
288- h! (y0, model:: NonLinModel , x0, d0, p) = model. solver_h! (y0, x0, d0, p)
306+ h! (y0, model:: NonLinModel , x0, d0, p) = model. h! (y0, x0, d0, p)
307+
308+ include (" solver.jl" )
289309
290- detailstr (model:: NonLinModel ) = " , $(typeof (model. solver). name . name) ( $(model . solver . order) ) solver"
291- detailstr (:: NonLinModel{<:Real, <:Function, <:Function, <:Any, <: EmptySolver} ) = " , empty solver"
310+ detailstr (model:: NonLinModel ) = " , $(typeof (model. solver)) solver"
311+ detailstr (:: NonLinModel{<:Real, <:EmptySolver} ) = " , empty solver"
0 commit comments