@@ -10,11 +10,10 @@ using ModelingToolkit: t_nounits as t
10
10
@parameters σ=28.0 ρ=10.0 β=8/3 δt=0.1
11
11
@variables x(t)=1.0 y(t)=0.0 z(t)=0.0
12
12
k = 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))
18
17
```
19
18
"""
20
19
struct ImplicitDiscreteSystem <: AbstractTimeDependentSystem
136
135
137
136
"""
138
137
$(TYPEDSIGNATURES)
138
+
139
139
Constructs a ImplicitDiscreteSystem.
140
140
"""
141
141
function ImplicitDiscreteSystem (eqs:: AbstractVector{<:Equation} , iv, dvs, ps;
@@ -170,6 +170,8 @@ function ImplicitDiscreteSystem(eqs::AbstractVector{<:Equation}, iv, dvs, ps;
170
170
:ImplicitDiscreteSystem , force = true )
171
171
end
172
172
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]
173
175
defaults = Dict {Any, Any} (todict (defaults))
174
176
guesses = Dict {Any, Any} (todict (guesses))
175
177
var_to_name = Dict ()
@@ -236,6 +238,8 @@ function ImplicitDiscreteSystem(eqs, iv; kwargs...)
236
238
return ImplicitDiscreteSystem (eqs, iv,
237
239
collect (allunknowns), collect (new_ps); kwargs... )
238
240
end
241
+ # basically at every timestep it should build a nonlinear solve
242
+ # Previous timesteps should be treated as parameters? is this right?
239
243
240
244
function flatten (sys:: ImplicitDiscreteSystem , noeqs = false )
241
245
systems = get_systems (sys)
@@ -259,10 +263,25 @@ end
259
263
260
264
function generate_function (
261
265
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))
266
285
end
267
286
268
287
function shift_u0map_forward (sys:: ImplicitDiscreteSystem , u0map, defs)
@@ -311,7 +330,7 @@ function SciMLBase.ImplicitDiscreteProblem(
311
330
f, u0, p = process_SciMLProblem (
312
331
ImplicitDiscreteFunction, sys, u0map, parammap; eval_expression, eval_module)
313
332
u0 = f (u0, p, tspan[1 ])
314
- ImplicitDiscreteProblem (f, u0, tspan, p; kwargs... )
333
+ NonlinearProblem (f, u0, tspan, p; kwargs... )
315
334
end
316
335
317
336
function SciMLBase. ImplicitDiscreteFunction (sys:: ImplicitDiscreteSystem , args... ; kwargs... )
@@ -337,14 +356,15 @@ function SciMLBase.ImplicitDiscreteFunction{iip, specialize}(
337
356
eval_module = @__MODULE__ ,
338
357
analytic = nothing ,
339
358
kwargs... ) where {iip, specialize}
359
+
340
360
if ! iscomplete (sys)
341
361
error (" A completed `ImplicitDiscreteSystem` is required. Call `complete` or `structural_simplify` on the system before creating a `ImplicitDiscreteProblem`" )
342
362
end
343
363
f_gen = generate_function (sys, dvs, ps; expression = Val{true },
344
364
expression_module = eval_module, kwargs... )
345
365
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)
348
368
349
369
if specialize === SciMLBase. FunctionWrapperSpecialize && iip
350
370
if u0 === nothing || p === nothing || t === nothing
@@ -379,8 +399,8 @@ struct ImplicitDiscreteFunctionClosure{O, I} <: Function
379
399
f_oop:: O
380
400
f_iip:: I
381
401
end
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)
384
404
385
405
function ImplicitDiscreteFunctionExpr {iip} (sys:: ImplicitDiscreteSystem , dvs = unknowns (sys),
386
406
ps = parameters (sys), u0 = nothing ;
0 commit comments