@@ -45,16 +45,23 @@ function SciMLBase.__solve(
4545
4646 internal_ode_kwargs = (; kwargs... , odesolve_kwargs... , save_end = true )
4747
48+ odecache_by_eltype = Dict {Tuple{Any, Int}, Any} ()
4849 solve_internal_odes! = @closure (
4950 resid_nodes,
5051 us,
5152 p,
5253 cur_nshoot,
5354 nodes,
5455 odecache,
55- ) -> __multiple_shooting_solve_internal_odes! (
56- resid_nodes, us, cur_nshoot, odecache, nodes, u0_size, N, ensemblealg, tspan
57- )
56+ ) -> begin
57+ odecache_ = __multiple_shooting_odecache_for_eltype (
58+ odecache, odecache_by_eltype, ensemblealg, prob, alg. ode_alg, us, cur_nshoot,
59+ u0_size, N, internal_ode_kwargs
60+ )
61+ __multiple_shooting_solve_internal_odes! (
62+ resid_nodes, us, cur_nshoot, odecache_, nodes, u0_size, N, ensemblealg, tspan
63+ )
64+ end
5865
5966 # This gets all the nshoots except the final SingleShooting case
6067 all_nshoots = __get_all_nshoots (alg. grid_coarsening, nshoots)
@@ -357,17 +364,35 @@ function __multiple_shooting_init_jacobian_odecache(
357364 )
358365 T_dual = eltype (overloaded_input_type (jac_cache))
359366 xduals = zeros (T_dual, size (u))
367+ prob = remake (prob; tspan = T_dual .(prob. tspan))
360368 return __multiple_shooting_init_odecache (
361369 ensemblealg, prob, alg, xduals, nshoots; kwargs...
362370 )
363371end
364372
373+ function __multiple_shooting_odecache_for_eltype (
374+ odecache, odecache_by_eltype, ensemblealg, prob, ode_alg, us, nshoots, u0_size, N,
375+ internal_ode_kwargs
376+ )
377+ cache = odecache isa Vector ? first (odecache) : odecache
378+ eltype (cache. u) === eltype (us) && return odecache
379+
380+ key = (eltype (us), nshoots)
381+ return get! (odecache_by_eltype, key) do
382+ u0 = copy (reshape (@view (us[1 : N]), u0_size))
383+ prob = remake (prob; tspan = eltype (us).(prob. tspan))
384+ __multiple_shooting_init_odecache (
385+ ensemblealg, prob, ode_alg, u0, nshoots; internal_ode_kwargs...
386+ )
387+ end
388+ end
389+
365390# Not using `EnsembleProblem` since it is hard to initialize the cache and stuff
366391function __multiple_shooting_solve_internal_odes! (
367392 resid_nodes, us, cur_nshoots:: Int , odecache,
368393 nodes, u0_size, N:: Int , :: EnsembleSerial , tspan
369394 )
370- ts_ = Vector {Vector{ typeof(first(tspan))} } (undef, cur_nshoots)
395+ ts_ = Vector {typeof(odecache.sol.t) } (undef, cur_nshoots)
371396 us_ = Vector {Vector{typeof(us)}} (undef, cur_nshoots)
372397
373398 for i in 1 : cur_nshoots
@@ -389,7 +414,7 @@ function __multiple_shooting_solve_internal_odes!(
389414 resid_nodes, us, cur_nshoots:: Int , odecache:: Vector ,
390415 nodes, u0_size, N:: Int , :: EnsembleThreads , tspan
391416 )
392- ts_ = Vector {Vector{ typeof(first(tspan))} } (undef, cur_nshoots)
417+ ts_ = Vector {typeof(first(odecache).sol.t) } (undef, cur_nshoots)
393418 us_ = Vector {Vector{typeof(us)}} (undef, cur_nshoots)
394419
395420 n_splits = min (cur_nshoots, Threads. nthreads ())
0 commit comments