@@ -10,11 +10,10 @@ using ModelingToolkit: t_nounits as t
1010@parameters σ=28.0 ρ=10.0 β=8/3 δt=0.1
1111@variables x(t)=1.0 y(t)=0.0 z(t)=0.0
1212k = ShiftIndex(t)
13- eqs = [x(k+1) ~ σ*(y-x),
14- y(k+1) ~ x*(ρ-z)-y,
15- z(k+1) ~ x*y - β*z]
16- @named de = ImplicitDiscreteSystem(eqs,t,[x,y,z],[σ,ρ,β]; tspan = (0, 1000.0)) # or
17- @named de = ImplicitDiscreteSystem(eqs)
13+ eqs = [x ~ σ*(y(k-1)-x),
14+ y ~ x*(ρ-z(k-1))-y,
15+ z ~ x(k-1)*y - β*z]
16+ @named ide = ImplicitDiscreteSystem(eqs,t,[x,y,z],[σ,ρ,β]; tspan = (0, 1000.0))
1817```
1918"""
2019struct ImplicitDiscreteSystem <: AbstractTimeDependentSystem
136135
137136"""
138137 $(TYPEDSIGNATURES)
138+
139139Constructs a ImplicitDiscreteSystem.
140140"""
141141function ImplicitDiscreteSystem (eqs:: AbstractVector{<:Equation} , iv, dvs, ps;
@@ -170,6 +170,8 @@ function ImplicitDiscreteSystem(eqs::AbstractVector{<:Equation}, iv, dvs, ps;
170170 :ImplicitDiscreteSystem , force = true )
171171 end
172172
173+ # Copy equations to canonical form, but do not touch array expressions
174+ eqs = [wrap (eq. lhs) isa Symbolics. Arr ? eq : 0 ~ eq. rhs - eq. lhs for eq in eqs]
173175 defaults = Dict {Any, Any} (todict (defaults))
174176 guesses = Dict {Any, Any} (todict (guesses))
175177 var_to_name = Dict ()
@@ -236,6 +238,8 @@ function ImplicitDiscreteSystem(eqs, iv; kwargs...)
236238 return ImplicitDiscreteSystem (eqs, iv,
237239 collect (allunknowns), collect (new_ps); kwargs... )
238240end
241+ # basically at every timestep it should build a nonlinear solve
242+ # Previous timesteps should be treated as parameters? is this right?
239243
240244function flatten (sys:: ImplicitDiscreteSystem , noeqs = false )
241245 systems = get_systems (sys)
@@ -259,10 +263,25 @@ end
259263
260264function generate_function (
261265 sys:: ImplicitDiscreteSystem , dvs = unknowns (sys), ps = parameters (sys); wrap_code = identity, kwargs... )
262- exprs = [eq. rhs for eq in equations (sys)]
263- wrap_code = wrap_code .∘ wrap_array_vars (sys, exprs) .∘
264- wrap_parameter_dependencies (sys, false )
265- generate_custom_function (sys, exprs, dvs, ps; wrap_code, kwargs... )
266+ if ! iscomplete (sys)
267+ error (" A completed system is required. Call `complete` or `structural_simplify` on the system." )
268+ end
269+ p = (reorder_parameters (sys, unwrap .(ps))... , cachesyms... )
270+ isscalar = ! (exprs isa AbstractArray)
271+ pre, sol_states = get_substitutions_and_solved_unknowns (sys, isscalar ? [exprs] : exprs)
272+ if postprocess_fbody === nothing
273+ postprocess_fbody = pre
274+ end
275+ if states === nothing
276+ states = sol_states
277+ end
278+ exprs = [eq. lhs - eq. rhs for eq in equations (sys)]
279+ u = map (Shift (iv, - 1 ), dvs)
280+ u_next = dvs
281+
282+ wrap_code = wrap_code .∘ wrap_array_vars (sys, exprs) .∘ wrap_parameter_dependencies (sys, false )
283+
284+ build_function (exprs, u_next, u, p... , get_iv (sys))
266285end
267286
268287function shift_u0map_forward (sys:: ImplicitDiscreteSystem , u0map, defs)
@@ -311,7 +330,7 @@ function SciMLBase.ImplicitDiscreteProblem(
311330 f, u0, p = process_SciMLProblem (
312331 ImplicitDiscreteFunction, sys, u0map, parammap; eval_expression, eval_module)
313332 u0 = f (u0, p, tspan[1 ])
314- ImplicitDiscreteProblem (f, u0, tspan, p; kwargs... )
333+ NonlinearProblem (f, u0, tspan, p; kwargs... )
315334end
316335
317336function SciMLBase. ImplicitDiscreteFunction (sys:: ImplicitDiscreteSystem , args... ; kwargs... )
@@ -337,14 +356,15 @@ function SciMLBase.ImplicitDiscreteFunction{iip, specialize}(
337356 eval_module = @__MODULE__ ,
338357 analytic = nothing ,
339358 kwargs... ) where {iip, specialize}
359+
340360 if ! iscomplete (sys)
341361 error (" A completed `ImplicitDiscreteSystem` is required. Call `complete` or `structural_simplify` on the system before creating a `ImplicitDiscreteProblem`" )
342362 end
343363 f_gen = generate_function (sys, dvs, ps; expression = Val{true },
344364 expression_module = eval_module, kwargs... )
345365 f_oop, f_iip = eval_or_rgf .(f_gen; eval_expression, eval_module)
346- f (u, p, t) = f_oop (u, p, t)
347- f (du, u, p, t) = f_iip (du , u, p, t)
366+ f (u_next, u, p, t) = f_oop (u_next, u, p, t)
367+ f (resid, u_next, u, p, t) = f_iip (resid, u_next , u, p, t)
348368
349369 if specialize === SciMLBase. FunctionWrapperSpecialize && iip
350370 if u0 === nothing || p === nothing || t === nothing
@@ -379,8 +399,8 @@ struct ImplicitDiscreteFunctionClosure{O, I} <: Function
379399 f_oop:: O
380400 f_iip:: I
381401end
382- (f:: ImplicitDiscreteFunctionClosure )(u, p, t) = f. f_oop (u, p, t)
383- (f:: ImplicitDiscreteFunctionClosure )(du, u, p, t) = f. f_iip (du , u, p, t)
402+ (f:: ImplicitDiscreteFunctionClosure )(u_next, u, p, t) = f. f_oop (u_next, u, p, t)
403+ (f:: ImplicitDiscreteFunctionClosure )(resid, u_next, u, p, t) = f. f_iip (resid, u_next , u, p, t)
384404
385405function ImplicitDiscreteFunctionExpr {iip} (sys:: ImplicitDiscreteSystem , dvs = unknowns (sys),
386406 ps = parameters (sys), u0 = nothing ;
0 commit comments