@@ -273,6 +273,103 @@ function WorkPrecision(prob, alg, abstols, reltols, dts = nothing;
273
273
return WorkPrecision (prob, abstols, reltols, errors, times, name, N)
274
274
end
275
275
276
+ # Work precision information for a BVP
277
+ function WorkPrecision (prob:: AbstractBVProblem , alg, abstols, reltols, dts = nothing ;
278
+ name = nothing , appxsol = nothing , error_estimate = :final ,
279
+ numruns = 20 , seconds = 2 , kwargs... )
280
+ N = length (abstols)
281
+ errors = Vector {Float64} (undef, N)
282
+ times = Vector {Float64} (undef, N)
283
+ if name === nothing
284
+ name = " WP-Alg"
285
+ end
286
+
287
+ if haskey (kwargs, :prob_choice )
288
+ _prob = prob[kwargs[:prob_choice ]]
289
+ elseif prob isa AbstractArray
290
+ _prob = prob[1 ]
291
+ else
292
+ _prob = prob
293
+ end
294
+
295
+ let _prob = _prob
296
+ timeseries_errors = error_estimate ∈ TIMESERIES_ERRORS
297
+ dense_errors = error_estimate ∈ DENSE_ERRORS
298
+ for i in 1 : N
299
+ if dts === nothing
300
+ sol = solve (_prob, alg; kwargs... , abstol = abstols[i],
301
+ reltol = reltols[i], timeseries_errors = timeseries_errors,
302
+ dense_errors = dense_errors)
303
+ else
304
+ sol = DiffEqBase. solve (_prob, alg; kwargs... , abstol = abstols[i],
305
+ reltol = reltols[i], dt = dts[i],
306
+ timeseries_errors = timeseries_errors,
307
+ dense_errors = dense_errors)
308
+ end
309
+
310
+ if haskey (kwargs, :prob_choice )
311
+ cur_appxsol = appxsol[kwargs[:prob_choice ]]
312
+ elseif prob isa AbstractArray
313
+ cur_appxsol = appxsol[1 ]
314
+ else
315
+ cur_appxsol = appxsol
316
+ end
317
+
318
+ if cur_appxsol != = nothing
319
+ errsol = appxtrue (sol, cur_appxsol)
320
+ errors[i] = mean (errsol. errors[error_estimate])
321
+ else
322
+ errors[i] = mean (sol. errors[error_estimate])
323
+ end
324
+
325
+ benchmark_f = let dts = dts, _prob = _prob, alg = alg, sol = sol,
326
+ abstols = abstols, reltols = reltols, kwargs = kwargs
327
+
328
+ if dts === nothing
329
+ if typeof (_prob) <: DAEProblem
330
+ () -> @elapsed solve (_prob, alg;
331
+ abstol = abstols[i],
332
+ reltol = reltols[i],
333
+ timeseries_errors = false ,
334
+ dense_errors = false , kwargs... )
335
+ else
336
+ () -> @elapsed solve (_prob, alg;
337
+ abstol = abstols[i],
338
+ reltol = reltols[i],
339
+ timeseries_errors = false ,
340
+ dense_errors = false , kwargs... )
341
+ end
342
+ else
343
+ if typeof (_prob) <: DAEProblem
344
+ () -> @elapsed solve (_prob, alg;
345
+ abstol = abstols[i],
346
+ reltol = reltols[i],
347
+ dt = dts[i],
348
+ timeseries_errors = false ,
349
+ dense_errors = false , kwargs... )
350
+ else
351
+ () -> @elapsed solve (_prob, alg;
352
+ abstol = abstols[i],
353
+ reltol = reltols[i],
354
+ dt = dts[i],
355
+ timeseries_errors = false ,
356
+ dense_errors = false , kwargs... )
357
+ end
358
+ end
359
+ end
360
+ benchmark_f () # pre-compile
361
+
362
+ b_t = benchmark_f ()
363
+ if b_t > seconds
364
+ times[i] = b_t
365
+ else
366
+ times[i] = mapreduce (i -> benchmark_f (), min, 2 : numruns; init = b_t)
367
+ end
368
+ end
369
+ end
370
+ return WorkPrecision (prob, abstols, reltols, errors, times, name, N)
371
+ end
372
+
276
373
# Work precision information for a nonlinear problem.
277
374
function WorkPrecision (prob:: NonlinearProblem , alg, abstols, reltols, dts = nothing ; name = nothing , appxsol = nothing , error_estimate = :l2 , numruns = 20 , seconds = 2 , kwargs... )
278
375
isnothing (appxsol) && error (" Must provide the real value as the \" appxsol\" kwarg." )
@@ -587,6 +684,33 @@ function WorkPrecisionSet(prob::AbstractEnsembleProblem, abstols, reltols, setup
587
684
Int (trajectories))
588
685
end
589
686
687
+ function WorkPrecisionSet (prob:: AbstractBVProblem ,
688
+ abstols, reltols, setups;
689
+ print_names = false , names = nothing , appxsol = nothing ,
690
+ error_estimate = :final ,
691
+ test_dt = nothing , kwargs... )
692
+ N = length (setups)
693
+ @assert names === nothing || length (setups) == length (names)
694
+ wps = Vector {WorkPrecision} (undef, N)
695
+ if names === nothing
696
+ names = [_default_name (setup[:alg ]) for setup in setups]
697
+ end
698
+ for i in 1 : N
699
+ print_names && println (names[i])
700
+ _abstols = get (setups[i], :abstols , abstols)
701
+ _reltols = get (setups[i], :reltols , reltols)
702
+ _dts = get (setups[i], :dts , nothing )
703
+ filtered_setup = filter (p -> p. first in DiffEqBase. allowedkeywords, setups[i])
704
+
705
+ wps[i] = WorkPrecision (prob, setups[i][:alg ], _abstols, _reltols, _dts;
706
+ appxsol = appxsol,
707
+ error_estimate = error_estimate,
708
+ name = names[i], kwargs... , filtered_setup... )
709
+ end
710
+ return WorkPrecisionSet (wps, N, abstols, reltols, prob, setups, names, error_estimate,
711
+ nothing )
712
+ end
713
+
590
714
function get_sample_errors (prob:: AbstractRODEProblem , setup, test_dt = nothing ;
591
715
appxsol_setup = nothing ,
592
716
numruns, error_estimate = :final ,
0 commit comments