1
+ struct Schedule
2
+ var_eq_matching:: Any
3
+ dummy_sub:: Any
4
+ end
5
+
1
6
function filter_kwargs (kwargs)
2
7
kwargs = Dict (kwargs)
3
8
for key in keys (kwargs)
@@ -316,6 +321,8 @@ function DiffEqBase.ODEFunction{iip, specialize}(sys::AbstractODESystem,
316
321
sparsity = false ,
317
322
analytic = nothing ,
318
323
split_idxs = nothing ,
324
+ initializeprob = nothing ,
325
+ initializeprobmap = nothing ,
319
326
kwargs... ) where {iip, specialize}
320
327
if ! iscomplete (sys)
321
328
error (" A completed system is required. Call `complete` or `structural_simplify` on the system before creating an `ODEFunction`" )
@@ -487,6 +494,7 @@ function DiffEqBase.ODEFunction{iip, specialize}(sys::AbstractODESystem,
487
494
end
488
495
489
496
@set! sys. split_idxs = split_idxs
497
+
490
498
ODEFunction {iip, specialize} (f;
491
499
sys = sys,
492
500
jac = _jac === nothing ? nothing : _jac,
@@ -495,7 +503,9 @@ function DiffEqBase.ODEFunction{iip, specialize}(sys::AbstractODESystem,
495
503
jac_prototype = jac_prototype,
496
504
observed = observedfun,
497
505
sparsity = sparsity ? jacobian_sparsity (sys) : nothing ,
498
- analytic = analytic)
506
+ analytic = analytic,
507
+ initializeprob = initializeprob,
508
+ initializeprobmap = initializeprobmap)
499
509
end
500
510
501
511
"""
@@ -525,6 +535,8 @@ function DiffEqBase.DAEFunction{iip}(sys::AbstractODESystem, dvs = unknowns(sys)
525
535
sparse = false , simplify = false ,
526
536
eval_module = @__MODULE__ ,
527
537
checkbounds = false ,
538
+ initializeprob = nothing ,
539
+ initializeprobmap = nothing ,
528
540
kwargs... ) where {iip}
529
541
if ! iscomplete (sys)
530
542
error (" A completed system is required. Call `complete` or `structural_simplify` on the system before creating a `DAEFunction`" )
@@ -596,7 +608,9 @@ function DiffEqBase.DAEFunction{iip}(sys::AbstractODESystem, dvs = unknowns(sys)
596
608
sys = sys,
597
609
jac = _jac === nothing ? nothing : _jac,
598
610
jac_prototype = jac_prototype,
599
- observed = observedfun)
611
+ observed = observedfun,
612
+ initializeprob = initializeprob,
613
+ initializeprobmap = initializeprobmap)
600
614
end
601
615
602
616
function DiffEqBase. DDEFunction (sys:: AbstractODESystem , args... ; kwargs... )
@@ -839,18 +853,46 @@ function process_DEProblem(constructor, sys::AbstractODESystem, u0map, parammap;
839
853
tofloat = true ,
840
854
symbolic_u0 = false ,
841
855
u0_constructor = identity,
856
+ guesses = Dict (),
857
+ t = nothing ,
858
+ warn_initialize_determined = true ,
842
859
kwargs... )
843
860
eqs = equations (sys)
844
861
dvs = unknowns (sys)
845
862
ps = full_parameters (sys)
846
863
iv = get_iv (sys)
847
864
865
+ # Append zeros to the variables which are determined by the initialization system
866
+ # This essentially bypasses the check for if initial conditions are defined for DAEs
867
+ # since they will be checked in the initialization problem's construction
868
+ # TODO : make check for if a DAE cheaper than calculating the mass matrix a second time!
869
+ ci = infer_clocks! (ClockInference (TearingState (sys)))
870
+ # TODO : make it work with clocks
871
+ # ModelingToolkit.get_tearing_state(sys) !== nothing => Requires structural_simplify first
872
+ if (implicit_dae || calculate_massmatrix (sys) != = I) &&
873
+ all (isequal (Continuous ()), ci. var_domain) &&
874
+ ModelingToolkit. get_tearing_state (sys) != = nothing
875
+ if eltype (u0map) <: Number
876
+ u0map = unknowns (sys) .=> u0map
877
+ end
878
+ initializeprob = ModelingToolkit. InitializationProblem (
879
+ sys, t, u0map, parammap; guesses, warn_initialize_determined)
880
+ initializeprobmap = getu (initializeprob, unknowns (sys))
881
+
882
+ zerovars = setdiff (unknowns (sys), keys (defaults (sys))) .=> 0.0
883
+ trueinit = identity .([zerovars; u0map])
884
+ else
885
+ initializeprob = nothing
886
+ initializeprobmap = nothing
887
+ trueinit = u0map
888
+ end
889
+
848
890
if has_index_cache (sys) && get_index_cache (sys) != = nothing
849
- u0, defs = get_u0 (sys, u0map , parammap; symbolic_u0)
891
+ u0, defs = get_u0 (sys, trueinit , parammap; symbolic_u0)
850
892
p = MTKParameters (sys, parammap)
851
893
else
852
894
u0, p, defs = get_u0_p (sys,
853
- u0map ,
895
+ trueinit ,
854
896
parammap;
855
897
tofloat,
856
898
use_union,
@@ -881,6 +923,8 @@ function process_DEProblem(constructor, sys::AbstractODESystem, u0map, parammap;
881
923
checkbounds = checkbounds, p = p,
882
924
linenumbers = linenumbers, parallel = parallel, simplify = simplify,
883
925
sparse = sparse, eval_expression = eval_expression,
926
+ initializeprob = initializeprob,
927
+ initializeprobmap = initializeprobmap,
884
928
kwargs... )
885
929
implicit_dae ? (f, du0, u0, p) : (f, u0, p)
886
930
end
@@ -984,13 +1028,14 @@ function DiffEqBase.ODEProblem{iip, specialize}(sys::AbstractODESystem, u0map =
984
1028
parammap = DiffEqBase. NullParameters ();
985
1029
callback = nothing ,
986
1030
check_length = true ,
1031
+ warn_initialize_determined = true ,
987
1032
kwargs... ) where {iip, specialize}
988
1033
if ! iscomplete (sys)
989
1034
error (" A completed system is required. Call `complete` or `structural_simplify` on the system before creating an `ODEProblem`" )
990
1035
end
991
1036
f, u0, p = process_DEProblem (ODEFunction{iip, specialize}, sys, u0map, parammap;
992
1037
t = tspan != = nothing ? tspan[1 ] : tspan,
993
- check_length, kwargs... )
1038
+ check_length, warn_initialize_determined, kwargs... )
994
1039
cbs = process_events (sys; callback, kwargs... )
995
1040
inits = []
996
1041
if has_discrete_subsystems (sys) && (dss = get_discrete_subsystems (sys)) != = nothing
@@ -1055,13 +1100,15 @@ end
1055
1100
1056
1101
function DiffEqBase. DAEProblem {iip} (sys:: AbstractODESystem , du0map, u0map, tspan,
1057
1102
parammap = DiffEqBase. NullParameters ();
1103
+ warn_initialize_determined = true ,
1058
1104
check_length = true , kwargs... ) where {iip}
1059
1105
if ! iscomplete (sys)
1060
1106
error (" A completed system is required. Call `complete` or `structural_simplify` on the system before creating a `DAEProblem`" )
1061
1107
end
1062
1108
f, du0, u0, p = process_DEProblem (DAEFunction{iip}, sys, u0map, parammap;
1063
1109
implicit_dae = true , du0map = du0map, check_length,
1064
- kwargs... )
1110
+ t = tspan != = nothing ? tspan[1 ] : tspan,
1111
+ warn_initialize_determined, kwargs... )
1065
1112
diffvars = collect_differential_variables (sys)
1066
1113
sts = unknowns (sys)
1067
1114
differential_vars = map (Base. Fix2 (in, diffvars), sts)
@@ -1237,6 +1284,7 @@ function ODEProblemExpr{iip}(sys::AbstractODESystem, u0map, tspan,
1237
1284
error (" A completed system is required. Call `complete` or `structural_simplify` on the system before creating a `ODEProblemExpr`" )
1238
1285
end
1239
1286
f, u0, p = process_DEProblem (ODEFunctionExpr{iip}, sys, u0map, parammap; check_length,
1287
+ t = tspan != = nothing ? tspan[1 ] : tspan,
1240
1288
kwargs... )
1241
1289
linenumbers = get (kwargs, :linenumbers , true )
1242
1290
kwargs = filter_kwargs (kwargs)
@@ -1282,6 +1330,7 @@ function DAEProblemExpr{iip}(sys::AbstractODESystem, du0map, u0map, tspan,
1282
1330
error (" A completed system is required. Call `complete` or `structural_simplify` on the system before creating a `DAEProblemExpr`" )
1283
1331
end
1284
1332
f, du0, u0, p = process_DEProblem (DAEFunctionExpr{iip}, sys, u0map, parammap;
1333
+ t = tspan != = nothing ? tspan[1 ] : tspan,
1285
1334
implicit_dae = true , du0map = du0map, check_length,
1286
1335
kwargs... )
1287
1336
linenumbers = get (kwargs, :linenumbers , true )
@@ -1442,3 +1491,82 @@ function flatten_equations(eqs)
1442
1491
end
1443
1492
end
1444
1493
end
1494
+
1495
+ struct InitializationProblem{iip, specialization} end
1496
+
1497
+ """
1498
+ ```julia
1499
+ InitializationProblem{iip}(sys::AbstractODESystem, u0map, tspan,
1500
+ parammap = DiffEqBase.NullParameters();
1501
+ version = nothing, tgrad = false,
1502
+ jac = false,
1503
+ checkbounds = false, sparse = false,
1504
+ simplify = false,
1505
+ linenumbers = true, parallel = SerialForm(),
1506
+ kwargs...) where {iip}
1507
+ ```
1508
+
1509
+ Generates a NonlinearProblem or NonlinearLeastSquaresProblem from an ODESystem
1510
+ which represents the initialization, i.e. the calculation of the consistent
1511
+ initial conditions for the given DAE.
1512
+ """
1513
+ function InitializationProblem (sys:: AbstractODESystem , args... ; kwargs... )
1514
+ InitializationProblem {true} (sys, args... ; kwargs... )
1515
+ end
1516
+
1517
+ function InitializationProblem (sys:: AbstractODESystem , t,
1518
+ u0map:: StaticArray ,
1519
+ args... ;
1520
+ kwargs... )
1521
+ InitializationProblem {false, SciMLBase.FullSpecialize} (
1522
+ sys, t, u0map, args... ; kwargs... )
1523
+ end
1524
+
1525
+ function InitializationProblem {true} (sys:: AbstractODESystem , args... ; kwargs... )
1526
+ InitializationProblem {true, SciMLBase.AutoSpecialize} (sys, args... ; kwargs... )
1527
+ end
1528
+
1529
+ function InitializationProblem {false} (sys:: AbstractODESystem , args... ; kwargs... )
1530
+ InitializationProblem {false, SciMLBase.FullSpecialize} (sys, args... ; kwargs... )
1531
+ end
1532
+
1533
+ function InitializationProblem {iip, specialize} (sys:: AbstractODESystem ,
1534
+ t:: Number , u0map = [],
1535
+ parammap = DiffEqBase. NullParameters ();
1536
+ guesses = [],
1537
+ check_length = true ,
1538
+ warn_initialize_determined = true ,
1539
+ kwargs... ) where {iip, specialize}
1540
+ if ! iscomplete (sys)
1541
+ error (" A completed system is required. Call `complete` or `structural_simplify` on the system before creating an `ODEProblem`" )
1542
+ end
1543
+
1544
+ if isempty (u0map) && get_initializesystem (sys) != = nothing
1545
+ isys = get_initializesystem (sys)
1546
+ elseif isempty (u0map) && get_initializesystem (sys) === nothing
1547
+ isys = structural_simplify (generate_initializesystem (sys); fully_determined = false )
1548
+ else
1549
+ isys = structural_simplify (
1550
+ generate_initializesystem (sys; u0map); fully_determined = false )
1551
+ end
1552
+
1553
+ neqs = length (equations (isys))
1554
+ nunknown = length (unknowns (isys))
1555
+
1556
+ if warn_initialize_determined && neqs > nunknown
1557
+ @warn " Initialization system is overdetermined. $neqs equations for $nunknown unknowns. Initialization will default to using least squares. To suppress this warning pass warn_initialize_determined = false."
1558
+ end
1559
+ if warn_initialize_determined && neqs < nunknown
1560
+ @warn " Initialization system is underdetermined. $neqs equations for $nunknown unknowns. Initialization will default to using least squares. To suppress this warning pass warn_initialize_determined = false."
1561
+ end
1562
+
1563
+ parammap isa DiffEqBase. NullParameters || isempty (parammap) ?
1564
+ [get_iv (sys) => t] :
1565
+ merge (todict (parammap), Dict (get_iv (sys) => t))
1566
+
1567
+ if neqs == nunknown
1568
+ NonlinearProblem (isys, guesses, parammap)
1569
+ else
1570
+ NonlinearLeastSquaresProblem (isys, guesses, parammap)
1571
+ end
1572
+ end
0 commit comments