@@ -1774,18 +1774,87 @@ function linearization_function(sys::AbstractSystem, inputs,
1774
1774
sys = ssys
1775
1775
initsys = complete (generate_initializesystem (
1776
1776
sys, guesses = guesses (sys), algebraic_only = true ))
1777
+ if p isa SciMLBase. NullParameters
1778
+ p = Dict ()
1779
+ else
1780
+ p = todict (p)
1781
+ end
1782
+ p[get_iv (sys)] = 0.0
1783
+ if has_index_cache (initsys) && get_index_cache (initsys) != = nothing
1784
+ oldps = MTKParameters (initsys, p, merge (guesses (sys), defaults (sys), op))
1785
+ initsys_ps = parameters (initsys)
1786
+ initsys_idxs = [parameter_index (initsys, param) for param in initsys_ps]
1787
+ tunable_ps = [initsys_ps[i]
1788
+ for i in eachindex (initsys_ps)
1789
+ if initsys_idxs[i]. portion == SciMLStructures. Tunable ()]
1790
+ tunable_getter = isempty (tunable_ps) ? nothing : getu (sys, tunable_ps)
1791
+ discrete_ps = [initsys_ps[i]
1792
+ for i in eachindex (initsys_ps)
1793
+ if initsys_idxs[i]. portion == SciMLStructures. Discrete ()]
1794
+ disc_getter = isempty (discrete_ps) ? nothing : getu (sys, discrete_ps)
1795
+ constant_ps = [initsys_ps[i]
1796
+ for i in eachindex (initsys_ps)
1797
+ if initsys_idxs[i]. portion == SciMLStructures. Constants ()]
1798
+ const_getter = isempty (constant_ps) ? nothing : getu (sys, constant_ps)
1799
+ nonnum_ps = [initsys_ps[i]
1800
+ for i in eachindex (initsys_ps)
1801
+ if initsys_idxs[i]. portion == NONNUMERIC_PORTION]
1802
+ nonnum_getter = isempty (nonnum_ps) ? nothing : getu (sys, nonnum_ps)
1803
+ u_getter = isempty (unknowns (initsys)) ? (_... ) -> nothing :
1804
+ getu (sys, unknowns (initsys))
1805
+ get_initprob_u_p = let tunable_getter = tunable_getter,
1806
+ disc_getter = disc_getter,
1807
+ const_getter = const_getter,
1808
+ nonnum_getter = nonnum_getter,
1809
+ oldps = oldps,
1810
+ u_getter = u_getter
1811
+
1812
+ function (u, p, t)
1813
+ state = ProblemState (; u, p, t)
1814
+ if tunable_getter != = nothing
1815
+ oldps = SciMLStructures. replace! (
1816
+ SciMLStructures. Tunable (), oldps, tunable_getter (state))
1817
+ end
1818
+ if disc_getter != = nothing
1819
+ oldps = SciMLStructures. replace! (
1820
+ SciMLStructures. Discrete (), oldps, disc_getter (state))
1821
+ end
1822
+ if const_getter != = nothing
1823
+ oldps = SciMLStructures. replace! (
1824
+ SciMLStructures. Constants (), oldps, const_getter (state))
1825
+ end
1826
+ if nonnum_getter != = nothing
1827
+ oldps = SciMLStructures. replace! (
1828
+ NONNUMERIC_PORTION, oldps, nonnum_getter (state))
1829
+ end
1830
+ newu = u_getter (state)
1831
+ return newu, oldps
1832
+ end
1833
+ end
1834
+ else
1835
+ get_initprob_u_p = let p_getter = getu (sys, parameters (initsys)),
1836
+ u_getter = getu (sys, unknowns (initsys))
1837
+
1838
+ function (u, p, t)
1839
+ state = ProblemState (; u, p, t)
1840
+ return u_getter (state), p_getter (state)
1841
+ end
1842
+ end
1843
+ end
1777
1844
initfn = NonlinearFunction (initsys)
1778
1845
initprobmap = getu (initsys, unknowns (sys))
1779
1846
ps = parameters (sys)
1780
1847
lin_fun = let diff_idxs = diff_idxs,
1781
1848
alge_idxs = alge_idxs,
1782
1849
input_idxs = input_idxs,
1783
1850
sts = unknowns (sys),
1851
+ get_initprob_u_p = get_initprob_u_p,
1784
1852
fun = ODEFunction {true, SciMLBase.FullSpecialize} (
1785
1853
sys, unknowns (sys), ps; initializeprobmap = initprobmap),
1786
1854
initfn = initfn,
1787
1855
h = build_explicit_observed_function (sys, outputs),
1788
- chunk = ForwardDiff. Chunk (input_idxs)
1856
+ chunk = ForwardDiff. Chunk (input_idxs),
1857
+ initialize = initialize
1789
1858
1790
1859
function (u, p, t)
1791
1860
if u != = nothing # Handle systems without unknowns
@@ -1794,7 +1863,8 @@ function linearization_function(sys::AbstractSystem, inputs,
1794
1863
if initialize && ! isempty (alge_idxs) # This is expensive and can be omitted if the user knows that the system is already initialized
1795
1864
residual = fun (u, p, t)
1796
1865
if norm (residual[alge_idxs]) > √ (eps (eltype (residual)))
1797
- initprob = NonlinearLeastSquaresProblem (initfn, u, p)
1866
+ initu0, initp = get_initprob_u_p (u, p, t)
1867
+ initprob = NonlinearLeastSquaresProblem (initfn, initu0, initp)
1798
1868
@set! fun. initializeprob = initprob
1799
1869
prob = ODEProblem (fun, u, (t, t + 1 ), p)
1800
1870
integ = init (prob, OrdinaryDiffEq. Rodas5P ())
0 commit comments