@@ -303,6 +303,18 @@ function SciMLBase.remake_initialization_data(sys::ODESystem, odefn, u0, t0, p,
303303 diff_idxs[i] || continue
304304 u0map[dvs[i]] = newu0[i]
305305 end
306+ else
307+ # The user did pass `u0` to `remake`, so they want to use
308+ # the specified values. If we fill the rest of `u0map` with
309+ # old values, the initialization can end up overdetermined
310+ # (e.g. if the user specified a value for an algebraic variable)
311+ # and wants to solve for a differential variable
312+
313+ # instead, fill the guesses with old values. That way, the user's
314+ # u0map are the only constraints (along with defaults) and
315+ # if the system is underdetermined, variables will likely retain
316+ # their old values.
317+ merge! (guesses, Dict (dvs .=> newu0))
306318 end
307319 if p === missing
308320 # the user didn't pass `p` to `remake`, so they want to retain
@@ -311,6 +323,20 @@ function SciMLBase.remake_initialization_data(sys::ODESystem, odefn, u0, t0, p,
311323 for p in ps
312324 pmap[p] = getp (sys, p)(newp)
313325 end
326+ else
327+ # we can't just fill guesses for parameters like we did for unknowns
328+ # because that can unintentionally make parameters solvable. If the
329+ # parameter is solvable with the existing specification, fill its
330+ # guess and fill `pmap` otherwise.
331+ pmap_fallbacks = Dict ()
332+ for p in ps
333+ if is_parameter_solvable (p, pmap, defs, guesses)
334+ guesses[p] = getp (sys, p)(newp)
335+ else
336+ pmap_fallbacks[p] = getp (sys, p)(newp)
337+ end
338+ end
339+ add_fallbacks! (pmap, ps, pmap_fallbacks)
314340 end
315341 # all non-solvable parameters need values regardless
316342 for p in ps
0 commit comments