From b150b8874d90a6804c98e0232db2e3a958589edf Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 02:03:40 +0530 Subject: [PATCH 01/45] Added DAE solvers --- lib/OrdinaryDiffEqDAE/Project.toml | 20 +++ .../src/OrdinaryDiffEqDAE.jl | 16 +++ lib/OrdinaryDiffEqDAE/src/alg_utils.jl | 12 ++ lib/OrdinaryDiffEqDAE/src/algorithms.jl | 75 ++++++++++ lib/OrdinaryDiffEqDAE/src/controllers.jl | 130 +++++++++++++++++ .../OrdinaryDiffEqDAE/src}/dae_caches.jl | 2 +- .../src}/dae_perform_step.jl | 2 +- src/OrdinaryDiffEq.jl | 6 +- src/alg_utils.jl | 10 -- src/algorithms.jl | 78 +--------- src/integrators/controllers.jl | 133 +----------------- 11 files changed, 261 insertions(+), 223 deletions(-) create mode 100644 lib/OrdinaryDiffEqDAE/Project.toml create mode 100644 lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/algorithms.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/controllers.jl rename {src/caches => lib/OrdinaryDiffEqDAE/src}/dae_caches.jl (99%) rename {src/perform_step => lib/OrdinaryDiffEqDAE/src}/dae_perform_step.jl (99%) diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml new file mode 100644 index 0000000000..ee3e8c74e7 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/Project.toml @@ -0,0 +1,20 @@ +name = "OrdinaryDiffEqDAE" +uuid = "7d2d7016-1c68-401d-834f-6be2c6dc7d88" +authors = ["ParamThakkar123 "] +version = "1.0.0" + +[deps] +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[compat] +julia = "1.10" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl new file mode 100644 index 0000000000..0be59f3cbf --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -0,0 +1,16 @@ +module OrdinaryDiffEqDAE + +import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, + DEFAULT_PRECS, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache +using TruncatedStacktraces + +include("algorithms.jl") +include("alg_utils.jl") +include("controllers.jl") +include("dae_caches.jl") +include("dae_perform_step.jl") + +export DABDF2, DImplicitEuler, DFBDF + +end # module OrdinaryDiffEqDAE diff --git a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl new file mode 100644 index 0000000000..ff0d60daac --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl @@ -0,0 +1,12 @@ +isadaptive(alg::DImplicitEuler) = true +isadaptive(alg::DABDF2) = true +isadaptive(alg::DFBDF) = true + +alg_extrapolates(alg::DImplicitEuler) = true +alg_extrapolates(alg::DABDF2) = true + +alg_order(alg::DImplicitEuler) = 1 +alg_order(alg::DABDF2) = 2 +alg_order(alg::DFBDF) = 1#dummy value + +isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/algorithms.jl b/lib/OrdinaryDiffEqDAE/src/algorithms.jl new file mode 100644 index 0000000000..f8584348a5 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/algorithms.jl @@ -0,0 +1,75 @@ +struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DImplicitEuler(; + chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +#= +struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, + linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = + DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( + linsolve,nlsolve,precs,extrapolant) +=# + +struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + controller::Symbol +end +function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, controller = :Standard) where {MO} + DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, + controller) +end + +TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/controllers.jl b/lib/OrdinaryDiffEqDAE/src/controllers.jl new file mode 100644 index 0000000000..4ae1a93a28 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/controllers.jl @@ -0,0 +1,130 @@ +function step_reject_controller!(integrator, ::DFBDF) + bdf_step_reject_controller!(integrator, integrator.cache.terkm1) +end + +function post_newton_controller!(integrator, alg) + integrator.dt = integrator.dt / integrator.opts.failfactor + nothing +end + +function post_newton_controller!(integrator, alg::DFBDF) + @unpack cache = integrator + if cache.order > 1 && cache.nlsolver.nfails >= 3 + cache.order -= 1 + end + integrator.dt = integrator.dt / integrator.opts.failfactor + integrator.cache.consfailcnt += 1 + integrator.cache.nconsteps = 0 + nothing +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqMutableCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache + k = cache.order + # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] + end + @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqConstantCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache + k = cache.order + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + if u isa Number + for i in 2:(k - 2) + terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] + end + terk_tmp *= abs(dt^(k - 2)) + else + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * + u_history[:, i - 1] + end + terk_tmp = reshape(vc, size(terk_tmp)) + terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) + end + atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function stepsize_controller!(integrator, + alg::DFBDF{max_order}) where { + max_order, +} + @unpack cache = integrator + cache.prev_order = cache.order + k, terk = choose_order!(alg, integrator, cache, Val(max_order)) + if k != cache.order + integrator.cache.nconsteps = 0 + cache.order = k + end + if iszero(terk) + q = inv(integrator.opts.qmax) + else + q = ((2 * terk / (k + 1))^(1 / (k + 1))) + end + integrator.qold = q + q +end + +function step_accept_controller!(integrator, alg::DFBDF{max_order}, + q) where {max_order} + integrator.cache.consfailcnt = 0 + if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min + q = one(q) + end + integrator.cache.nconsteps += 1 + integrator.cache.iters_from_event += 1 + return integrator.dt / q +end \ No newline at end of file diff --git a/src/caches/dae_caches.jl b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl similarity index 99% rename from src/caches/dae_caches.jl rename to lib/OrdinaryDiffEqDAE/src/dae_caches.jl index cc53b10a61..c432408952 100644 --- a/src/caches/dae_caches.jl +++ b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl @@ -253,4 +253,4 @@ function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltype u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, iters_from_event) -end +end \ No newline at end of file diff --git a/src/perform_step/dae_perform_step.jl b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl similarity index 99% rename from src/perform_step/dae_perform_step.jl rename to lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl index a89ddc0001..4b4eab7e71 100644 --- a/src/perform_step/dae_perform_step.jl +++ b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl @@ -457,4 +457,4 @@ function perform_step!(integrator, cache::DFBDFCache{max_order}, @.. broadcast=false integrator.fsallast=integrator.du = (nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dt) #TODO Lorenz plot seems not smooth -end +end \ No newline at end of file diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 6214e87808..4ba78958c1 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -156,7 +156,6 @@ include("caches/adams_bashforth_moulton_caches.jl") include("caches/nordsieck_caches.jl") include("caches/prk_caches.jl") include("caches/pdirk_caches.jl") -include("caches/dae_caches.jl") include("caches/qprk_caches.jl") include("tableaus/low_order_rk_tableaus.jl") @@ -289,8 +288,11 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_finite_difference_weights, estimate_terk, calc_Lagrange_interp, bdf_step_reject_controller! + +include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") +using ..OrdinaryDiffEqDAE +export DImplicitEuler, DABDF2, DFBDF include("nlsolve/newton.jl") -include("perform_step/dae_perform_step.jl") import PrecompileTools diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 77bf1df0f4..34e9722c1d 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -41,7 +41,6 @@ isfsal(alg::Rodas4P) = false isfsal(alg::Rodas4P2) = false # Pseudo Non-FSAL isfsal(alg::PDIRK44) = false -isfsal(alg::DImplicitEuler) = false isfsal(alg::RKO65) = false isfsal(alg::FRK65) = true #isfsal(alg::RKM) = false @@ -153,9 +152,6 @@ ismultistep(alg::ETD2) = true isadaptive(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false isadaptive(alg::OrdinaryDiffEqAdaptiveAlgorithm) = true isadaptive(alg::OrdinaryDiffEqCompositeAlgorithm) = all(isadaptive.(alg.algs)) -isadaptive(alg::DImplicitEuler) = true -isadaptive(alg::DABDF2) = true -isadaptive(alg::DFBDF) = true anyadaptive(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = isadaptive(alg) anyadaptive(alg::OrdinaryDiffEqCompositeAlgorithm) = any(isadaptive, alg.algs) @@ -346,8 +342,6 @@ end alg_extrapolates(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false alg_extrapolates(alg::CompositeAlgorithm) = any(alg_extrapolates.(alg.algs)) -alg_extrapolates(alg::DImplicitEuler) = true -alg_extrapolates(alg::DABDF2) = true alg_extrapolates(alg::MagnusLeapfrog) = true function alg_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) @@ -509,10 +503,6 @@ alg_order(alg::JVODE) = 1 #dummy value alg_order(alg::PDIRK44) = 4 -alg_order(alg::DImplicitEuler) = 1 -alg_order(alg::DABDF2) = 2 -alg_order(alg::DFBDF) = 1#dummy value - alg_order(alg::Alshina2) = 2 alg_order(alg::Alshina3) = 3 alg_order(alg::Alshina6) = 6 diff --git a/src/algorithms.jl b/src/algorithms.jl index 1b921906bb..1ec6d9e17b 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -1093,80 +1093,4 @@ end const MultistepAlgorithms = Union{ AB3, AB4, AB5, ABM32, ABM43, ABM54} -const SplitAlgorithms = Union{CNAB2, CNLF2} - -#= -struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, - linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = - DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( - linsolve,nlsolve,precs,extrapolant) -=# - -struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DImplicitEuler(; - chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - controller::Symbol -end -function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, controller = :Standard) where {MO} - DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, - controller) -end - -TruncatedStacktraces.@truncate_stacktrace DFBDF +const SplitAlgorithms = Union{CNAB2, CNLF2} \ No newline at end of file diff --git a/src/integrators/controllers.jl b/src/integrators/controllers.jl index 69169566c3..e4cab76b04 100644 --- a/src/integrators/controllers.jl +++ b/src/integrators/controllers.jl @@ -473,135 +473,4 @@ end function step_reject_controller!(integrator, alg::JVODE) integrator.dt *= integrator.qold -end - -function step_reject_controller!(integrator, ::DFBDF) - bdf_step_reject_controller!(integrator, integrator.cache.terkm1) -end - -function post_newton_controller!(integrator, alg) - integrator.dt = integrator.dt / integrator.opts.failfactor - nothing -end - -function post_newton_controller!(integrator, alg::DFBDF) - @unpack cache = integrator - if cache.order > 1 && cache.nlsolver.nfails >= 3 - cache.order -= 1 - end - integrator.dt = integrator.dt / integrator.opts.failfactor - integrator.cache.consfailcnt += 1 - integrator.cache.nconsteps = 0 - nothing -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqMutableCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache - k = cache.order - # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] - end - @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqConstantCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache - k = cache.order - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - if u isa Number - for i in 2:(k - 2) - terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] - end - terk_tmp *= abs(dt^(k - 2)) - else - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * - u_history[:, i - 1] - end - terk_tmp = reshape(vc, size(terk_tmp)) - terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) - end - atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function stepsize_controller!(integrator, - alg::DFBDF{max_order}) where { - max_order, -} - @unpack cache = integrator - cache.prev_order = cache.order - k, terk = choose_order!(alg, integrator, cache, Val(max_order)) - if k != cache.order - integrator.cache.nconsteps = 0 - cache.order = k - end - if iszero(terk) - q = inv(integrator.opts.qmax) - else - q = ((2 * terk / (k + 1))^(1 / (k + 1))) - end - integrator.qold = q - q -end - -function step_accept_controller!(integrator, alg::DFBDF{max_order}, - q) where {max_order} - integrator.cache.consfailcnt = 0 - if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min - q = one(q) - end - integrator.cache.nconsteps += 1 - integrator.cache.iters_from_event += 1 - return integrator.dt / q -end +end \ No newline at end of file From 09f9af8ce03445da96734237d70a1403a94086a3 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 02:17:41 +0530 Subject: [PATCH 02/45] @unpack --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 3 ++- .../OrdinaryDiffEqDAE/test}/dae_ad_tests.jl | 2 +- .../test}/dae_convergence_tests.jl | 2 +- .../OrdinaryDiffEqDAE/test}/dae_event.jl | 2 +- .../test}/dae_initialization_tests.jl | 2 +- .../test}/dae_initialize_integration.jl | 2 +- .../OrdinaryDiffEqDAE/test}/hard_dae.jl | 2 +- lib/OrdinaryDiffEqDAE/test/runtest.jl | 0 src/OrdinaryDiffEq.jl | 2 +- test/runtests.jl | 18 ++++++++++++------ 10 files changed, 21 insertions(+), 14 deletions(-) rename {test/interface => lib/OrdinaryDiffEqDAE/test}/dae_ad_tests.jl (99%) rename {test/algconvergence => lib/OrdinaryDiffEqDAE/test}/dae_convergence_tests.jl (99%) rename {test/integrators => lib/OrdinaryDiffEqDAE/test}/dae_event.jl (95%) rename {test/integrators => lib/OrdinaryDiffEqDAE/test}/dae_initialization_tests.jl (99%) rename {test/interface => lib/OrdinaryDiffEqDAE/test}/dae_initialize_integration.jl (98%) rename {test/regression => lib/OrdinaryDiffEqDAE/test}/hard_dae.jl (99%) create mode 100644 lib/OrdinaryDiffEqDAE/test/runtest.jl diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 0be59f3cbf..ed77fee311 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -2,7 +2,8 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + @unpack using TruncatedStacktraces include("algorithms.jl") diff --git a/test/interface/dae_ad_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl similarity index 99% rename from test/interface/dae_ad_tests.jl rename to lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl index 1040152adb..398aa310be 100644 --- a/test/interface/dae_ad_tests.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl @@ -57,4 +57,4 @@ sol1 = solve(prob, DFBDF(), dt = 1e-5, abstol = 1e-8, reltol = 1e-8) sum(sol) end @test ForwardDiff.gradient(f, [0.04, 3e7, 1e4])≈[0, 0, 0] atol=1e-8 -end +end \ No newline at end of file diff --git a/test/algconvergence/dae_convergence_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl similarity index 99% rename from test/algconvergence/dae_convergence_tests.jl rename to lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl index 859f194d68..e3ef2dd474 100644 --- a/test/algconvergence/dae_convergence_tests.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl @@ -53,4 +53,4 @@ prob_dae_linear_oop = DAEProblem( @test sim24.𝒪est[:final]≈2 atol=testTol @test_nowarn solve(prob, DFBDF()) -end +end \ No newline at end of file diff --git a/test/integrators/dae_event.jl b/lib/OrdinaryDiffEqDAE/test/dae_event.jl similarity index 95% rename from test/integrators/dae_event.jl rename to lib/OrdinaryDiffEqDAE/test/dae_event.jl index 7c32b8d46e..c20b600670 100644 --- a/test/integrators/dae_event.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_event.jl @@ -27,4 +27,4 @@ sol = solve(prob, DFBDF(), callback = cb, tstops = [50.0], abstol = 1e-12, relto @test sol.t[end] == 100.0 @test sol[end][1]≈0.686300529575259 atol=1e-7 @test sol[end][2]≈2.0797982209353813e-6 atol=1e-7 -@test sol[end][3]≈1.31369739062652 atol=1e-7 +@test sol[end][3]≈1.31369739062652 atol=1e-7 \ No newline at end of file diff --git a/test/integrators/dae_initialization_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl similarity index 99% rename from test/integrators/dae_initialization_tests.jl rename to lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl index b3cdd2a858..5cf37c27f4 100644 --- a/test/integrators/dae_initialization_tests.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl @@ -265,4 +265,4 @@ f = ODEFunction(f2, mass_matrix = Diagonal([1.0, 1.0, 0.0])) prob = ODEProblem(f, ones(3), (0.0, 1.0)) integrator = init(prob, Rodas5P(), initializealg = ShampineCollocationInit(1.0, BrokenNLSolve())) -@test all(isequal(reinterpret(Float64, 0xDEADBEEFDEADBEEF)), integrator.u) +@test all(isequal(reinterpret(Float64, 0xDEADBEEFDEADBEEF)), integrator.u) \ No newline at end of file diff --git a/test/interface/dae_initialize_integration.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl similarity index 98% rename from test/interface/dae_initialize_integration.jl rename to lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl index 2d09cb1a41..33913925e2 100644 --- a/test/interface/dae_initialize_integration.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl @@ -75,4 +75,4 @@ sol = solve(prob, Rodas5P(), dt = 1e-10) @test SciMLBase.successful_retcode(sol) @test sol[1] == [1.0] @test sol[2] ≈ [0.9999999998] -@test sol[end] ≈ [-1.0] +@test sol[end] ≈ [-1.0] \ No newline at end of file diff --git a/test/regression/hard_dae.jl b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl similarity index 99% rename from test/regression/hard_dae.jl rename to lib/OrdinaryDiffEqDAE/test/hard_dae.jl index 302de87d2a..f47b226ce1 100644 --- a/test/regression/hard_dae.jl +++ b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl @@ -272,4 +272,4 @@ for prob in [prob1, prob2], alg in [simple_implicit_euler, alg_switch] @test sol(0, idxs = 1) == 5 @test sol(2, idxs = 1) == 0 @test sol(4, idxs = 1) > 10 -end +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 4ba78958c1..cc134875bd 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -466,7 +466,7 @@ export Alshina2, Alshina3, Alshina6 export AutoSwitch, AutoTsit5, AutoDP5, AutoVern6, AutoVern7, AutoVern8, AutoVern9 -export KuttaPRK2p5, PDIRK44, DImplicitEuler, DABDF2, DFBDF +export KuttaPRK2p5, PDIRK44 export ShampineCollocationInit, BrownFullBasicInit, NoInit diff --git a/test/runtests.jl b/test/runtests.jl index 2bce643dd9..5779113d6b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -77,6 +77,12 @@ function activate_sdirk() Pkg.instantiate() end +function activate_dae() + Pkg.activate("../lib/OrdinaryDiffEqDAE") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + #Start Test Script @time begin @@ -141,9 +147,9 @@ end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceV" || GROUP == "Interface") @time @safetestset "Interpolation Derivative Error Tests" include("interface/interpolation_derivative_error_tests.jl") @time @safetestset "AD Tests" include("interface/ad_tests.jl") - @time @safetestset "DAE AD Tests" include("interface/dae_ad_tests.jl") + @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl") @time @safetestset "Newton Tests" include("interface/newton_tests.jl") - @time @safetestset "DAE Initialize Integration" include("interface/dae_initialize_integration.jl") + @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl") end if !is_APPVEYOR && @@ -167,8 +173,8 @@ end @time @safetestset "Reverse Directioned Event Tests" include("integrators/rev_events_tests.jl") @time @safetestset "Differentiation Direction Tests" include("integrators/diffdir_tests.jl") @time @safetestset "Resize Tests" include("integrators/resize_tests.jl") - @time @safetestset "DAE Initialization Tests" include("integrators/dae_initialization_tests.jl") - @time @safetestset "DAE Event Tests" include("integrators/dae_event.jl") + @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl") + @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_event.jl") @time @safetestset "Cache Tests" include("integrators/ode_cache_tests.jl") @time @safetestset "Add Steps Tests" include("integrators/ode_add_steps_tests.jl") @time @safetestset "IMEX Split Function Tests" include("integrators/split_ode_tests.jl") @@ -179,7 +185,7 @@ end @time @safetestset "Special Interp Tests" include("regression/special_interps.jl") @time @safetestset "Inplace Tests" include("regression/ode_inplace_tests.jl") @time @safetestset "Adaptive Tests" include("regression/ode_adaptive_tests.jl") - @time @safetestset "Hard DAE Tests" include("regression/hard_dae.jl") + @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqDAE/test/hard_dae.jl") end if !is_APPVEYOR && (GROUP == "All" || GROUP == "Regression_II" || GROUP == "Regression") @@ -193,7 +199,7 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_I" @time @safetestset "Partitioned Methods Tests" include("algconvergence/partitioned_methods_tests.jl") @time @safetestset "Convergence Tests" include("algconvergence/ode_convergence_tests.jl") - @time @safetestset "DAE Convergence Tests" include("algconvergence/dae_convergence_tests.jl") + @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl") @time @safetestset "Non-autonomous Convergence Tests" include("algconvergence/non-autonomous_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("algconvergence/adams_tests.jl") @time @safetestset "Nordsieck Tests" include("algconvergence/nordsieck_tests.jl") From dbb4e5fa28cc685df0100047ef0e55fb518c3de5 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:19:15 +0530 Subject: [PATCH 03/45] @.. --- lib/OrdinaryDiffEqDAE/Project.toml | 1 + lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml index ee3e8c74e7..b15e3bbe39 100644 --- a/lib/OrdinaryDiffEqDAE/Project.toml +++ b/lib/OrdinaryDiffEqDAE/Project.toml @@ -6,6 +6,7 @@ version = "1.0.0" [deps] OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" [extras] DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index ed77fee311..82a1d7d496 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -5,6 +5,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack using TruncatedStacktraces +import FastBroadCast: @.. include("algorithms.jl") include("alg_utils.jl") From 70e3240518eab50f367d01e08c0a6177ea0324f1 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:41:13 +0530 Subject: [PATCH 04/45] @.. --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- lib/OrdinaryDiffEqDAE/test/runtest.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 82a1d7d496..9643b52c2d 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -5,7 +5,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack using TruncatedStacktraces -import FastBroadCast: @.. +import FastBroadcast: @.. include("algorithms.jl") include("alg_utils.jl") diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl index e69de29bb2..a639da4027 100644 --- a/lib/OrdinaryDiffEqDAE/test/runtest.jl +++ b/lib/OrdinaryDiffEqDAE/test/runtest.jl @@ -0,0 +1,2 @@ +using SafeTestsets + From c40127efaf84f06746bea3cdfa227129cbe5e90f Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:43:51 +0530 Subject: [PATCH 05/45] @cache --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 9643b52c2d..374e6b772b 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -3,7 +3,7 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack + @unpack, @cache using TruncatedStacktraces import FastBroadcast: @.. From d9769abf17aedbfaa9b666163ee9911034c6b6b1 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:46:02 +0530 Subject: [PATCH 06/45] MuladdMacro --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 374e6b772b..0657ec30b9 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -4,7 +4,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack, @cache -using TruncatedStacktraces +using TruncatedStacktraces, MuladdMacro import FastBroadcast: @.. include("algorithms.jl") From 44e3a2a6e07e645624b502bcf0810be15ca039f5 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:56:06 +0530 Subject: [PATCH 07/45] controllers --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 0657ec30b9..9017917bb8 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -3,7 +3,9 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack, @cache + @unpack, @cache, default_controller, stepsize_controller!, + step_accept_controller!, + step_reject_controller!, post_newton_controller! using TruncatedStacktraces, MuladdMacro import FastBroadcast: @.. From 79a15979908064270e55c7bf1822d1df2d6ffb89 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 11:13:21 +0530 Subject: [PATCH 08/45] post_newton_controller! --- src/OrdinaryDiffEq.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index cc134875bd..18d1dcc5dc 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -166,7 +166,6 @@ include("tableaus/qprk_tableaus.jl") include("integrators/type.jl") include("integrators/controllers.jl") -include("integrators/integrator_utils.jl") include("integrators/integrator_interface.jl") include("cache_utils.jl") @@ -292,6 +291,10 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") using ..OrdinaryDiffEqDAE export DImplicitEuler, DABDF2, DFBDF + + +using ..OrdinaryDiffEqDAE: post_newton_controller! +include("integrators/integrator_utils.jl") include("nlsolve/newton.jl") import PrecompileTools From 24d3c61a4b8897ea0cc2206a9aa0353838ebca57 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Fri, 26 Jul 2024 22:20:47 +0530 Subject: [PATCH 09/45] DAE added to BDF --- .../src/OrdinaryDiffEqBDF.jl | 7 +- lib/OrdinaryDiffEqBDF/src/alg_utils.jl | 13 ++ lib/OrdinaryDiffEqBDF/src/algorithms.jl | 76 ++++++++++ lib/OrdinaryDiffEqBDF/src/controllers.jl | 132 ++++++++++++++++++ .../src/dae_caches.jl | 0 .../src/dae_perform_step.jl | 0 .../test/dae_ad_tests.jl | 0 .../test/dae_convergence_tests.jl | 0 .../test/dae_event.jl | 0 .../test/dae_initialization_tests.jl | 0 .../test/dae_initialize_integration.jl | 0 .../test/hard_dae.jl | 0 .../test/runtest.jl | 0 lib/OrdinaryDiffEqDAE/Project.toml | 21 --- .../src/OrdinaryDiffEqDAE.jl | 20 --- lib/OrdinaryDiffEqDAE/src/alg_utils.jl | 12 -- lib/OrdinaryDiffEqDAE/src/algorithms.jl | 75 ---------- lib/OrdinaryDiffEqDAE/src/controllers.jl | 130 ----------------- src/OrdinaryDiffEq.jl | 10 +- test/runtests.jl | 12 +- 20 files changed, 235 insertions(+), 273 deletions(-) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/src/dae_caches.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/src/dae_perform_step.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_ad_tests.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_convergence_tests.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_event.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_initialization_tests.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_initialize_integration.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/hard_dae.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/runtest.jl (100%) delete mode 100644 lib/OrdinaryDiffEqDAE/Project.toml delete mode 100644 lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/controllers.jl diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 2080050161..740ced5261 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -22,7 +22,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, get_current_alg_order, get_current_adaptive_order, default_controller, stepsize_controller!, step_accept_controller!, step_reject_controller!, post_newton_controller!, - u_modified! + u_modified!, DAEAlgorithm, _unwrap_val using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA using LinearAlgebra: I @@ -32,10 +32,13 @@ include("algorithms.jl") include("alg_utils.jl") include("bdf_utils.jl") include("bdf_caches.jl") +include("dae_caches.jl") include("controllers.jl") +include("dae_perform_step.jl") include("bdf_perform_step.jl") export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, - SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK + SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK, + DABDF2, DImplicitEuler, DFBDF end diff --git a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl index aea50d0df0..8400ef7ea7 100644 --- a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl @@ -24,3 +24,16 @@ get_current_alg_order(alg::FBDF, cache) = cache.order get_current_adaptive_order(alg::QNDF, cache) = cache.order get_current_adaptive_order(alg::FBDF, cache) = cache.order + +isadaptive(alg::DImplicitEuler) = true +isadaptive(alg::DABDF2) = true +isadaptive(alg::DFBDF) = true + +alg_extrapolates(alg::DImplicitEuler) = true +alg_extrapolates(alg::DABDF2) = true + +alg_order(alg::DImplicitEuler) = 1 +alg_order(alg::DABDF2) = 2 +alg_order(alg::DFBDF) = 1#dummy value + +isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index 0a91dce0b6..0ed740a489 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -388,3 +388,79 @@ unew = uold + dt * (f1(unew) + f2(y1)) See also `SBDF`, `IMEXEuler`. """ IMEXEulerARK(; kwargs...) = SBDF(1; ark = true, kwargs...) + +struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DImplicitEuler(; + chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +#= +struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, + linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = + DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( + linsolve,nlsolve,precs,extrapolant) +=# + +struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + controller::Symbol +end +function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, controller = :Standard) where {MO} + DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, + controller) +end + +TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/controllers.jl b/lib/OrdinaryDiffEqBDF/src/controllers.jl index 4c1e8b9274..23b9aab655 100644 --- a/lib/OrdinaryDiffEqBDF/src/controllers.jl +++ b/lib/OrdinaryDiffEqBDF/src/controllers.jl @@ -262,3 +262,135 @@ function step_accept_controller!(integrator, alg::FBDF{max_order}, integrator.cache.iters_from_event += 1 return integrator.dt / q end + + +function step_reject_controller!(integrator, ::DFBDF) + bdf_step_reject_controller!(integrator, integrator.cache.terkm1) +end + +function post_newton_controller!(integrator, alg) + integrator.dt = integrator.dt / integrator.opts.failfactor + nothing +end + +function post_newton_controller!(integrator, alg::DFBDF) + @unpack cache = integrator + if cache.order > 1 && cache.nlsolver.nfails >= 3 + cache.order -= 1 + end + integrator.dt = integrator.dt / integrator.opts.failfactor + integrator.cache.consfailcnt += 1 + integrator.cache.nconsteps = 0 + nothing +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqMutableCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache + k = cache.order + # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] + end + @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqConstantCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache + k = cache.order + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + if u isa Number + for i in 2:(k - 2) + terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] + end + terk_tmp *= abs(dt^(k - 2)) + else + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * + u_history[:, i - 1] + end + terk_tmp = reshape(vc, size(terk_tmp)) + terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) + end + atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function stepsize_controller!(integrator, + alg::DFBDF{max_order}) where { + max_order, +} + @unpack cache = integrator + cache.prev_order = cache.order + k, terk = choose_order!(alg, integrator, cache, Val(max_order)) + if k != cache.order + integrator.cache.nconsteps = 0 + cache.order = k + end + if iszero(terk) + q = inv(integrator.opts.qmax) + else + q = ((2 * terk / (k + 1))^(1 / (k + 1))) + end + integrator.qold = q + q +end + +function step_accept_controller!(integrator, alg::DFBDF{max_order}, + q) where {max_order} + integrator.cache.consfailcnt = 0 + if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min + q = one(q) + end + integrator.cache.nconsteps += 1 + integrator.cache.iters_from_event += 1 + return integrator.dt / q +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_caches.jl b/lib/OrdinaryDiffEqBDF/src/dae_caches.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/src/dae_caches.jl rename to lib/OrdinaryDiffEqBDF/src/dae_caches.jl diff --git a/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl b/lib/OrdinaryDiffEqBDF/src/dae_perform_step.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl rename to lib/OrdinaryDiffEqBDF/src/dae_perform_step.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl b/lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl rename to lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl b/lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl rename to lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_event.jl b/lib/OrdinaryDiffEqBDF/test/dae_event.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_event.jl rename to lib/OrdinaryDiffEqBDF/test/dae_event.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl b/lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl rename to lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl b/lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl rename to lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl diff --git a/lib/OrdinaryDiffEqDAE/test/hard_dae.jl b/lib/OrdinaryDiffEqBDF/test/hard_dae.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/hard_dae.jl rename to lib/OrdinaryDiffEqBDF/test/hard_dae.jl diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqBDF/test/runtest.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/runtest.jl rename to lib/OrdinaryDiffEqBDF/test/runtest.jl diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml deleted file mode 100644 index b15e3bbe39..0000000000 --- a/lib/OrdinaryDiffEqDAE/Project.toml +++ /dev/null @@ -1,21 +0,0 @@ -name = "OrdinaryDiffEqDAE" -uuid = "7d2d7016-1c68-401d-834f-6be2c6dc7d88" -authors = ["ParamThakkar123 "] -version = "1.0.0" - -[deps] -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[compat] -julia = "1.10" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl deleted file mode 100644 index 9017917bb8..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ /dev/null @@ -1,20 +0,0 @@ -module OrdinaryDiffEqDAE - -import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, - DEFAULT_PRECS, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack, @cache, default_controller, stepsize_controller!, - step_accept_controller!, - step_reject_controller!, post_newton_controller! -using TruncatedStacktraces, MuladdMacro -import FastBroadcast: @.. - -include("algorithms.jl") -include("alg_utils.jl") -include("controllers.jl") -include("dae_caches.jl") -include("dae_perform_step.jl") - -export DABDF2, DImplicitEuler, DFBDF - -end # module OrdinaryDiffEqDAE diff --git a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl deleted file mode 100644 index ff0d60daac..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl +++ /dev/null @@ -1,12 +0,0 @@ -isadaptive(alg::DImplicitEuler) = true -isadaptive(alg::DABDF2) = true -isadaptive(alg::DFBDF) = true - -alg_extrapolates(alg::DImplicitEuler) = true -alg_extrapolates(alg::DABDF2) = true - -alg_order(alg::DImplicitEuler) = 1 -alg_order(alg::DABDF2) = 2 -alg_order(alg::DFBDF) = 1#dummy value - -isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/algorithms.jl b/lib/OrdinaryDiffEqDAE/src/algorithms.jl deleted file mode 100644 index f8584348a5..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/algorithms.jl +++ /dev/null @@ -1,75 +0,0 @@ -struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DImplicitEuler(; - chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -#= -struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, - linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = - DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( - linsolve,nlsolve,precs,extrapolant) -=# - -struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - controller::Symbol -end -function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, controller = :Standard) where {MO} - DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, - controller) -end - -TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/controllers.jl b/lib/OrdinaryDiffEqDAE/src/controllers.jl deleted file mode 100644 index 4ae1a93a28..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/controllers.jl +++ /dev/null @@ -1,130 +0,0 @@ -function step_reject_controller!(integrator, ::DFBDF) - bdf_step_reject_controller!(integrator, integrator.cache.terkm1) -end - -function post_newton_controller!(integrator, alg) - integrator.dt = integrator.dt / integrator.opts.failfactor - nothing -end - -function post_newton_controller!(integrator, alg::DFBDF) - @unpack cache = integrator - if cache.order > 1 && cache.nlsolver.nfails >= 3 - cache.order -= 1 - end - integrator.dt = integrator.dt / integrator.opts.failfactor - integrator.cache.consfailcnt += 1 - integrator.cache.nconsteps = 0 - nothing -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqMutableCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache - k = cache.order - # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] - end - @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqConstantCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache - k = cache.order - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - if u isa Number - for i in 2:(k - 2) - terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] - end - terk_tmp *= abs(dt^(k - 2)) - else - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * - u_history[:, i - 1] - end - terk_tmp = reshape(vc, size(terk_tmp)) - terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) - end - atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function stepsize_controller!(integrator, - alg::DFBDF{max_order}) where { - max_order, -} - @unpack cache = integrator - cache.prev_order = cache.order - k, terk = choose_order!(alg, integrator, cache, Val(max_order)) - if k != cache.order - integrator.cache.nconsteps = 0 - cache.order = k - end - if iszero(terk) - q = inv(integrator.opts.qmax) - else - q = ((2 * terk / (k + 1))^(1 / (k + 1))) - end - integrator.qold = q - q -end - -function step_accept_controller!(integrator, alg::DFBDF{max_order}, - q) where {max_order} - integrator.cache.consfailcnt = 0 - if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min - q = one(q) - end - integrator.cache.nconsteps += 1 - integrator.cache.iters_from_event += 1 - return integrator.dt / q -end \ No newline at end of file diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 69c6504a62..68cc4991e1 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -273,7 +273,8 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") using ..OrdinaryDiffEqBDF export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, - SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK + SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK, + DImplicitEuler, DABDF2, DFBDF include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault @@ -289,12 +290,7 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp, bdf_step_reject_controller! -include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") -using ..OrdinaryDiffEqDAE -export DImplicitEuler, DABDF2, DFBDF - - -using ..OrdinaryDiffEqDAE: post_newton_controller! +using ..OrdinaryDiffEqBDF: post_newton_controller! include("integrators/integrator_utils.jl") include("nlsolve/newton.jl") diff --git a/test/runtests.jl b/test/runtests.jl index fd9dbd5378..d3f88cdec2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -153,9 +153,9 @@ end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceV" || GROUP == "Interface") @time @safetestset "Interpolation Derivative Error Tests" include("interface/interpolation_derivative_error_tests.jl") @time @safetestset "AD Tests" include("interface/ad_tests.jl") - @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl") + @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl") @time @safetestset "Newton Tests" include("interface/newton_tests.jl") - @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl") + @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl") end if !is_APPVEYOR && @@ -179,8 +179,8 @@ end @time @safetestset "Reverse Directioned Event Tests" include("integrators/rev_events_tests.jl") @time @safetestset "Differentiation Direction Tests" include("integrators/diffdir_tests.jl") @time @safetestset "Resize Tests" include("integrators/resize_tests.jl") - @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl") - @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_event.jl") + @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl") + @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_event.jl") @time @safetestset "Cache Tests" include("integrators/ode_cache_tests.jl") @time @safetestset "Add Steps Tests" include("integrators/ode_add_steps_tests.jl") @time @safetestset "IMEX Split Function Tests" include("integrators/split_ode_tests.jl") @@ -191,7 +191,7 @@ end @time @safetestset "Special Interp Tests" include("regression/special_interps.jl") @time @safetestset "Inplace Tests" include("regression/ode_inplace_tests.jl") @time @safetestset "Adaptive Tests" include("regression/ode_adaptive_tests.jl") - @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqDAE/test/hard_dae.jl") + @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqBDF/test/hard_dae.jl") end if !is_APPVEYOR && (GROUP == "All" || GROUP == "Regression_II" || GROUP == "Regression") @@ -205,7 +205,7 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_I" @time @safetestset "Partitioned Methods Tests" include("algconvergence/partitioned_methods_tests.jl") @time @safetestset "Convergence Tests" include("algconvergence/ode_convergence_tests.jl") - @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl") + @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl") @time @safetestset "Non-autonomous Convergence Tests" include("algconvergence/non-autonomous_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("algconvergence/adams_tests.jl") @time @safetestset "Nordsieck Tests" include("algconvergence/nordsieck_tests.jl") From cc67c34b1dabf5769a41c7fcd979f4288f0dba00 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Fri, 26 Jul 2024 22:31:11 +0530 Subject: [PATCH 10/45] added tests --- lib/OrdinaryDiffEqBDF/test/runtest.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/OrdinaryDiffEqBDF/test/runtest.jl b/lib/OrdinaryDiffEqBDF/test/runtest.jl index a639da4027..aeacfd70d2 100644 --- a/lib/OrdinaryDiffEqBDF/test/runtest.jl +++ b/lib/OrdinaryDiffEqBDF/test/runtest.jl @@ -1,2 +1,8 @@ using SafeTestsets +@time @safetestset "DAE AD Tests" include("dae_ad_tests.jl") +@time @safetestset "DAE Initialize Integration" include("dae_initialize_integration.jl") +@time @safetestset "DAE Initialization Tests" include("dae_initialization_tests.jl") +@time @safetestset "DAE Event Tests" include("dae_event.jl") +@time @safetestset "Hard DAE Tests" include("hard_dae.jl") +@time @safetestset "DAE Convergence Tests" include("dae_convergence_tests.jl") \ No newline at end of file From 1f834d6fb40fbbde3d4eb410403ef96f0b14b806 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Fri, 26 Jul 2024 23:33:54 -0400 Subject: [PATCH 11/45] Update lib/OrdinaryDiffEqBDF/src/algorithms.jl --- lib/OrdinaryDiffEqBDF/src/algorithms.jl | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index 0ed740a489..71900e4925 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -426,19 +426,6 @@ function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = V nlsolve, precs, extrapolant, controller) end -#= -struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, - linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = - DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( - linsolve,nlsolve,precs,extrapolant) -=# struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} max_order::Val{MO} From 4e2352717ac65c0be7fff0f55f7e54acaf527729 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 02:03:40 +0530 Subject: [PATCH 12/45] Added DAE solvers --- lib/OrdinaryDiffEqDAE/Project.toml | 20 +++ .../src/OrdinaryDiffEqDAE.jl | 16 +++ lib/OrdinaryDiffEqDAE/src/alg_utils.jl | 12 ++ lib/OrdinaryDiffEqDAE/src/algorithms.jl | 75 ++++++++++ lib/OrdinaryDiffEqDAE/src/controllers.jl | 130 +++++++++++++++++ .../OrdinaryDiffEqDAE/src}/dae_caches.jl | 2 +- .../src}/dae_perform_step.jl | 2 +- src/OrdinaryDiffEq.jl | 7 +- src/alg_utils.jl | 10 -- src/algorithms.jl | 78 +--------- src/integrators/controllers.jl | 133 +----------------- 11 files changed, 261 insertions(+), 224 deletions(-) create mode 100644 lib/OrdinaryDiffEqDAE/Project.toml create mode 100644 lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/algorithms.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/controllers.jl rename {src/caches => lib/OrdinaryDiffEqDAE/src}/dae_caches.jl (99%) rename {src/perform_step => lib/OrdinaryDiffEqDAE/src}/dae_perform_step.jl (99%) diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml new file mode 100644 index 0000000000..ee3e8c74e7 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/Project.toml @@ -0,0 +1,20 @@ +name = "OrdinaryDiffEqDAE" +uuid = "7d2d7016-1c68-401d-834f-6be2c6dc7d88" +authors = ["ParamThakkar123 "] +version = "1.0.0" + +[deps] +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[compat] +julia = "1.10" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl new file mode 100644 index 0000000000..0be59f3cbf --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -0,0 +1,16 @@ +module OrdinaryDiffEqDAE + +import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, + DEFAULT_PRECS, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache +using TruncatedStacktraces + +include("algorithms.jl") +include("alg_utils.jl") +include("controllers.jl") +include("dae_caches.jl") +include("dae_perform_step.jl") + +export DABDF2, DImplicitEuler, DFBDF + +end # module OrdinaryDiffEqDAE diff --git a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl new file mode 100644 index 0000000000..ff0d60daac --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl @@ -0,0 +1,12 @@ +isadaptive(alg::DImplicitEuler) = true +isadaptive(alg::DABDF2) = true +isadaptive(alg::DFBDF) = true + +alg_extrapolates(alg::DImplicitEuler) = true +alg_extrapolates(alg::DABDF2) = true + +alg_order(alg::DImplicitEuler) = 1 +alg_order(alg::DABDF2) = 2 +alg_order(alg::DFBDF) = 1#dummy value + +isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/algorithms.jl b/lib/OrdinaryDiffEqDAE/src/algorithms.jl new file mode 100644 index 0000000000..f8584348a5 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/algorithms.jl @@ -0,0 +1,75 @@ +struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DImplicitEuler(; + chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +#= +struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, + linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = + DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( + linsolve,nlsolve,precs,extrapolant) +=# + +struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + controller::Symbol +end +function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, controller = :Standard) where {MO} + DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, + controller) +end + +TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/controllers.jl b/lib/OrdinaryDiffEqDAE/src/controllers.jl new file mode 100644 index 0000000000..4ae1a93a28 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/controllers.jl @@ -0,0 +1,130 @@ +function step_reject_controller!(integrator, ::DFBDF) + bdf_step_reject_controller!(integrator, integrator.cache.terkm1) +end + +function post_newton_controller!(integrator, alg) + integrator.dt = integrator.dt / integrator.opts.failfactor + nothing +end + +function post_newton_controller!(integrator, alg::DFBDF) + @unpack cache = integrator + if cache.order > 1 && cache.nlsolver.nfails >= 3 + cache.order -= 1 + end + integrator.dt = integrator.dt / integrator.opts.failfactor + integrator.cache.consfailcnt += 1 + integrator.cache.nconsteps = 0 + nothing +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqMutableCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache + k = cache.order + # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] + end + @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqConstantCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache + k = cache.order + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + if u isa Number + for i in 2:(k - 2) + terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] + end + terk_tmp *= abs(dt^(k - 2)) + else + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * + u_history[:, i - 1] + end + terk_tmp = reshape(vc, size(terk_tmp)) + terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) + end + atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function stepsize_controller!(integrator, + alg::DFBDF{max_order}) where { + max_order, +} + @unpack cache = integrator + cache.prev_order = cache.order + k, terk = choose_order!(alg, integrator, cache, Val(max_order)) + if k != cache.order + integrator.cache.nconsteps = 0 + cache.order = k + end + if iszero(terk) + q = inv(integrator.opts.qmax) + else + q = ((2 * terk / (k + 1))^(1 / (k + 1))) + end + integrator.qold = q + q +end + +function step_accept_controller!(integrator, alg::DFBDF{max_order}, + q) where {max_order} + integrator.cache.consfailcnt = 0 + if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min + q = one(q) + end + integrator.cache.nconsteps += 1 + integrator.cache.iters_from_event += 1 + return integrator.dt / q +end \ No newline at end of file diff --git a/src/caches/dae_caches.jl b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl similarity index 99% rename from src/caches/dae_caches.jl rename to lib/OrdinaryDiffEqDAE/src/dae_caches.jl index cc53b10a61..c432408952 100644 --- a/src/caches/dae_caches.jl +++ b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl @@ -253,4 +253,4 @@ function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltype u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, iters_from_event) -end +end \ No newline at end of file diff --git a/src/perform_step/dae_perform_step.jl b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl similarity index 99% rename from src/perform_step/dae_perform_step.jl rename to lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl index a89ddc0001..4b4eab7e71 100644 --- a/src/perform_step/dae_perform_step.jl +++ b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl @@ -457,4 +457,4 @@ function perform_step!(integrator, cache::DFBDFCache{max_order}, @.. broadcast=false integrator.fsallast=integrator.du = (nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dt) #TODO Lorenz plot seems not smooth -end +end \ No newline at end of file diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 6c66031e7b..1f57f77891 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -155,7 +155,6 @@ include("caches/adams_bashforth_moulton_caches.jl") include("caches/nordsieck_caches.jl") include("caches/prk_caches.jl") include("caches/pdirk_caches.jl") -include("caches/dae_caches.jl") include("caches/qprk_caches.jl") include("tableaus/low_order_rk_tableaus.jl") @@ -290,9 +289,11 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_finite_difference_weights, estimate_terk, calc_Lagrange_interp, bdf_step_reject_controller! - + +include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") +using ..OrdinaryDiffEqDAE +export DImplicitEuler, DABDF2, DFBDF include("nlsolve/newton.jl") -include("perform_step/dae_perform_step.jl") import PrecompileTools diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 4120c7652b..80d21e2b8b 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -41,7 +41,6 @@ isfsal(alg::Rodas4P) = false isfsal(alg::Rodas4P2) = false # Pseudo Non-FSAL isfsal(alg::PDIRK44) = false -isfsal(alg::DImplicitEuler) = false isfsal(alg::RKO65) = false isfsal(alg::FRK65) = true #isfsal(alg::RKM) = false @@ -155,9 +154,6 @@ ismultistep(alg::ETD2) = true isadaptive(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false isadaptive(alg::OrdinaryDiffEqAdaptiveAlgorithm) = true isadaptive(alg::OrdinaryDiffEqCompositeAlgorithm) = all(isadaptive.(alg.algs)) -isadaptive(alg::DImplicitEuler) = true -isadaptive(alg::DABDF2) = true -isadaptive(alg::DFBDF) = true anyadaptive(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = isadaptive(alg) anyadaptive(alg::OrdinaryDiffEqCompositeAlgorithm) = any(isadaptive, alg.algs) @@ -347,8 +343,6 @@ end alg_extrapolates(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false alg_extrapolates(alg::CompositeAlgorithm) = any(alg_extrapolates.(alg.algs)) -alg_extrapolates(alg::DImplicitEuler) = true -alg_extrapolates(alg::DABDF2) = true alg_extrapolates(alg::MagnusLeapfrog) = true function alg_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) @@ -507,10 +501,6 @@ alg_order(alg::JVODE) = 1 #dummy value alg_order(alg::PDIRK44) = 4 -alg_order(alg::DImplicitEuler) = 1 -alg_order(alg::DABDF2) = 2 -alg_order(alg::DFBDF) = 1#dummy value - alg_order(alg::Alshina2) = 2 alg_order(alg::Alshina3) = 3 alg_order(alg::Alshina6) = 6 diff --git a/src/algorithms.jl b/src/algorithms.jl index 238926aa4c..52985f65fb 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -931,80 +931,4 @@ end const MultistepAlgorithms = Union{ AB3, AB4, AB5, ABM32, ABM43, ABM54} -const SplitAlgorithms = Union{CNAB2, CNLF2} - -#= -struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, - linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = - DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( - linsolve,nlsolve,precs,extrapolant) -=# - -struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DImplicitEuler(; - chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - controller::Symbol -end -function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, controller = :Standard) where {MO} - DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, - controller) -end - -TruncatedStacktraces.@truncate_stacktrace DFBDF +const SplitAlgorithms = Union{CNAB2, CNLF2} \ No newline at end of file diff --git a/src/integrators/controllers.jl b/src/integrators/controllers.jl index 10af114a40..87b6d71fc1 100644 --- a/src/integrators/controllers.jl +++ b/src/integrators/controllers.jl @@ -422,135 +422,4 @@ end function step_reject_controller!(integrator, alg::JVODE) integrator.dt *= integrator.qold -end - -function step_reject_controller!(integrator, ::DFBDF) - bdf_step_reject_controller!(integrator, integrator.cache.terkm1) -end - -function post_newton_controller!(integrator, alg) - integrator.dt = integrator.dt / integrator.opts.failfactor - nothing -end - -function post_newton_controller!(integrator, alg::DFBDF) - @unpack cache = integrator - if cache.order > 1 && cache.nlsolver.nfails >= 3 - cache.order -= 1 - end - integrator.dt = integrator.dt / integrator.opts.failfactor - integrator.cache.consfailcnt += 1 - integrator.cache.nconsteps = 0 - nothing -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqMutableCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache - k = cache.order - # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] - end - @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqConstantCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache - k = cache.order - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - if u isa Number - for i in 2:(k - 2) - terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] - end - terk_tmp *= abs(dt^(k - 2)) - else - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * - u_history[:, i - 1] - end - terk_tmp = reshape(vc, size(terk_tmp)) - terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) - end - atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function stepsize_controller!(integrator, - alg::DFBDF{max_order}) where { - max_order, -} - @unpack cache = integrator - cache.prev_order = cache.order - k, terk = choose_order!(alg, integrator, cache, Val(max_order)) - if k != cache.order - integrator.cache.nconsteps = 0 - cache.order = k - end - if iszero(terk) - q = inv(integrator.opts.qmax) - else - q = ((2 * terk / (k + 1))^(1 / (k + 1))) - end - integrator.qold = q - q -end - -function step_accept_controller!(integrator, alg::DFBDF{max_order}, - q) where {max_order} - integrator.cache.consfailcnt = 0 - if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min - q = one(q) - end - integrator.cache.nconsteps += 1 - integrator.cache.iters_from_event += 1 - return integrator.dt / q -end +end \ No newline at end of file From eee031e33de0ecb7b65f892d813641835ea4b24d Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 02:17:41 +0530 Subject: [PATCH 13/45] @unpack --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 3 ++- .../OrdinaryDiffEqDAE/test}/dae_ad_tests.jl | 2 +- .../test}/dae_convergence_tests.jl | 2 +- .../OrdinaryDiffEqDAE/test}/dae_event.jl | 2 +- .../test}/dae_initialization_tests.jl | 2 +- .../test}/dae_initialize_integration.jl | 2 +- .../OrdinaryDiffEqDAE/test}/hard_dae.jl | 2 +- lib/OrdinaryDiffEqDAE/test/runtest.jl | 0 src/OrdinaryDiffEq.jl | 2 +- test/runtests.jl | 16 ++++++++-------- 10 files changed, 17 insertions(+), 16 deletions(-) rename {test/interface => lib/OrdinaryDiffEqDAE/test}/dae_ad_tests.jl (99%) rename {test/algconvergence => lib/OrdinaryDiffEqDAE/test}/dae_convergence_tests.jl (99%) rename {test/integrators => lib/OrdinaryDiffEqDAE/test}/dae_event.jl (95%) rename {test/integrators => lib/OrdinaryDiffEqDAE/test}/dae_initialization_tests.jl (99%) rename {test/interface => lib/OrdinaryDiffEqDAE/test}/dae_initialize_integration.jl (98%) rename {test/regression => lib/OrdinaryDiffEqDAE/test}/hard_dae.jl (99%) create mode 100644 lib/OrdinaryDiffEqDAE/test/runtest.jl diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 0be59f3cbf..ed77fee311 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -2,7 +2,8 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + @unpack using TruncatedStacktraces include("algorithms.jl") diff --git a/test/interface/dae_ad_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl similarity index 99% rename from test/interface/dae_ad_tests.jl rename to lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl index 1040152adb..398aa310be 100644 --- a/test/interface/dae_ad_tests.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl @@ -57,4 +57,4 @@ sol1 = solve(prob, DFBDF(), dt = 1e-5, abstol = 1e-8, reltol = 1e-8) sum(sol) end @test ForwardDiff.gradient(f, [0.04, 3e7, 1e4])≈[0, 0, 0] atol=1e-8 -end +end \ No newline at end of file diff --git a/test/algconvergence/dae_convergence_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl similarity index 99% rename from test/algconvergence/dae_convergence_tests.jl rename to lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl index 859f194d68..e3ef2dd474 100644 --- a/test/algconvergence/dae_convergence_tests.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl @@ -53,4 +53,4 @@ prob_dae_linear_oop = DAEProblem( @test sim24.𝒪est[:final]≈2 atol=testTol @test_nowarn solve(prob, DFBDF()) -end +end \ No newline at end of file diff --git a/test/integrators/dae_event.jl b/lib/OrdinaryDiffEqDAE/test/dae_event.jl similarity index 95% rename from test/integrators/dae_event.jl rename to lib/OrdinaryDiffEqDAE/test/dae_event.jl index 7c32b8d46e..c20b600670 100644 --- a/test/integrators/dae_event.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_event.jl @@ -27,4 +27,4 @@ sol = solve(prob, DFBDF(), callback = cb, tstops = [50.0], abstol = 1e-12, relto @test sol.t[end] == 100.0 @test sol[end][1]≈0.686300529575259 atol=1e-7 @test sol[end][2]≈2.0797982209353813e-6 atol=1e-7 -@test sol[end][3]≈1.31369739062652 atol=1e-7 +@test sol[end][3]≈1.31369739062652 atol=1e-7 \ No newline at end of file diff --git a/test/integrators/dae_initialization_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl similarity index 99% rename from test/integrators/dae_initialization_tests.jl rename to lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl index b3cdd2a858..5cf37c27f4 100644 --- a/test/integrators/dae_initialization_tests.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl @@ -265,4 +265,4 @@ f = ODEFunction(f2, mass_matrix = Diagonal([1.0, 1.0, 0.0])) prob = ODEProblem(f, ones(3), (0.0, 1.0)) integrator = init(prob, Rodas5P(), initializealg = ShampineCollocationInit(1.0, BrokenNLSolve())) -@test all(isequal(reinterpret(Float64, 0xDEADBEEFDEADBEEF)), integrator.u) +@test all(isequal(reinterpret(Float64, 0xDEADBEEFDEADBEEF)), integrator.u) \ No newline at end of file diff --git a/test/interface/dae_initialize_integration.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl similarity index 98% rename from test/interface/dae_initialize_integration.jl rename to lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl index 2d09cb1a41..33913925e2 100644 --- a/test/interface/dae_initialize_integration.jl +++ b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl @@ -75,4 +75,4 @@ sol = solve(prob, Rodas5P(), dt = 1e-10) @test SciMLBase.successful_retcode(sol) @test sol[1] == [1.0] @test sol[2] ≈ [0.9999999998] -@test sol[end] ≈ [-1.0] +@test sol[end] ≈ [-1.0] \ No newline at end of file diff --git a/test/regression/hard_dae.jl b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl similarity index 99% rename from test/regression/hard_dae.jl rename to lib/OrdinaryDiffEqDAE/test/hard_dae.jl index 302de87d2a..f47b226ce1 100644 --- a/test/regression/hard_dae.jl +++ b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl @@ -272,4 +272,4 @@ for prob in [prob1, prob2], alg in [simple_implicit_euler, alg_switch] @test sol(0, idxs = 1) == 5 @test sol(2, idxs = 1) == 0 @test sol(4, idxs = 1) > 10 -end +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 1f57f77891..e1f65da79b 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -465,7 +465,7 @@ export Alshina2, Alshina3, Alshina6 export AutoSwitch, AutoTsit5, AutoDP5, AutoVern6, AutoVern7, AutoVern8, AutoVern9 -export KuttaPRK2p5, PDIRK44, DImplicitEuler, DABDF2, DFBDF +export KuttaPRK2p5, PDIRK44 export ShampineCollocationInit, BrownFullBasicInit, NoInit diff --git a/test/runtests.jl b/test/runtests.jl index 3327354672..fd03660767 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -77,8 +77,8 @@ function activate_sdirk() Pkg.instantiate() end -function activate_firk() - Pkg.activate("../lib/OrdinaryDiffEqFIRK") +function activate_dae() + Pkg.activate("../lib/OrdinaryDiffEqDAE") Pkg.develop(PackageSpec(path = dirname(@__DIR__))) Pkg.instantiate() end @@ -147,9 +147,9 @@ end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceV" || GROUP == "Interface") @time @safetestset "Interpolation Derivative Error Tests" include("interface/interpolation_derivative_error_tests.jl") @time @safetestset "AD Tests" include("interface/ad_tests.jl") - @time @safetestset "DAE AD Tests" include("interface/dae_ad_tests.jl") + @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl") @time @safetestset "Newton Tests" include("interface/newton_tests.jl") - @time @safetestset "DAE Initialize Integration" include("interface/dae_initialize_integration.jl") + @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl") end if !is_APPVEYOR && @@ -173,8 +173,8 @@ end @time @safetestset "Reverse Directioned Event Tests" include("integrators/rev_events_tests.jl") @time @safetestset "Differentiation Direction Tests" include("integrators/diffdir_tests.jl") @time @safetestset "Resize Tests" include("integrators/resize_tests.jl") - @time @safetestset "DAE Initialization Tests" include("integrators/dae_initialization_tests.jl") - @time @safetestset "DAE Event Tests" include("integrators/dae_event.jl") + @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl") + @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_event.jl") @time @safetestset "Cache Tests" include("integrators/ode_cache_tests.jl") @time @safetestset "Add Steps Tests" include("integrators/ode_add_steps_tests.jl") @time @safetestset "IMEX Split Function Tests" include("integrators/split_ode_tests.jl") @@ -185,7 +185,7 @@ end @time @safetestset "Special Interp Tests" include("regression/special_interps.jl") @time @safetestset "Inplace Tests" include("regression/ode_inplace_tests.jl") @time @safetestset "Adaptive Tests" include("regression/ode_adaptive_tests.jl") - @time @safetestset "Hard DAE Tests" include("regression/hard_dae.jl") + @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqDAE/test/hard_dae.jl") end if !is_APPVEYOR && (GROUP == "All" || GROUP == "Regression_II" || GROUP == "Regression") @@ -199,7 +199,7 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_I" @time @safetestset "Partitioned Methods Tests" include("algconvergence/partitioned_methods_tests.jl") @time @safetestset "Convergence Tests" include("algconvergence/ode_convergence_tests.jl") - @time @safetestset "DAE Convergence Tests" include("algconvergence/dae_convergence_tests.jl") + @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl") @time @safetestset "Non-autonomous Convergence Tests" include("algconvergence/non-autonomous_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("algconvergence/adams_tests.jl") @time @safetestset "Nordsieck Tests" include("algconvergence/nordsieck_tests.jl") From 4cf4c4b879c9be1773b47fe35703a4568b2742c3 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:19:15 +0530 Subject: [PATCH 14/45] @.. --- lib/OrdinaryDiffEqDAE/Project.toml | 1 + lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml index ee3e8c74e7..b15e3bbe39 100644 --- a/lib/OrdinaryDiffEqDAE/Project.toml +++ b/lib/OrdinaryDiffEqDAE/Project.toml @@ -6,6 +6,7 @@ version = "1.0.0" [deps] OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" [extras] DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index ed77fee311..82a1d7d496 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -5,6 +5,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack using TruncatedStacktraces +import FastBroadCast: @.. include("algorithms.jl") include("alg_utils.jl") From 2a01c6ba3767b12cfe620c2498e383b5e74241de Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:41:13 +0530 Subject: [PATCH 15/45] @.. --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- lib/OrdinaryDiffEqDAE/test/runtest.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 82a1d7d496..9643b52c2d 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -5,7 +5,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack using TruncatedStacktraces -import FastBroadCast: @.. +import FastBroadcast: @.. include("algorithms.jl") include("alg_utils.jl") diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl index e69de29bb2..a639da4027 100644 --- a/lib/OrdinaryDiffEqDAE/test/runtest.jl +++ b/lib/OrdinaryDiffEqDAE/test/runtest.jl @@ -0,0 +1,2 @@ +using SafeTestsets + From 1c7c5812391c014ee2c8a5d4275fce547080283e Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:43:51 +0530 Subject: [PATCH 16/45] @cache --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 9643b52c2d..374e6b772b 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -3,7 +3,7 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack + @unpack, @cache using TruncatedStacktraces import FastBroadcast: @.. From 5d3d39a7e9e0013c58c04010b2979d915fc6c170 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:46:02 +0530 Subject: [PATCH 17/45] MuladdMacro --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 374e6b772b..0657ec30b9 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -4,7 +4,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack, @cache -using TruncatedStacktraces +using TruncatedStacktraces, MuladdMacro import FastBroadcast: @.. include("algorithms.jl") From 4ace562e93c4c8b2b7a4bf6f3c2e64e3a732ce00 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:56:06 +0530 Subject: [PATCH 18/45] controllers --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 0657ec30b9..9017917bb8 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -3,7 +3,9 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack, @cache + @unpack, @cache, default_controller, stepsize_controller!, + step_accept_controller!, + step_reject_controller!, post_newton_controller! using TruncatedStacktraces, MuladdMacro import FastBroadcast: @.. From 039c13f87a6586b93c44711b977182a0bba46631 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 11:13:21 +0530 Subject: [PATCH 19/45] post_newton_controller! --- src/OrdinaryDiffEq.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index e1f65da79b..2b150621d3 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -164,7 +164,6 @@ include("tableaus/qprk_tableaus.jl") include("integrators/type.jl") include("integrators/controllers.jl") -include("integrators/integrator_utils.jl") include("integrators/integrator_interface.jl") include("cache_utils.jl") @@ -293,6 +292,10 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") using ..OrdinaryDiffEqDAE export DImplicitEuler, DABDF2, DFBDF + + +using ..OrdinaryDiffEqDAE: post_newton_controller! +include("integrators/integrator_utils.jl") include("nlsolve/newton.jl") import PrecompileTools From bf696ad65427c9a26819357aadd87719eb54b305 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Fri, 26 Jul 2024 22:20:47 +0530 Subject: [PATCH 20/45] DAE added to BDF --- .../src/OrdinaryDiffEqBDF.jl | 7 +- lib/OrdinaryDiffEqBDF/src/alg_utils.jl | 13 ++ lib/OrdinaryDiffEqBDF/src/algorithms.jl | 76 ++++++++++ lib/OrdinaryDiffEqBDF/src/controllers.jl | 132 ++++++++++++++++++ .../src/dae_caches.jl | 0 .../src/dae_perform_step.jl | 0 .../test/dae_ad_tests.jl | 0 .../test/dae_convergence_tests.jl | 0 .../test/dae_event.jl | 0 .../test/dae_initialization_tests.jl | 0 .../test/dae_initialize_integration.jl | 0 .../test/hard_dae.jl | 0 .../test/runtest.jl | 0 lib/OrdinaryDiffEqDAE/Project.toml | 21 --- .../src/OrdinaryDiffEqDAE.jl | 20 --- lib/OrdinaryDiffEqDAE/src/alg_utils.jl | 12 -- lib/OrdinaryDiffEqDAE/src/algorithms.jl | 75 ---------- lib/OrdinaryDiffEqDAE/src/controllers.jl | 130 ----------------- src/OrdinaryDiffEq.jl | 10 +- test/runtests.jl | 12 +- 20 files changed, 235 insertions(+), 273 deletions(-) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/src/dae_caches.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/src/dae_perform_step.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_ad_tests.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_convergence_tests.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_event.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_initialization_tests.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/dae_initialize_integration.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/hard_dae.jl (100%) rename lib/{OrdinaryDiffEqDAE => OrdinaryDiffEqBDF}/test/runtest.jl (100%) delete mode 100644 lib/OrdinaryDiffEqDAE/Project.toml delete mode 100644 lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/controllers.jl diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 2080050161..740ced5261 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -22,7 +22,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, get_current_alg_order, get_current_adaptive_order, default_controller, stepsize_controller!, step_accept_controller!, step_reject_controller!, post_newton_controller!, - u_modified! + u_modified!, DAEAlgorithm, _unwrap_val using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA using LinearAlgebra: I @@ -32,10 +32,13 @@ include("algorithms.jl") include("alg_utils.jl") include("bdf_utils.jl") include("bdf_caches.jl") +include("dae_caches.jl") include("controllers.jl") +include("dae_perform_step.jl") include("bdf_perform_step.jl") export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, - SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK + SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK, + DABDF2, DImplicitEuler, DFBDF end diff --git a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl index aea50d0df0..8400ef7ea7 100644 --- a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl @@ -24,3 +24,16 @@ get_current_alg_order(alg::FBDF, cache) = cache.order get_current_adaptive_order(alg::QNDF, cache) = cache.order get_current_adaptive_order(alg::FBDF, cache) = cache.order + +isadaptive(alg::DImplicitEuler) = true +isadaptive(alg::DABDF2) = true +isadaptive(alg::DFBDF) = true + +alg_extrapolates(alg::DImplicitEuler) = true +alg_extrapolates(alg::DABDF2) = true + +alg_order(alg::DImplicitEuler) = 1 +alg_order(alg::DABDF2) = 2 +alg_order(alg::DFBDF) = 1#dummy value + +isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index 0a91dce0b6..0ed740a489 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -388,3 +388,79 @@ unew = uold + dt * (f1(unew) + f2(y1)) See also `SBDF`, `IMEXEuler`. """ IMEXEulerARK(; kwargs...) = SBDF(1; ark = true, kwargs...) + +struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DImplicitEuler(; + chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +#= +struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, + linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = + DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( + linsolve,nlsolve,precs,extrapolant) +=# + +struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + controller::Symbol +end +function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, controller = :Standard) where {MO} + DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, + controller) +end + +TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/controllers.jl b/lib/OrdinaryDiffEqBDF/src/controllers.jl index 4c1e8b9274..23b9aab655 100644 --- a/lib/OrdinaryDiffEqBDF/src/controllers.jl +++ b/lib/OrdinaryDiffEqBDF/src/controllers.jl @@ -262,3 +262,135 @@ function step_accept_controller!(integrator, alg::FBDF{max_order}, integrator.cache.iters_from_event += 1 return integrator.dt / q end + + +function step_reject_controller!(integrator, ::DFBDF) + bdf_step_reject_controller!(integrator, integrator.cache.terkm1) +end + +function post_newton_controller!(integrator, alg) + integrator.dt = integrator.dt / integrator.opts.failfactor + nothing +end + +function post_newton_controller!(integrator, alg::DFBDF) + @unpack cache = integrator + if cache.order > 1 && cache.nlsolver.nfails >= 3 + cache.order -= 1 + end + integrator.dt = integrator.dt / integrator.opts.failfactor + integrator.cache.consfailcnt += 1 + integrator.cache.nconsteps = 0 + nothing +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqMutableCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache + k = cache.order + # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] + end + @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqConstantCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache + k = cache.order + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + if u isa Number + for i in 2:(k - 2) + terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] + end + terk_tmp *= abs(dt^(k - 2)) + else + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * + u_history[:, i - 1] + end + terk_tmp = reshape(vc, size(terk_tmp)) + terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) + end + atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function stepsize_controller!(integrator, + alg::DFBDF{max_order}) where { + max_order, +} + @unpack cache = integrator + cache.prev_order = cache.order + k, terk = choose_order!(alg, integrator, cache, Val(max_order)) + if k != cache.order + integrator.cache.nconsteps = 0 + cache.order = k + end + if iszero(terk) + q = inv(integrator.opts.qmax) + else + q = ((2 * terk / (k + 1))^(1 / (k + 1))) + end + integrator.qold = q + q +end + +function step_accept_controller!(integrator, alg::DFBDF{max_order}, + q) where {max_order} + integrator.cache.consfailcnt = 0 + if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min + q = one(q) + end + integrator.cache.nconsteps += 1 + integrator.cache.iters_from_event += 1 + return integrator.dt / q +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_caches.jl b/lib/OrdinaryDiffEqBDF/src/dae_caches.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/src/dae_caches.jl rename to lib/OrdinaryDiffEqBDF/src/dae_caches.jl diff --git a/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl b/lib/OrdinaryDiffEqBDF/src/dae_perform_step.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl rename to lib/OrdinaryDiffEqBDF/src/dae_perform_step.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl b/lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl rename to lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl b/lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl rename to lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_event.jl b/lib/OrdinaryDiffEqBDF/test/dae_event.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_event.jl rename to lib/OrdinaryDiffEqBDF/test/dae_event.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl b/lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl rename to lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl b/lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl rename to lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl diff --git a/lib/OrdinaryDiffEqDAE/test/hard_dae.jl b/lib/OrdinaryDiffEqBDF/test/hard_dae.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/hard_dae.jl rename to lib/OrdinaryDiffEqBDF/test/hard_dae.jl diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqBDF/test/runtest.jl similarity index 100% rename from lib/OrdinaryDiffEqDAE/test/runtest.jl rename to lib/OrdinaryDiffEqBDF/test/runtest.jl diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml deleted file mode 100644 index b15e3bbe39..0000000000 --- a/lib/OrdinaryDiffEqDAE/Project.toml +++ /dev/null @@ -1,21 +0,0 @@ -name = "OrdinaryDiffEqDAE" -uuid = "7d2d7016-1c68-401d-834f-6be2c6dc7d88" -authors = ["ParamThakkar123 "] -version = "1.0.0" - -[deps] -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[compat] -julia = "1.10" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl deleted file mode 100644 index 9017917bb8..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ /dev/null @@ -1,20 +0,0 @@ -module OrdinaryDiffEqDAE - -import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, - DEFAULT_PRECS, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack, @cache, default_controller, stepsize_controller!, - step_accept_controller!, - step_reject_controller!, post_newton_controller! -using TruncatedStacktraces, MuladdMacro -import FastBroadcast: @.. - -include("algorithms.jl") -include("alg_utils.jl") -include("controllers.jl") -include("dae_caches.jl") -include("dae_perform_step.jl") - -export DABDF2, DImplicitEuler, DFBDF - -end # module OrdinaryDiffEqDAE diff --git a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl deleted file mode 100644 index ff0d60daac..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl +++ /dev/null @@ -1,12 +0,0 @@ -isadaptive(alg::DImplicitEuler) = true -isadaptive(alg::DABDF2) = true -isadaptive(alg::DFBDF) = true - -alg_extrapolates(alg::DImplicitEuler) = true -alg_extrapolates(alg::DABDF2) = true - -alg_order(alg::DImplicitEuler) = 1 -alg_order(alg::DABDF2) = 2 -alg_order(alg::DFBDF) = 1#dummy value - -isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/algorithms.jl b/lib/OrdinaryDiffEqDAE/src/algorithms.jl deleted file mode 100644 index f8584348a5..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/algorithms.jl +++ /dev/null @@ -1,75 +0,0 @@ -struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DImplicitEuler(; - chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -#= -struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, - linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = - DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( - linsolve,nlsolve,precs,extrapolant) -=# - -struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - controller::Symbol -end -function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, controller = :Standard) where {MO} - DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, - controller) -end - -TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/controllers.jl b/lib/OrdinaryDiffEqDAE/src/controllers.jl deleted file mode 100644 index 4ae1a93a28..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/controllers.jl +++ /dev/null @@ -1,130 +0,0 @@ -function step_reject_controller!(integrator, ::DFBDF) - bdf_step_reject_controller!(integrator, integrator.cache.terkm1) -end - -function post_newton_controller!(integrator, alg) - integrator.dt = integrator.dt / integrator.opts.failfactor - nothing -end - -function post_newton_controller!(integrator, alg::DFBDF) - @unpack cache = integrator - if cache.order > 1 && cache.nlsolver.nfails >= 3 - cache.order -= 1 - end - integrator.dt = integrator.dt / integrator.opts.failfactor - integrator.cache.consfailcnt += 1 - integrator.cache.nconsteps = 0 - nothing -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqMutableCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache - k = cache.order - # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] - end - @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqConstantCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache - k = cache.order - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - if u isa Number - for i in 2:(k - 2) - terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] - end - terk_tmp *= abs(dt^(k - 2)) - else - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * - u_history[:, i - 1] - end - terk_tmp = reshape(vc, size(terk_tmp)) - terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) - end - atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function stepsize_controller!(integrator, - alg::DFBDF{max_order}) where { - max_order, -} - @unpack cache = integrator - cache.prev_order = cache.order - k, terk = choose_order!(alg, integrator, cache, Val(max_order)) - if k != cache.order - integrator.cache.nconsteps = 0 - cache.order = k - end - if iszero(terk) - q = inv(integrator.opts.qmax) - else - q = ((2 * terk / (k + 1))^(1 / (k + 1))) - end - integrator.qold = q - q -end - -function step_accept_controller!(integrator, alg::DFBDF{max_order}, - q) where {max_order} - integrator.cache.consfailcnt = 0 - if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min - q = one(q) - end - integrator.cache.nconsteps += 1 - integrator.cache.iters_from_event += 1 - return integrator.dt / q -end \ No newline at end of file diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 2b150621d3..e6fb096fbc 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -273,7 +273,8 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") using ..OrdinaryDiffEqBDF export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, - SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK + SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK, + DImplicitEuler, DABDF2, DFBDF include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault @@ -289,12 +290,7 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp, bdf_step_reject_controller! -include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") -using ..OrdinaryDiffEqDAE -export DImplicitEuler, DABDF2, DFBDF - - -using ..OrdinaryDiffEqDAE: post_newton_controller! +using ..OrdinaryDiffEqBDF: post_newton_controller! include("integrators/integrator_utils.jl") include("nlsolve/newton.jl") diff --git a/test/runtests.jl b/test/runtests.jl index fd03660767..1edccc79e5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -147,9 +147,9 @@ end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceV" || GROUP == "Interface") @time @safetestset "Interpolation Derivative Error Tests" include("interface/interpolation_derivative_error_tests.jl") @time @safetestset "AD Tests" include("interface/ad_tests.jl") - @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl") + @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl") @time @safetestset "Newton Tests" include("interface/newton_tests.jl") - @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl") + @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl") end if !is_APPVEYOR && @@ -173,8 +173,8 @@ end @time @safetestset "Reverse Directioned Event Tests" include("integrators/rev_events_tests.jl") @time @safetestset "Differentiation Direction Tests" include("integrators/diffdir_tests.jl") @time @safetestset "Resize Tests" include("integrators/resize_tests.jl") - @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl") - @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_event.jl") + @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl") + @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_event.jl") @time @safetestset "Cache Tests" include("integrators/ode_cache_tests.jl") @time @safetestset "Add Steps Tests" include("integrators/ode_add_steps_tests.jl") @time @safetestset "IMEX Split Function Tests" include("integrators/split_ode_tests.jl") @@ -185,7 +185,7 @@ end @time @safetestset "Special Interp Tests" include("regression/special_interps.jl") @time @safetestset "Inplace Tests" include("regression/ode_inplace_tests.jl") @time @safetestset "Adaptive Tests" include("regression/ode_adaptive_tests.jl") - @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqDAE/test/hard_dae.jl") + @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqBDF/test/hard_dae.jl") end if !is_APPVEYOR && (GROUP == "All" || GROUP == "Regression_II" || GROUP == "Regression") @@ -199,7 +199,7 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_I" @time @safetestset "Partitioned Methods Tests" include("algconvergence/partitioned_methods_tests.jl") @time @safetestset "Convergence Tests" include("algconvergence/ode_convergence_tests.jl") - @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl") + @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl") @time @safetestset "Non-autonomous Convergence Tests" include("algconvergence/non-autonomous_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("algconvergence/adams_tests.jl") @time @safetestset "Nordsieck Tests" include("algconvergence/nordsieck_tests.jl") From bcb3f4d2501b49879e4afb05c10e3d0035938297 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Fri, 26 Jul 2024 22:31:11 +0530 Subject: [PATCH 21/45] added tests --- lib/OrdinaryDiffEqBDF/test/runtest.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/OrdinaryDiffEqBDF/test/runtest.jl b/lib/OrdinaryDiffEqBDF/test/runtest.jl index a639da4027..aeacfd70d2 100644 --- a/lib/OrdinaryDiffEqBDF/test/runtest.jl +++ b/lib/OrdinaryDiffEqBDF/test/runtest.jl @@ -1,2 +1,8 @@ using SafeTestsets +@time @safetestset "DAE AD Tests" include("dae_ad_tests.jl") +@time @safetestset "DAE Initialize Integration" include("dae_initialize_integration.jl") +@time @safetestset "DAE Initialization Tests" include("dae_initialization_tests.jl") +@time @safetestset "DAE Event Tests" include("dae_event.jl") +@time @safetestset "Hard DAE Tests" include("hard_dae.jl") +@time @safetestset "DAE Convergence Tests" include("dae_convergence_tests.jl") \ No newline at end of file From a3e474eea0bb263c37828bc8e77c60a3ec8e9580 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 02:03:40 +0530 Subject: [PATCH 22/45] Added DAE solvers --- lib/OrdinaryDiffEqDAE/Project.toml | 20 + .../src/OrdinaryDiffEqDAE.jl | 16 + lib/OrdinaryDiffEqDAE/src/alg_utils.jl | 12 + lib/OrdinaryDiffEqDAE/src/algorithms.jl | 75 +++ lib/OrdinaryDiffEqDAE/src/controllers.jl | 130 +++++ lib/OrdinaryDiffEqDAE/src/dae_caches.jl | 256 ++++++++++ lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl | 460 ++++++++++++++++++ src/OrdinaryDiffEq.jl | 6 + 8 files changed, 975 insertions(+) create mode 100644 lib/OrdinaryDiffEqDAE/Project.toml create mode 100644 lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/algorithms.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/controllers.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/dae_caches.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml new file mode 100644 index 0000000000..ee3e8c74e7 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/Project.toml @@ -0,0 +1,20 @@ +name = "OrdinaryDiffEqDAE" +uuid = "7d2d7016-1c68-401d-834f-6be2c6dc7d88" +authors = ["ParamThakkar123 "] +version = "1.0.0" + +[deps] +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[compat] +julia = "1.10" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl new file mode 100644 index 0000000000..0be59f3cbf --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -0,0 +1,16 @@ +module OrdinaryDiffEqDAE + +import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, + DEFAULT_PRECS, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache +using TruncatedStacktraces + +include("algorithms.jl") +include("alg_utils.jl") +include("controllers.jl") +include("dae_caches.jl") +include("dae_perform_step.jl") + +export DABDF2, DImplicitEuler, DFBDF + +end # module OrdinaryDiffEqDAE diff --git a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl new file mode 100644 index 0000000000..ff0d60daac --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl @@ -0,0 +1,12 @@ +isadaptive(alg::DImplicitEuler) = true +isadaptive(alg::DABDF2) = true +isadaptive(alg::DFBDF) = true + +alg_extrapolates(alg::DImplicitEuler) = true +alg_extrapolates(alg::DABDF2) = true + +alg_order(alg::DImplicitEuler) = 1 +alg_order(alg::DABDF2) = 2 +alg_order(alg::DFBDF) = 1#dummy value + +isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/algorithms.jl b/lib/OrdinaryDiffEqDAE/src/algorithms.jl new file mode 100644 index 0000000000..f8584348a5 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/algorithms.jl @@ -0,0 +1,75 @@ +struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DImplicitEuler(; + chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +#= +struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, + linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = + DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( + linsolve,nlsolve,precs,extrapolant) +=# + +struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + controller::Symbol +end +function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, controller = :Standard) where {MO} + DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, + controller) +end + +TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/controllers.jl b/lib/OrdinaryDiffEqDAE/src/controllers.jl new file mode 100644 index 0000000000..4ae1a93a28 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/controllers.jl @@ -0,0 +1,130 @@ +function step_reject_controller!(integrator, ::DFBDF) + bdf_step_reject_controller!(integrator, integrator.cache.terkm1) +end + +function post_newton_controller!(integrator, alg) + integrator.dt = integrator.dt / integrator.opts.failfactor + nothing +end + +function post_newton_controller!(integrator, alg::DFBDF) + @unpack cache = integrator + if cache.order > 1 && cache.nlsolver.nfails >= 3 + cache.order -= 1 + end + integrator.dt = integrator.dt / integrator.opts.failfactor + integrator.cache.consfailcnt += 1 + integrator.cache.nconsteps = 0 + nothing +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqMutableCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache + k = cache.order + # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] + end + @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqConstantCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache + k = cache.order + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + if u isa Number + for i in 2:(k - 2) + terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] + end + terk_tmp *= abs(dt^(k - 2)) + else + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * + u_history[:, i - 1] + end + terk_tmp = reshape(vc, size(terk_tmp)) + terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) + end + atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function stepsize_controller!(integrator, + alg::DFBDF{max_order}) where { + max_order, +} + @unpack cache = integrator + cache.prev_order = cache.order + k, terk = choose_order!(alg, integrator, cache, Val(max_order)) + if k != cache.order + integrator.cache.nconsteps = 0 + cache.order = k + end + if iszero(terk) + q = inv(integrator.opts.qmax) + else + q = ((2 * terk / (k + 1))^(1 / (k + 1))) + end + integrator.qold = q + q +end + +function step_accept_controller!(integrator, alg::DFBDF{max_order}, + q) where {max_order} + integrator.cache.consfailcnt = 0 + if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min + q = one(q) + end + integrator.cache.nconsteps += 1 + integrator.cache.iters_from_event += 1 + return integrator.dt / q +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_caches.jl b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl new file mode 100644 index 0000000000..c432408952 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl @@ -0,0 +1,256 @@ +@cache mutable struct DImplicitEulerCache{uType, rateType, uNoUnitsType, N} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + uprev2::uType + atmp::uNoUnitsType + k₁::rateType + k₂::rateType + nlsolver::N +end + +mutable struct DImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache + nlsolver::N +end + +function alg_cache(alg::DImplicitEuler, du, u, res_prototype, rate_prototype, + ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + α = 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(false)) + + DImplicitEulerConstantCache(nlsolver) +end + +function alg_cache(alg::DImplicitEuler, du, u, res_prototype, rate_prototype, + ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + α = 1 + k₁ = zero(rate_prototype) + k₂ = zero(rate_prototype) + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(true)) + + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + DImplicitEulerCache(u, uprev, uprev2, atmp, k₁, k₂, nlsolver) +end + +@cache mutable struct DABDF2ConstantCache{N, dtType, rate_prototype} <: + OrdinaryDiffEqConstantCache + nlsolver::N + eulercache::DImplicitEulerConstantCache + dtₙ₋₁::dtType + fsalfirstprev::rate_prototype +end + +function alg_cache(alg::DABDF2, du, u, res_prototype, rate_prototype, + ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 1, 1 + α = 1 // 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(false)) + eulercache = DImplicitEulerConstantCache(nlsolver) + + dtₙ₋₁ = one(dt) + fsalfirstprev = rate_prototype + + DABDF2ConstantCache(nlsolver, eulercache, dtₙ₋₁, fsalfirstprev) +end + +@cache mutable struct DABDF2Cache{uType, rateType, uNoUnitsType, N, dtType} <: + OrdinaryDiffEqMutableCache + uₙ::uType + uₙ₋₁::uType + uₙ₋₂::uType + fsalfirst::rateType + fsalfirstprev::rateType + atmp::uNoUnitsType + nlsolver::N + eulercache::DImplicitEulerCache + dtₙ₋₁::dtType +end + +function alg_cache(alg::DABDF2, du, u, res_prototype, rate_prototype, + ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 1, 1 + α = 1 // 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(true)) + fsalfirst = zero(rate_prototype) + + fsalfirstprev = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + k₁ = zero(rate_prototype) + k₂ = zero(rate_prototype) + + eulercache = DImplicitEulerCache(u, uprev, uprev2, atmp, k₁, k₂, nlsolver) + + dtₙ₋₁ = one(dt) + + DABDF2Cache(u, uprev, uprev2, fsalfirst, fsalfirstprev, atmp, + nlsolver, eulercache, dtₙ₋₁) +end + +@cache mutable struct DFBDFConstantCache{MO, N, tsType, tType, uType, uuType, coeffType, + EEstType, rType, wType} <: + OrdinaryDiffEqConstantCache + nlsolver::N + ts::tsType + ts_tmp::tsType + t_old::tType + u_history::uuType + order::Int + prev_order::Int + u₀::uType + u_corrector::uuType + bdf_coeffs::coeffType + max_order::Val{MO} + nconsteps::Int + consfailcnt::Int + terkm2::EEstType + terkm1::EEstType + terk::EEstType + terkp1::EEstType + r::rType + weights::wType + iters_from_event::Int +end + +function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, + uprev, uprev2, f, t, dt, reltol, p, calck, ::Val{false}) where {MO} + γ, c = 1.0, 1.0 + max_order = MO + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + bdf_coeffs = SA[1 -1 0 0 0 0; + 2//3 -4//3 1//3 0 0 0; + 6//11 -18//11 9//11 -2//11 0 0; + 12//25 -48//25 36//25 -16//25 3//25 0; + 60//137 -300//137 300//137 -200//137 75//137 -12//137] + ts = zero(Vector{typeof(t)}(undef, max_order + 2)) #ts is the successful past points, it will be updated after successful step + ts_tmp = similar(ts) + + u_history = zero(Matrix{eltype(u)}(undef, length(u), max_order + 2)) + order = 1 + prev_order = 1 + u_corrector = similar(u_history) + recursivefill!(u_corrector, zero(eltype(u))) + recursivefill!(u_history, zero(eltype(u_history))) + terkm2 = tTypeNoUnits(1) + terkm1 = tTypeNoUnits(1) + terk = tTypeNoUnits(1) + terkp1 = tTypeNoUnits(1) + r = zero(Vector{typeof(t)}(undef, max_order + 2)) + weights = zero(Vector{typeof(t)}(undef, max_order + 2)) + weights[1] = 1 + nconsteps = 0 + consfailcnt = 0 + t_old = zero(t) + iters_from_event = 0 + u₀ = zero(u) + + DFBDFConstantCache(nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, u₀, + u_corrector, bdf_coeffs, Val(5), nconsteps, consfailcnt, terkm2, + terkm1, terk, terkp1, r, weights, iters_from_event) +end + +@cache mutable struct DFBDFCache{MO, N, rateType, uNoUnitsType, tsType, tType, uType, + uuType, coeffType, EEstType, rType, wType} <: + OrdinaryDiffEqMutableCache + fsalfirst::rateType + nlsolver::N + ts::tsType + ts_tmp::tsType + t_old::tType + u_history::uuType + order::Int + prev_order::Int + u_corrector::uuType + u₀::uType + bdf_coeffs::coeffType + max_order::Val{MO} + nconsteps::Int + consfailcnt::Int + tmp::uType + atmp::uNoUnitsType + terkm2::EEstType + terkm1::EEstType + terk::EEstType + terkp1::EEstType + terk_tmp::uType + terkp1_tmp::uType + r::rType + weights::wType + equi_ts::tsType + iters_from_event::Int +end + +function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, + tTypeNoUnits, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {MO} + γ, c = 1.0, 1.0 + fsalfirst = zero(rate_prototype) + max_order = MO + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + #=bdf_coeffs = SA[1 -1 0 0 0 0 ; + 3//2 -2 1//2 0 0 0 ; + 11//6 -3 3//2 -1//3 0 0 ; + 25//12 -4 3 -4//3 1//4 0 ; + 137//60 -5 5 -10//3 5//4 -1//5]=# + bdf_coeffs = SA[1 -1 0 0 0 0; + 2//3 -4//3 1//3 0 0 0; + 6//11 -18//11 9//11 -2//11 0 0; + 12//25 -48//25 36//25 -16//25 3//25 0; + 60//137 -300//137 300//137 -200//137 75//137 -12//137] + ts = Vector{typeof(t)}(undef, max_order + 2) #ts is the successful past points, it will be updated after successful step + u_history = Matrix{eltype(u)}(undef, length(u), max_order + 2) + order = 1 + prev_order = 1 + u_corrector = similar(u_history) + recursivefill!(ts, zero(t)) + recursivefill!(u_corrector, zero(eltype(u))) + recursivefill!(u_history, zero(eltype(u_history))) + terkm2 = tTypeNoUnits(1) + terkm1 = tTypeNoUnits(1) + terk = tTypeNoUnits(1) + terkp1 = tTypeNoUnits(1) + terk_tmp = similar(u) + terkp1_tmp = similar(u) + r = Vector{typeof(t)}(undef, max_order + 2) + weights = Vector{typeof(t)}(undef, max_order + 2) + recursivefill!(r, zero(t)) + recursivefill!(weights, zero(t)) + weights[1] = 1 + nconsteps = 0 + consfailcnt = 0 + t_old = zero(t) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, zero(uEltypeNoUnits)) + u₀ = similar(u) + equi_ts = similar(ts) + tmp = similar(u) + ts_tmp = similar(ts) + iters_from_event = 0 + + DFBDFCache(fsalfirst, nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, + u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, + terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, + iters_from_event) +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl new file mode 100644 index 0000000000..4b4eab7e71 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl @@ -0,0 +1,460 @@ +function initialize!(integrator, cache::DImplicitEulerConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.k[1] = integrator.du +end + +function initialize!(integrator, cache::DImplicitEulerCache) + integrator.kshortsize = 2 + @unpack k₁, k₂ = cache + resize!(integrator.k, integrator.kshortsize) + integrator.k .= [k₁, k₂] + integrator.k[1] .= integrator.du + nothing +end + +@muladd function perform_step!(integrator, cache::DImplicitEulerConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack nlsolver = cache + + nlsolver.z = zero(u) + nlsolver.tmp = zero(u) + nlsolver.γ = 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = uprev + z + + if integrator.opts.adaptive && integrator.success_iter > 0 + # local truncation error (LTE) bound by dt^2/2*max|y''(t)| + # use 2nd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s + + tmp = r * + integrator.opts.internalnorm.((u - uprev) / dt1 - (uprev - uprev2) / dt2, t) + atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + else + integrator.EEst = 1 + end + + integrator.u = u + integrator.du = (u - uprev) / dt + + if integrator.opts.calck + integrator.k[2] = integrator.k[1] + integrator.k[1] = integrator.du + end +end + +@muladd function perform_step!(integrator, cache::DImplicitEulerCache, repeat_step = false) + @unpack t, dt, uprev, du, u, f, p = integrator + @unpack atmp, nlsolver = cache + @unpack tmp = nlsolver + + @. nlsolver.z = false + @. nlsolver.tmp = false + nlsolver.γ = 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=uprev + z + @.. broadcast=false du=z * inv(dt) + + if integrator.opts.adaptive && integrator.success_iter > 0 + # local truncation error (LTE) bound by dt^2/2*max|y''(t)| + # use 2nd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s + + @.. broadcast=false tmp=r * integrator.opts.internalnorm( + (u - uprev) / dt1 - + (uprev - uprev2) / dt2, t) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + else + integrator.EEst = 1 + end + + if integrator.opts.calck + integrator.k[2] .= integrator.k[1] + integrator.k[1] .= du + end +end + +function initialize!(integrator, cache::DABDF2ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.k[1] = integrator.du +end + +@muladd function perform_step!(integrator, cache::DABDF2ConstantCache, repeat_step = false) + @unpack t, f, p = integrator + @unpack dtₙ₋₁, nlsolver = cache + dtₙ, uₙ, uₙ₋₁, uₙ₋₂ = integrator.dt, integrator.u, integrator.uprev, integrator.uprev2 + + if integrator.iter == 1 && !integrator.u_modified + cache.dtₙ₋₁ = dtₙ + perform_step!(integrator, cache.eulercache, repeat_step) + integrator.fsalfirst = @.. broadcast=false (integrator.u - integrator.uprev)/dtₙ + cache.fsalfirstprev = integrator.fsalfirst + return + end + + # precalculations + ρ = dtₙ / dtₙ₋₁ + c1 = ρ^2 / (1 + 2ρ) + + nlsolver.γ = (1 + ρ) / (1 + 2ρ) + nlsolver.α = 1 // 1 + + nlsolver.z = zero(uₙ) + + nlsolver.tmp = -c1 * uₙ₋₁ + c1 * uₙ₋₂ + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + uₙ = uₙ₋₁ + z + integrator.fsallast = @.. broadcast=false z/dtₙ + + if integrator.opts.adaptive + tmp = integrator.fsallast - (1 + dtₙ / dtₙ₋₁) * integrator.fsalfirst + + (dtₙ / dtₙ₋₁) * cache.fsalfirstprev + est = (dtₙ₋₁ + dtₙ) / 6 * tmp + atmp = calculate_residuals(est, uₙ₋₁, uₙ, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + ################################### Finalize + + if integrator.EEst < one(integrator.EEst) + cache.fsalfirstprev = integrator.fsalfirst + cache.dtₙ₋₁ = dtₙ + end + + integrator.u = uₙ + integrator.du = du = (nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dtₙ) + + if integrator.opts.calck + integrator.k[2] = integrator.k[1] + integrator.k[1] = integrator.du + end + return +end + +function initialize!(integrator, cache::DABDF2Cache) + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + + integrator.kshortsize = 2 + @unpack k₁, k₂ = cache.eulercache + resize!(integrator.k, integrator.kshortsize) + integrator.k .= [k₁, k₂] + integrator.k[1] .= integrator.du + nothing +end + +@muladd function perform_step!(integrator, cache::DABDF2Cache, repeat_step = false) + @unpack t, dt, du, f, p = integrator + @unpack atmp, dtₙ₋₁, nlsolver = cache + @unpack z, tmp = nlsolver + uₙ, uₙ₋₁, uₙ₋₂, dtₙ = integrator.u, integrator.uprev, integrator.uprev2, integrator.dt + + if integrator.iter == 1 && !integrator.u_modified + cache.dtₙ₋₁ = dtₙ + perform_step!(integrator, cache.eulercache, repeat_step) + @.. broadcast=false integrator.fsalfirst=(uₙ - uₙ₋₁) / dt + cache.fsalfirstprev .= integrator.fsalfirst + return + end + + # precalculations + ρ = dtₙ / dtₙ₋₁ + c1 = ρ^2 / (1 + 2ρ) + + nlsolver.γ = (1 + ρ) / (1 + 2ρ) + nlsolver.α = 1 // 1 + @.. broadcast=false nlsolver.tmp=-c1 * uₙ₋₁ + c1 * uₙ₋₂ + nlsolver.z .= zero(eltype(z)) + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false uₙ=uₙ₋₁ + z + @.. broadcast=false du=(nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dt) + + @.. broadcast=false integrator.fsallast=du + integrator.stats.nf += 1 + if integrator.opts.adaptive + btilde0 = (dtₙ₋₁ + dtₙ) * 1 // 6 + btilde1 = 1 + ρ + btilde2 = ρ + @.. broadcast=false tmp=btilde0 * + (integrator.fsallast - btilde1 * integrator.fsalfirst + + btilde2 * cache.fsalfirstprev) + calculate_residuals!(atmp, tmp, uₙ₋₁, uₙ, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + ################################### Finalize + + if integrator.EEst < one(integrator.EEst) + @.. broadcast=false cache.fsalfirstprev=integrator.fsalfirst + cache.dtₙ₋₁ = dtₙ + end + return +end + +function initialize!(integrator, cache::DFBDFConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.du, integrator.uprev, integrator.p, + integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::DFBDFConstantCache{max_order}, + repeat_step = false) where {max_order} + @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, ts_tmp, iters_from_event, nconsteps = cache + @unpack t, dt, u, f, p, uprev = integrator + + k = order + reinitFBDF!(integrator, cache) + cache.u₀ = zero(u) + if iters_from_event >= 1 + cache.u₀ = calc_Lagrange_interp(k, weights, t + dt, ts, u_history, cache.u₀) + else + cache.u₀ = u + end + markfirststage!(nlsolver) + equi_ts = zeros(k - 1) + for i in 1:(k - 1) + equi_ts[i] = t - dt * i + end + + fill!(u_corrector, zero(eltype(u))) + if u isa Number + for i in 1:(k - 1) + u_corrector[i] = calc_Lagrange_interp(k, weights, equi_ts[i], ts, u_history, + u_corrector[i]) + end + tmp = uprev * bdf_coeffs[k, 2] + for i in 1:(k - 1) + tmp += u_corrector[i] * bdf_coeffs[k, i + 2] + end + else + for i in 1:(k - 1) + @.. broadcast=false @views u_corrector[:, i] = $calc_Lagrange_interp( + k, weights, + equi_ts[i], + ts, + u_history, + u_corrector[:, + i]) + end + tmp = uprev * bdf_coeffs[k, 2] + vc = _vec(tmp) + for i in 1:(k - 1) + vc += @.. broadcast=false u_corrector[:, i]*bdf_coeffs[k, i + 2] + end + tmp = reshape(vc, size(tmp)) + end + + nlsolver.tmp = tmp + cache.u₀ + nlsolver.z = zero(nlsolver.z) + nlsolver.γ = bdf_coeffs[k, 1] + nlsolver.α = 1 // 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = z + cache.u₀ + + for j in 2:k + r[j] = (1 - j) + for i in 2:(k + 1) + r[j] *= ((t + dt - j * dt) - ts[i]) / (i * dt) + end + end + + terkp1 = z + for j in 1:(k + 1) + terkp1 *= j * dt / (t + dt - ts[j]) + end + + lte = -1 / (1 + k) + for j in 2:k + lte -= (bdf_coeffs[k, j] // bdf_coeffs[k, 1]) * r[j] + end + lte *= terkp1 + + if integrator.opts.adaptive + for i in 1:(k + 1) + ts_tmp[i + 1] = ts[i] + end + ts_tmp[1] = t + dt + atmp = calculate_residuals(_vec(lte), _vec(uprev), _vec(u), integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + + terk = estimate_terk(integrator, cache, k + 1, Val(max_order), u) + atmp = calculate_residuals( + _vec(terk), _vec(uprev), _vec(u), integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + cache.terk = integrator.opts.internalnorm(atmp, t) + + if k > 1 + terkm1 = estimate_terk(integrator, cache, k, Val(max_order), u) + atmp = calculate_residuals(_vec(terkm1), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm1 = integrator.opts.internalnorm(atmp, t) + end + if k > 2 + terkm2 = estimate_terk(integrator, cache, k - 1, Val(max_order), u) + atmp = calculate_residuals(_vec(terkm2), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm2 = integrator.opts.internalnorm(atmp, t) + end + if nconsteps > k + 1 && k < max_order + atmp = calculate_residuals(_vec(terkp1), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkp1 = integrator.opts.internalnorm(atmp, t) + else + cache.terkp1 = zero(cache.terk) + end + end + integrator.u = u + integrator.fsallast = integrator.du = (nlsolver.α * z + nlsolver.tmp) * + inv(nlsolver.γ * dt) +end + +function initialize!(integrator, cache::DFBDFCache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + #integrator.f(integrator.fsalfirst, integrator.du, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + #integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::DFBDFCache{max_order}, + repeat_step = false) where {max_order} + @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, terk_tmp, terkp1_tmp, atmp, tmp, equi_ts, u₀, ts_tmp = cache + @unpack t, dt, u, f, p, uprev = integrator + + reinitFBDF!(integrator, cache) + k = order + @.. broadcast=false u₀=zero(u) + if cache.iters_from_event >= 1 + calc_Lagrange_interp!(k, weights, t + dt, ts, u_history, u₀) + else + @.. broadcast=false u₀=u + end + markfirststage!(nlsolver) + + for i in 1:(k - 1) + equi_ts[i] = t - dt * i + end + + fill!(u_corrector, zero(eltype(u))) + for i in 1:(k - 1) + @views calc_Lagrange_interp!(k, weights, equi_ts[i], ts, u_history, + u_corrector[:, i]) + end + + @.. broadcast=false tmp=uprev * bdf_coeffs[k, 2] + vc = _vec(tmp) + for i in 1:(k - 1) + @.. broadcast=false @views vc += u_corrector[:, i] * bdf_coeffs[k, i + 2] + end + + @.. broadcast=false nlsolver.tmp=tmp + u₀ + @.. broadcast=false nlsolver.z=zero(eltype(nlsolver.z)) + nlsolver.γ = bdf_coeffs[k, 1] + nlsolver.α = 1 // 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=z + u₀ + + for j in 2:k + r[j] = (1 - j) + for i in 2:(k + 1) + r[j] *= ((t + dt - j * dt) - ts[i]) / (i * dt) + end + end + + @.. broadcast=false terkp1_tmp=z + for j in 1:(k + 1) + @.. broadcast=false terkp1_tmp*=j * dt / (t + dt - ts[j]) + end + + lte = -1 / (1 + k) + for j in 2:k + lte -= (bdf_coeffs[k, j] // bdf_coeffs[k, 1]) * r[j] + end + @.. broadcast=false terk_tmp=lte * terkp1_tmp + if integrator.opts.adaptive + @unpack abstol, reltol, internalnorm = integrator.opts + for i in 1:(k + 1) + ts_tmp[i + 1] = ts[i] + end + ts_tmp[1] = t + dt + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, + internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + estimate_terk!(integrator, cache, k + 1, Val(max_order)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, + internalnorm, t) + cache.terk = integrator.opts.internalnorm(atmp, t) + + if k > 1 + estimate_terk!(integrator, cache, k, Val(max_order)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm1 = integrator.opts.internalnorm(atmp, t) + end + if k > 2 + estimate_terk!(integrator, cache, k - 1, Val(max_order)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm2 = integrator.opts.internalnorm(atmp, t) + end + if cache.nconsteps > k + 1 && k < max_order + calculate_residuals!(atmp, _vec(terkp1_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkp1 = integrator.opts.internalnorm(atmp, t) + else + cache.terkp1 = zero(cache.terkp1) + end + end + @.. broadcast=false integrator.fsallast=integrator.du = (nlsolver.α * z + + nlsolver.tmp) * + inv(nlsolver.γ * dt) #TODO Lorenz plot seems not smooth +end \ No newline at end of file diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index e6fb096fbc..c594bc4cd1 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -290,8 +290,14 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp, bdf_step_reject_controller! +<<<<<<< HEAD using ..OrdinaryDiffEqBDF: post_newton_controller! include("integrators/integrator_utils.jl") +======= +include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") +using ..OrdinaryDiffEqDAE +export DImplicitEuler, DABDF2, DFBDF +>>>>>>> b150b887 (Added DAE solvers) include("nlsolve/newton.jl") import PrecompileTools From da587cb5a7f1331f05fd1404447d68ff48c3189a Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 02:17:41 +0530 Subject: [PATCH 23/45] @unpack --- .../src/OrdinaryDiffEqDAE.jl | 3 +- lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl | 60 ++++ .../test/dae_convergence_tests.jl | 56 ++++ lib/OrdinaryDiffEqDAE/test/dae_event.jl | 30 ++ .../test/dae_initialization_tests.jl | 268 +++++++++++++++++ .../test/dae_initialize_integration.jl | 78 +++++ lib/OrdinaryDiffEqDAE/test/hard_dae.jl | 275 ++++++++++++++++++ lib/OrdinaryDiffEqDAE/test/runtest.jl | 0 test/runtests.jl | 12 +- 9 files changed, 775 insertions(+), 7 deletions(-) create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_event.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/hard_dae.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/runtest.jl diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 0be59f3cbf..ed77fee311 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -2,7 +2,8 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + @unpack using TruncatedStacktraces include("algorithms.jl") diff --git a/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl new file mode 100644 index 0000000000..398aa310be --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl @@ -0,0 +1,60 @@ +using OrdinaryDiffEq, LinearAlgebra, ForwardDiff, Test + +function rober(du, u, p, t) + y₁, y₂, y₃ = u + k₁, k₂, k₃ = p + du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ + du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du[3] = y₁ + y₂ + y₃ - 1 + nothing +end +function rober(u, p, t) + y₁, y₂, y₃ = u + k₁, k₂, k₃ = p + [-k₁ * y₁ + k₃ * y₂ * y₃, + k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2, + y₁ + y₂ + y₃ - 1] +end +M = [1.0 0 0 + 0 1.0 0 + 0 0 0] +roberf = ODEFunction(rober, mass_matrix = M) +roberf_oop = ODEFunction{false}(rober, mass_matrix = M) +prob_mm = ODEProblem(roberf, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) +prob_mm_oop = ODEProblem(roberf_oop, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rodas5P(), reltol = 1e-8, abstol = 1e-8) +sol = solve(prob_mm_oop, Rodas5P(), reltol = 1e-8, abstol = 1e-8) + +function f(out, du, u, p, t) + out[1] = -p[1] * u[1] + p[3] * u[2] * u[3] - du[1] + out[2] = +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2] + out[3] = u[1] + u[2] + u[3] - 1.0 +end +function f(du, u, p, t) + [-p[1] * u[1] + p[3] * u[2] * u[3] - du[1], + +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2], + u[1] + u[2] + u[3] - 1.0] +end +p = [0.04, 3e7, 1e4] +u₀ = [1.0, 0, 0] +du₀ = [-0.04, 0.04, 0.0] +tspan = (0.0, 100000.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) +prob_oop = DAEProblem{false}(f, du₀, u₀, tspan, p, differential_vars = differential_vars) +sol1 = solve(prob, DFBDF(), dt = 1e-5, abstol = 1e-8, reltol = 1e-8) + +# These tests flex differentiation of the solver and through the initialization +# To only test the solver part and isolate potential issues, set the initialization to consistent +@testset "Inplace: $(isinplace(_prob)), DAEProblem: $(_prob isa DAEProblem), BrownBasic: $(initalg isa BrownFullBasicInit), Autodiff: $autodiff" for _prob in [ + prob, prob_mm, prob_oop, prob_mm_oop], + initalg in [BrownFullBasicInit(), ShampineCollocationInit()], autodiff in [true, false] + + alg = _prob isa DAEProblem ? DFBDF(; autodiff) : Rodas5P(; autodiff) + function f(p) + sol = solve(remake(_prob, p = p), alg, abstol = 1e-14, + reltol = 1e-14, initializealg = initalg) + sum(sol) + end + @test ForwardDiff.gradient(f, [0.04, 3e7, 1e4])≈[0, 0, 0] atol=1e-8 +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl new file mode 100644 index 0000000000..e3ef2dd474 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl @@ -0,0 +1,56 @@ +using OrdinaryDiffEq, DiffEqDevTools +using Test, Random +Random.seed!(100) + +dts = 1 .// 2 .^ (9:-1:5) +testTol = 0.2 + +f_dae_linear = (res, du, u, p, t) -> (@. res = du - u) +f_dae_linear_analytic = (du0, u0, p, t) -> @. u0 * exp(t) +prob_dae_linear_iip = DAEProblem( + DAEFunction(f_dae_linear; + analytic = f_dae_linear_analytic), + [1.0, 1.0], [1.0, 1.0], (0.0, 1.0)) + +@testset "DAE Solver Convergence Tests (in-place)" begin + prob = prob_dae_linear_iip + + sim11 = test_convergence(dts, prob, DImplicitEuler()) + @test sim11.𝒪est[:final]≈1 atol=testTol + + sim12 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) + @test sim12.𝒪est[:final]≈1 atol=testTol + + sim13 = test_convergence(dts, prob, DABDF2()) + @test sim13.𝒪est[:final]≈2 atol=testTol + + sim14 = test_convergence(dts, prob, DABDF2(; autodiff = false)) + @test sim14.𝒪est[:final]≈2 atol=testTol + + @test_nowarn solve(prob, DFBDF()) +end + +f_dae_linear = (du, u, p, t) -> (@. du - u) +f_dae_linear_analytic = (du0, u0, p, t) -> @. u0 * exp(t) +prob_dae_linear_oop = DAEProblem( + DAEFunction(f_dae_linear; + analytic = f_dae_linear_analytic), + 1.0, 1.0, (0.0, 1.0)) + +@testset "DAE Solver Convergence Tests (out-of-place)" begin + prob = prob_dae_linear_oop + + sim21 = test_convergence(dts, prob, DImplicitEuler()) + @test sim21.𝒪est[:final]≈1 atol=testTol + + sim22 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) + @test sim22.𝒪est[:final]≈1 atol=testTol + + sim23 = test_convergence(dts, prob, DABDF2()) + @test sim23.𝒪est[:final]≈2 atol=testTol + + sim24 = test_convergence(dts, prob, DABDF2(; autodiff = false)) + @test sim24.𝒪est[:final]≈2 atol=testTol + + @test_nowarn solve(prob, DFBDF()) +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_event.jl b/lib/OrdinaryDiffEqDAE/test/dae_event.jl new file mode 100644 index 0000000000..c20b600670 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_event.jl @@ -0,0 +1,30 @@ +using OrdinaryDiffEq, Test + +f = function (out, du, u, p, t) + out[1] = -p[1] * u[1] + p[3] * u[2] * u[3] - du[1] + out[2] = +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2] + out[3] = u[1] + u[2] + u[3] - p[4] +end +u₀ = [1.0, 0, 0] +du₀ = [0.0, 0.0, 0.0] +p = [0.04, 3.0e7, 1.0e4, 1.0] +tspan = (0.0, 100.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) +condition(u, t, integrator) = t in [50.0] +affect!(integrator) = integrator.p[4] = 2.0 +cb = DiscreteCallback(condition, affect!) + +#= +# Regression test +using Sundials +sol = solve(prob, IDA(), callback=cb, tstops=[50.0],abstol=1e-14,reltol=1e-14) +=# + +p = [0.04, 3.0e7, 1.0e4, 1.0] +prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) +sol = solve(prob, DFBDF(), callback = cb, tstops = [50.0], abstol = 1e-12, reltol = 1e-12) +@test sol.t[end] == 100.0 +@test sol[end][1]≈0.686300529575259 atol=1e-7 +@test sol[end][2]≈2.0797982209353813e-6 atol=1e-7 +@test sol[end][3]≈1.31369739062652 atol=1e-7 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl new file mode 100644 index 0000000000..5cf37c27f4 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl @@ -0,0 +1,268 @@ +using OrdinaryDiffEq, StaticArrays, LinearAlgebra, Test + +## Mass Matrix + +function rober_oop(u, p, t) + y₁, y₂, y₃ = u + k₁, k₂, k₃ = p + du1 = -k₁ * y₁ + k₃ * y₂ * y₃ + du2 = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du3 = y₁ + y₂ + y₃ - 1 + [du1, du2, du3] +end +M = [1.0 0 0 + 0 1.0 0 + 0 0 0] +f_oop = ODEFunction(rober_oop, mass_matrix = M) +prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rosenbrock23(autodiff = false), reltol = 1e-8, abstol = 1e-8) +@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! +sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8, + initializealg = ShampineCollocationInit()) +@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! + +prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8) +@test sum(sol[1]) ≈ 1 +@test sol[1] ≈ [1.0, 0.0, 0.0] +for alg in [Rosenbrock23(autodiff = false), Trapezoid()] + local sol + sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, + initializealg = ShampineCollocationInit()) + @test sum(sol[1]) ≈ 1 +end + +function rober(du, u, p, t) + y₁, y₂, y₃ = u + k₁, k₂, k₃ = p + du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ + du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du[3] = y₁ + y₂ + y₃ - 1 + nothing +end +M = [1.0 0 0 + 0 1.0 0 + 0 0 0] +f = ODEFunction(rober, mass_matrix = M) +prob_mm = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rodas5(autodiff = false), reltol = 1e-8, abstol = 1e-8) +@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! +sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8, + initializealg = ShampineCollocationInit()) +@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! + +prob_mm = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8) +@test sum(sol[1]) ≈ 1 +@test sol[1] ≈ [1.0, 0.0, 0.0] + +for alg in [Rodas5(autodiff = false), Trapezoid()] + local sol + sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, + initializealg = ShampineCollocationInit()) + @test sum(sol[1]) ≈ 1 +end + +function rober_no_p(du, u, p, t) + y₁, y₂, y₃ = u + (k₁, k₂, k₃) = (0.04, 3e7, 1e4) + du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ + du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du[3] = y₁ + y₂ + y₃ - 1 + nothing +end + +function rober_oop_no_p(du, u, p, t) + y₁, y₂, y₃ = u + (k₁, k₂, k₃) = (0.04, 3e7, 1e4) + du1 = -k₁ * y₁ + k₃ * y₂ * y₃ + du2 = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du3 = y₁ + y₂ + y₃ - 1 + [du1, du2, du3] +end + +# test oop and iip ODE initialization with parameters without eltype/length +struct UnusedParam +end +for f in ( + ODEFunction(rober_no_p, mass_matrix = M), ODEFunction(rober_oop_no_p, mass_matrix = M)) + local prob, probp + prob = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5)) + probp = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5), UnusedParam) + for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) + isapprox(init(prob, Rodas5(), abstol = 1e-10; initializealg).u, + init(prob, Rodas5(), abstol = 1e-10; initializealg).u) + end +end + +## DAEProblem + +f = function (du, u, p, t) + out1 = -0.04u[1] + 1e4 * u[2] * u[3] - du[1] + out2 = +0.04u[1] - 3e7 * u[2]^2 - 1e4 * u[2] * u[3] - du[2] + out3 = u[1] + u[2] + u[3] - 1.0 + [out1, out2, out3] +end + +u₀ = [1.0, 0, 0] +du₀ = [0.0, 0.0, 0.0] +tspan = (0.0, 100000.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +integrator = init(prob, DImplicitEuler()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +integrator = init(prob, DFBDF()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +u₀ = [1.0, 0, 0.2] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) +@test integrator.u≈[1.0, 0, 0.0] atol=1e-9 +integrator = init(prob, DABDF2(), initializealg = ShampineCollocationInit()) +@test !(integrator.u ≈ [1.0, 0, 0.0]) + +u₀ = [1.0, 0, 0.2] +prob = DAEProblem(f, du₀, u₀, tspan) +integrator = init(prob, DABDF2()) +@test !(integrator.u ≈ [1.0, 0, 0.0]) + +f = function (out, du, u, p, t) + out[1] = -0.04u[1] + 1e4 * u[2] * u[3] - du[1] + out[2] = +0.04u[1] - 3e7 * u[2]^2 - 1e4 * u[2] * u[3] - du[2] + out[3] = u[1] + u[2] + u[3] - 1.0 +end + +u₀ = [1.0, 0, 0] +du₀ = [0.0, 0.0, 0.0] +tspan = (0.0, 100000.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) +integrator2 = init(prob, DABDF2(autodiff = false)) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +@test integrator2.du[1]≈-0.04 atol=1e-99 +@test integrator2.du[2]≈0.04 atol=1e-9 +@test integrator2.u≈u₀ atol=1e-9 + +integrator = init(prob, DImplicitEuler()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +integrator = init(prob, DFBDF()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +u₀ = [1.0, 0, 0.2] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) +@test integrator.u≈[1.0, 0, 0.0] atol=1e-9 +integrator = init(prob, DABDF2(), initializealg = ShampineCollocationInit()) +@test !(integrator.u ≈ [1.0, 0, 0.0]) + +u₀ = [1.0, 0, 0.2] +prob = DAEProblem(f, du₀, u₀, tspan) +integrator = init(prob, DABDF2()) +@test !(integrator.u ≈ [1.0, 0, 0.0]) + +# Need to be able to find the consistent solution of this problem, broken right now +# analytical solution: +# u[1](t) -> cos(t) +# u[2](t) -> -sin(t) +# u[3](t) -> 2cos(t) +f = function (out, du, u, p, t) + out[1] = du[1] - u[2] + out[2] = du[2] + u[3] - cos(t) + out[3] = u[1] - cos(t) +end + +u₀ = [1.0, 0.0, 0.0] +du₀ = [0.0, 0.0, 0.0] +tspan = (0.0, 1.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2(); initializealg = ShampineCollocationInit()) + +@test integrator.du[1]≈0.0 atol=1e-9 +@test_broken integrator.du[2]≈-1.0 atol=1e-9 +@test_broken integrator.u[3]≈2.0 atol=1e-9 + +# test iip dae initialization with parameters without eltype/length +probp = DAEProblem(f, du₀, u₀, tspan, UnusedParam(), differential_vars = differential_vars) +for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) + @test isapprox( + init(probp, DABDF2(); initializealg).u, init(prob, DABDF2(); initializealg).u) +end + +f = function (du, u, p, t) + du - u +end + +u₀ = SVector(1.0) +du₀ = SVector(0.0) +tspan = (0.0, 1.0) +differential_vars = SVector(true) +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) + +@test integrator.du≈[1.0] atol=1e-9 + +f = function (du, u, p, t) + du .- u +end + +u₀ = SA[1.0, 1.0] +du₀ = SA[0.0, 0.0] +tspan = (0.0, 1.0) +differential_vars = [true, true] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) + +@test integrator.du[1]≈1.0 atol=1e-9 +@test integrator.du[2]≈1.0 atol=1e-9 +# test oop DAE initialization with parameters without eltype/length +probp = DAEProblem(f, du₀, u₀, tspan, UnusedParam(), differential_vars = differential_vars) +for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) + @test isapprox( + init(probp, DABDF2(); initializealg).u, init(prob, DABDF2(); initializealg).u) +end + +# to test that we get the right NL solve we need a broken solver. +struct BrokenNLSolve <: SciMLBase.AbstractNonlinearAlgorithm + BrokenNLSolve(; kwargs...) = new() +end +function SciMLBase.__solve(prob::NonlinearProblem, + alg::BrokenNLSolve, args...; + kwargs...) + u = fill(reinterpret(Float64, 0xDEADBEEFDEADBEEF), 3) + SciMLBase.build_solution(prob, alg, u, copy(u); + retcode = ReturnCode.Success) +end +function f2(u, p, t) + u +end +f = ODEFunction(f2, mass_matrix = Diagonal([1.0, 1.0, 0.0])) +prob = ODEProblem(f, ones(3), (0.0, 1.0)) +integrator = init(prob, Rodas5P(), + initializealg = ShampineCollocationInit(1.0, BrokenNLSolve())) +@test all(isequal(reinterpret(Float64, 0xDEADBEEFDEADBEEF)), integrator.u) \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl new file mode 100644 index 0000000000..33913925e2 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl @@ -0,0 +1,78 @@ +using ModelingToolkit, OrdinaryDiffEq, Test + +@parameters t g e b +@variables v(t) w(t) F(t) +@derivatives D' ~ t +single_neuron_eqs = [ + D(v) ~ min(max(-2 - v, v), 2 - v) - w + F, # add the flux term + D(w) ~ e * (v - g * w + b) +] +n1 = ODESystem(single_neuron_eqs, t, [v, w, F], [g, e, b], name = :n1) +n2 = ODESystem(single_neuron_eqs, t, [v, w, F], [g, e, b], name = :n2) +@parameters D Dk +connections = [0 ~ n1.F - D * Dk * max(n1.v - n2.v, 0) + 0 ~ n2.F - D * max(n2.v - n1.v, 0)] +connected = ODESystem(connections, t, [], [D, Dk], systems = [n1, n2], name = :connected) +connected = complete(connected) + +u0 = [ + n1.v => -2, + n1.w => -2 / 3, + n1.F => 0, + n2.v => -2, + n2.w => -0.7, + n2.F => 0 +] +tspan = (0.0, 1750.0) +p0 = [ + n1.g => 0.8, + n1.e => 0.04, + n1.b => 0, + n2.g => 0.8, + n2.e => 0.04, + n2.b => 0.2, + D => 0.047, + Dk => 1 +] + +prob = ODEProblem(connected, u0, tspan, p0) +sol = solve(prob, Rodas5(), initializealg = BrownFullBasicInit()) +@test prob.u0 == sol[1] +sol = solve(prob, Rodas5(), initializealg = ShampineCollocationInit()) +@test prob.u0 == sol[1] +#test initialization when given a specific nonlinear solver +using NonlinearSolve +sol = solve(prob, Rodas5(), initializealg = BrownFullBasicInit(1e-10, RobustMultiNewton())) +@test prob.u0 == sol[1] + +# Initialize on ODEs +# https://github.com/SciML/ModelingToolkit.jl/issues/2508 + +function testsys(du, u, p, t) + du[1] = -2 +end +function initsys(du, u, p) + du[1] = -1 + u[1] +end +nlprob = NonlinearProblem(initsys, [0.0]) +initprobmap(nlprob) = nlprob.u +sol = solve(nlprob) + +_f = ODEFunction(testsys; initializeprob = nlprob, initializeprobmap = initprobmap) +prob = ODEProblem(_f, [0.0], (0.0, 1.0)) +sol = solve(prob, Tsit5()) +@test SciMLBase.successful_retcode(sol) +@test sol[1] == [1.0] + +prob = ODEProblem(_f, [0.0], (0.0, 1.0)) +sol = solve(prob, Tsit5(), dt = 1e-10) +@test SciMLBase.successful_retcode(sol) +@test sol[1] == [1.0] +@test sol[2] ≈ [0.9999999998] +@test sol[end] ≈ [-1.0] + +sol = solve(prob, Rodas5P(), dt = 1e-10) +@test SciMLBase.successful_retcode(sol) +@test sol[1] == [1.0] +@test sol[2] ≈ [0.9999999998] +@test sol[end] ≈ [-1.0] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/hard_dae.jl b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl new file mode 100644 index 0000000000..f47b226ce1 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl @@ -0,0 +1,275 @@ +using OrdinaryDiffEq +using LinearAlgebra +using NLsolve +using Test + +p_inv = [500.0 + 0.084 + 4.69 + 2.0 + 400.0 + 20.0 + 0.2 + 1000.0 + 0.59 + 736.0 + 0.0 + 0.0 + 0.2 + 1.27 + 14.3 + 0.0 + 50.0 + 0.2 + 0.08 + 0.003 + 0.074 + 0.2 + 0.01 # Matt + 1.0 # V_ref + 1.0 # ω ref + 0.7 # Pref + 0 # Q_ref + 0.5 #Xtrans + 0.0 # Rtrans + 1.01 #Vm + 0.0] # Vθ + +function vsm(dx, x, p, t) + #PARAMETERS + ω_lp = p[1] + kp_pll = p[2] + ki_pll = p[3] + Ta = p[4] + kd = p[5] + kω = p[6] + kq = p[7] + ωf = p[8] + kpv = p[9] + kiv = p[10] + kffv = p[11] + rv = p[12] + lv = p[13] + kpc = p[14] + kic = p[15] + kffi = p[16] + ωad = p[17] + kad = p[18] + lf = p[19] + rf = p[20] + cf = p[21] + lg = p[22] + rg = p[23] + Vref = p[24] + ωref = p[25] + Pref = p[26] + Qref = p[27] + Xtrans = p[28] + Rtrans = p[29] + Vm = p[30] + Vθ = p[31] + + #STATE INDEX AND STATES + i__vi_filter, vi_filter = 1, x[1] + i__γd_ic, γd_ic = 2, x[2] + i__vq_pll, vq_pll = 3, x[3] + i__γq_ic, γq_ic = 4, x[4] + i__ir_filter, ir_filter = 5, x[5] + i__ξd_ic, ξd_ic = 6, x[6] + i__ϕd_ic, ϕd_ic = 7, x[7] + i__ε_pll, ε_pll = 8, x[8] + i__ir_cnv, ir_cnv = 9, x[9] + i__vr_filter, vr_filter = 10, x[10] + i__ω_oc, ω_oc = 11, x[11] + i__ξq_ic, ξq_ic = 12, x[12] + i__vd_pll, vd_pll = 13, x[13] + i__q_oc, q_oc = 14, x[14] + i__ϕq_ic, ϕq_ic = 15, x[15] + i__θ_pll, θ_pll = 16, x[16] + i__θ_oc, θ_oc = 17, x[17] + i__ii_cnv, ii_cnv = 18, x[18] + i__ii_filter, ii_filter = 19, x[19] + i__ir_source, ir_source = 20, x[20] + i__ii_source, ii_source = 21, x[21] + + ω_base = 60.0 * 2 * pi + ω_sys = 1.0 + + #PLL + δω_pll = kp_pll * atan(vq_pll / vd_pll) + ki_pll * ε_pll + ω_pll = δω_pll + ω_sys + vd_filt_pll = sin(θ_pll + pi / 2) * vr_filter - cos(θ_pll + pi / 2) * vi_filter + vq_filt_pll = cos(θ_pll + pi / 2) * vr_filter + sin(θ_pll + pi / 2) * vi_filter + + dx[i__vd_pll] = ω_lp * (vd_filt_pll - vd_pll) #docs:(1a) + dx[i__vq_pll] = ω_lp * (vq_filt_pll - vq_pll) #docs:(1b) + dx[i__ε_pll] = atan(vq_pll / vd_pll) #docs:(1c) + dx[i__θ_pll] = ω_base * δω_pll #docs:(1d) + + #OUTER LOOP CONTROL + pe = vr_filter * ir_filter + vi_filter * ii_filter #docs:(2d) + qe = vi_filter * ir_filter - vr_filter * ii_filter #docs:(2e) + v_ref_olc = Vref + kq * (Qref - q_oc) + + dx[i__ω_oc] = (Pref - pe - kd * (ω_oc - ω_pll) - kω * (ω_oc - ωref)) / Ta #docs:(2a) + dx[i__θ_oc] = ω_base * (ω_oc - ω_sys) #docs:(2b) + dx[i__q_oc] = ωf * (qe - q_oc) #docs:(2c) + + #INNER LOOP CONTROL + #reference transformations + vd_filt_olc = sin(θ_oc + pi / 2) * vr_filter - cos(θ_oc + pi / 2) * vi_filter + vq_filt_olc = cos(θ_oc + pi / 2) * vr_filter + sin(θ_oc + pi / 2) * vi_filter + id_filt_olc = sin(θ_oc + pi / 2) * ir_filter - cos(θ_oc + pi / 2) * ii_filter + iq_filt_olc = cos(θ_oc + pi / 2) * ir_filter + sin(θ_oc + pi / 2) * ii_filter + id_cnv_olc = sin(θ_oc + pi / 2) * ir_cnv - cos(θ_oc + pi / 2) * ii_cnv + iq_cnv_olc = cos(θ_oc + pi / 2) * ir_cnv + sin(θ_oc + pi / 2) * ii_cnv + + #Voltage control equations + Vd_filter_ref = v_ref_olc - rv * id_filt_olc + ω_oc * lv * iq_filt_olc #docs:(3g) + Vq_filter_ref = -rv * iq_filt_olc - ω_oc * lv * id_filt_olc #docs:(3h) + dx[i__ξd_ic] = Vd_filter_ref - vd_filt_olc #docs:(3a) + dx[i__ξq_ic] = Vq_filter_ref - vq_filt_olc #docs:(3b) + + #current control equations + Id_cnv_ref = (kpv * (Vd_filter_ref - vd_filt_olc) + kiv * ξd_ic - #docs:(3i) + cf * ω_oc * vq_filt_olc + kffi * id_filt_olc) + Iq_cnv_ref = (kpv * (Vq_filter_ref - vq_filt_olc) + + kiv * ξq_ic + #docs:(3j) + cf * ω_oc * vd_filt_olc + + kffi * iq_filt_olc) + dx[i__γd_ic] = Id_cnv_ref - id_cnv_olc #docs:(3c) + dx[i__γq_ic] = Iq_cnv_ref - iq_cnv_olc #docs:(3d) + + #active damping equations + Vd_cnv_ref = (kpc * (Id_cnv_ref - id_cnv_olc) + kic * γd_ic - lf * ω_oc * iq_cnv_olc + #docs:(3k) + kffv * vd_filt_olc - kad * (vd_filt_olc - ϕd_ic)) + Vq_cnv_ref = (kpc * (Iq_cnv_ref - iq_cnv_olc) + + kic * γq_ic + + lf * ω_oc * id_cnv_olc + #docs:(3l) + kffv * vq_filt_olc - kad * (vq_filt_olc - ϕq_ic)) + dx[i__ϕd_ic] = ωad * (vd_filt_olc - ϕd_ic) #docs:(3e) + dx[i__ϕq_ic] = ωad * (vq_filt_olc - ϕq_ic) #docs:(3f) + + #LCL FILTER + #reference transformations + Vr_cnv = sin(θ_oc + pi / 2) * Vd_cnv_ref + cos(θ_oc + pi / 2) * Vq_cnv_ref + Vi_cnv = -cos(θ_oc + pi / 2) * Vd_cnv_ref + sin(θ_oc + pi / 2) * Vq_cnv_ref + + Vr_pcc = Vm * cos(Vθ) + Vi_pcc = Vm * sin(Vθ) + + dx[i__ir_cnv] = (ω_base / lf) * #docs:(5a) + (Vr_cnv - vr_filter - rf * ir_cnv + ω_sys * lf * ii_cnv) + dx[i__ii_cnv] = (ω_base / lf) * #docs:(5b) + (Vi_cnv - vi_filter - rf * ii_cnv - ω_sys * lf * ir_cnv) + dx[i__vr_filter] = (ω_base / cf) * #docs:(5c) + (ir_cnv - ir_filter + ω_sys * cf * vi_filter) + dx[i__vi_filter] = (ω_base / cf) * #docs:(5d) + (ii_cnv - ii_filter - ω_sys * cf * vr_filter) + dx[i__ir_filter] = (ω_base / lg) * #docs:(5e) + (vr_filter - Vr_pcc - rg * ir_filter + ω_sys * lg * ii_filter) + dx[i__ii_filter] = +(ω_base / lg) * #docs:(5f) + (vi_filter - Vi_pcc - rg * ii_filter - ω_sys * lg * ir_filter) + + # Network interface algebraic equations 0 = I - YV + line_currents = ((Vr_cnv + Vi_cnv * 1im) - (Vr_pcc + Vi_pcc * 1im)) / + (Rtrans + Xtrans * 1im) + dx[i__ii_source] = ii_source - imag(line_currents) + dx[i__ir_source] = ir_source - real(line_currents) + return +end + +u0 = [0.0, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 1.0, + 1.0, + 0.0, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.0, + 1.0, + 0.0 +] +init_f! = (dx, x) -> vsm(dx, x, p_inv, 0) +res = nlsolve(init_f!, u0) + +M = diagm(ones(21)) +#Last 2 equations are algebraic +M[20, 20] = M[21, 21] = 0.0 + +f = ODEFunction(vsm, mass_matrix = M) + +condition(u, t, integrator) = t == 1.0 +affect!(integrator) = integrator.p[28] += 0.2 +cb = DiscreteCallback(condition, affect!) + +prob = ODEProblem(f, deepcopy(res.zero), (0, 20.0), deepcopy(p_inv)) +refsol = solve(prob, Rodas4(), saveat = 0.1, callback = cb, tstops = [1.0], reltol = 1e-12, + abstol = 1e-17) + +for solver in (Rodas4, Rodas4P, Rodas5, Rodas5P, FBDF, QNDF, Rosenbrock23) + @show solver + prob = ODEProblem(f, deepcopy(res.zero), (0, 20.0), deepcopy(p_inv)) + sol = solve( + prob, solver(), saveat = 0.1, callback = cb, tstops = [1.0], reltol = 1e-14, + abstol = 1e-14) + @test sol.retcode == ReturnCode.Success + @test sol.t[end] == 20.0 + @test maximum(sol - refsol) < 1e-11 +end + +function hardstop!(du, u, p, t) + pm, pg = p + y, f_wall, dy = u + du[1] = dy + du[2] = ifelse(y <= 0, y, f_wall) + du[3] = (-ifelse(t < 2, -pg * pm, pg * pm) - f_wall) / (-pm) +end + +hardstop!(u, p, t) = (du = similar(u); hardstop!(du, u, p, t); du) + +fun = ODEFunction(hardstop!, mass_matrix = Diagonal([1, 0, 1])) +prob1 = ODEProblem(fun, [5, 0, 0.0], (0, 4.0), [100, 10.0]) +prob2 = ODEProblem(fun, [5, 0, 0.0], (0, 4.0), [100, 10.0]) +for prob in [prob1, prob2] + @test solve(prob, ImplicitEuler(), dt = 1 / 2^10, adaptive = false).retcode == + ReturnCode.ConvergenceFailure +end + +condition2 = (u, t, integrator) -> t == 2 +affect2! = integrator -> integrator.u[1] = 1e-6 +cb = DiscreteCallback(condition2, affect2!) + +@isdefined(N_FAILS) || const N_FAILS = Ref(0) +function choice_function(integrator) + integrator.do_error_check = false + if integrator.force_stepfail + N_FAILS[] += 1 + else + N_FAILS[] = 0 + end + + (N_FAILS[] > 3) + 1 +end +simple_implicit_euler = ImplicitEuler(nlsolve = NLNewton(check_div = false, + always_new = true)) +alg_switch = CompositeAlgorithm((ImplicitEuler(), simple_implicit_euler), choice_function) + +for prob in [prob1, prob2], alg in [simple_implicit_euler, alg_switch] + sol = solve(prob, alg, callback = cb, dt = 1 / 2^10, adaptive = false) + @test sol.retcode == ReturnCode.Success + @test sol(0, idxs = 1) == 5 + @test sol(2, idxs = 1) == 0 + @test sol(4, idxs = 1) > 10 +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/runtests.jl b/test/runtests.jl index 1edccc79e5..fd03660767 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -147,9 +147,9 @@ end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceV" || GROUP == "Interface") @time @safetestset "Interpolation Derivative Error Tests" include("interface/interpolation_derivative_error_tests.jl") @time @safetestset "AD Tests" include("interface/ad_tests.jl") - @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl") + @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl") @time @safetestset "Newton Tests" include("interface/newton_tests.jl") - @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl") + @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl") end if !is_APPVEYOR && @@ -173,8 +173,8 @@ end @time @safetestset "Reverse Directioned Event Tests" include("integrators/rev_events_tests.jl") @time @safetestset "Differentiation Direction Tests" include("integrators/diffdir_tests.jl") @time @safetestset "Resize Tests" include("integrators/resize_tests.jl") - @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl") - @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_event.jl") + @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl") + @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_event.jl") @time @safetestset "Cache Tests" include("integrators/ode_cache_tests.jl") @time @safetestset "Add Steps Tests" include("integrators/ode_add_steps_tests.jl") @time @safetestset "IMEX Split Function Tests" include("integrators/split_ode_tests.jl") @@ -185,7 +185,7 @@ end @time @safetestset "Special Interp Tests" include("regression/special_interps.jl") @time @safetestset "Inplace Tests" include("regression/ode_inplace_tests.jl") @time @safetestset "Adaptive Tests" include("regression/ode_adaptive_tests.jl") - @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqBDF/test/hard_dae.jl") + @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqDAE/test/hard_dae.jl") end if !is_APPVEYOR && (GROUP == "All" || GROUP == "Regression_II" || GROUP == "Regression") @@ -199,7 +199,7 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_I" @time @safetestset "Partitioned Methods Tests" include("algconvergence/partitioned_methods_tests.jl") @time @safetestset "Convergence Tests" include("algconvergence/ode_convergence_tests.jl") - @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl") + @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl") @time @safetestset "Non-autonomous Convergence Tests" include("algconvergence/non-autonomous_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("algconvergence/adams_tests.jl") @time @safetestset "Nordsieck Tests" include("algconvergence/nordsieck_tests.jl") From f54c38c920b765ad9ae053ff6fb3e36afe6f49b5 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:19:15 +0530 Subject: [PATCH 24/45] @.. --- lib/OrdinaryDiffEqDAE/Project.toml | 1 + lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml index ee3e8c74e7..b15e3bbe39 100644 --- a/lib/OrdinaryDiffEqDAE/Project.toml +++ b/lib/OrdinaryDiffEqDAE/Project.toml @@ -6,6 +6,7 @@ version = "1.0.0" [deps] OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" [extras] DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index ed77fee311..82a1d7d496 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -5,6 +5,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack using TruncatedStacktraces +import FastBroadCast: @.. include("algorithms.jl") include("alg_utils.jl") From 16b955168d971430b3387cc29092658df1d91588 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:41:13 +0530 Subject: [PATCH 25/45] @.. --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- lib/OrdinaryDiffEqDAE/test/runtest.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 82a1d7d496..9643b52c2d 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -5,7 +5,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack using TruncatedStacktraces -import FastBroadCast: @.. +import FastBroadcast: @.. include("algorithms.jl") include("alg_utils.jl") diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl index e69de29bb2..a639da4027 100644 --- a/lib/OrdinaryDiffEqDAE/test/runtest.jl +++ b/lib/OrdinaryDiffEqDAE/test/runtest.jl @@ -0,0 +1,2 @@ +using SafeTestsets + From 44b2a9e4a3f1a81f6522a3389ad69a38108457f7 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:43:51 +0530 Subject: [PATCH 26/45] @cache --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 9643b52c2d..374e6b772b 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -3,7 +3,7 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack + @unpack, @cache using TruncatedStacktraces import FastBroadcast: @.. From 1ca1a5ca0752af4c65b665b5b929ba1edba0c2b2 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:46:02 +0530 Subject: [PATCH 27/45] MuladdMacro --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 374e6b772b..0657ec30b9 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -4,7 +4,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack, @cache -using TruncatedStacktraces +using TruncatedStacktraces, MuladdMacro import FastBroadcast: @.. include("algorithms.jl") From ba5a4293752ade9a4cda40a8d2c6bf6c0b2c00c0 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:56:06 +0530 Subject: [PATCH 28/45] controllers --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 0657ec30b9..9017917bb8 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -3,7 +3,9 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack, @cache + @unpack, @cache, default_controller, stepsize_controller!, + step_accept_controller!, + step_reject_controller!, post_newton_controller! using TruncatedStacktraces, MuladdMacro import FastBroadcast: @.. From 780d97c4ecffea76a50376c32194ff432c5a9c17 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 11:13:21 +0530 Subject: [PATCH 29/45] post_newton_controller! --- src/OrdinaryDiffEq.jl | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index c594bc4cd1..5f91695273 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -290,18 +290,8 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp, bdf_step_reject_controller! -<<<<<<< HEAD using ..OrdinaryDiffEqBDF: post_newton_controller! include("integrators/integrator_utils.jl") -======= -include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") -using ..OrdinaryDiffEqDAE -export DImplicitEuler, DABDF2, DFBDF ->>>>>>> b150b887 (Added DAE solvers) -include("nlsolve/newton.jl") - -import PrecompileTools - PrecompileTools.@compile_workload begin function lorenz(du, u, p, t) du[1] = 10.0(u[2] - u[1]) From 1c4209f66e28082814e7c68d0b85278699009865 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Fri, 26 Jul 2024 22:20:47 +0530 Subject: [PATCH 30/45] DAE added to BDF --- lib/OrdinaryDiffEqBDF/test/runtest.jl | 2 +- lib/OrdinaryDiffEqDAE/Project.toml | 21 - .../src/OrdinaryDiffEqDAE.jl | 20 - lib/OrdinaryDiffEqDAE/src/alg_utils.jl | 12 - lib/OrdinaryDiffEqDAE/src/algorithms.jl | 75 --- lib/OrdinaryDiffEqDAE/src/controllers.jl | 130 ----- lib/OrdinaryDiffEqDAE/src/dae_caches.jl | 256 ---------- lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl | 460 ------------------ lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl | 60 --- .../test/dae_convergence_tests.jl | 56 --- lib/OrdinaryDiffEqDAE/test/dae_event.jl | 30 -- .../test/dae_initialization_tests.jl | 268 ---------- .../test/dae_initialize_integration.jl | 78 --- lib/OrdinaryDiffEqDAE/test/hard_dae.jl | 275 ----------- lib/OrdinaryDiffEqDAE/test/runtest.jl | 2 - test/runtests.jl | 12 +- 16 files changed, 7 insertions(+), 1750 deletions(-) delete mode 100644 lib/OrdinaryDiffEqDAE/Project.toml delete mode 100644 lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/controllers.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/dae_caches.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_event.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/hard_dae.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/runtest.jl diff --git a/lib/OrdinaryDiffEqBDF/test/runtest.jl b/lib/OrdinaryDiffEqBDF/test/runtest.jl index aeacfd70d2..71d30a6a01 100644 --- a/lib/OrdinaryDiffEqBDF/test/runtest.jl +++ b/lib/OrdinaryDiffEqBDF/test/runtest.jl @@ -5,4 +5,4 @@ using SafeTestsets @time @safetestset "DAE Initialization Tests" include("dae_initialization_tests.jl") @time @safetestset "DAE Event Tests" include("dae_event.jl") @time @safetestset "Hard DAE Tests" include("hard_dae.jl") -@time @safetestset "DAE Convergence Tests" include("dae_convergence_tests.jl") \ No newline at end of file +@time @safetestset "DAE Convergence Tests" include("dae_convergence_tests.jl") diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml deleted file mode 100644 index b15e3bbe39..0000000000 --- a/lib/OrdinaryDiffEqDAE/Project.toml +++ /dev/null @@ -1,21 +0,0 @@ -name = "OrdinaryDiffEqDAE" -uuid = "7d2d7016-1c68-401d-834f-6be2c6dc7d88" -authors = ["ParamThakkar123 "] -version = "1.0.0" - -[deps] -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[compat] -julia = "1.10" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl deleted file mode 100644 index 9017917bb8..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ /dev/null @@ -1,20 +0,0 @@ -module OrdinaryDiffEqDAE - -import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, - DEFAULT_PRECS, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack, @cache, default_controller, stepsize_controller!, - step_accept_controller!, - step_reject_controller!, post_newton_controller! -using TruncatedStacktraces, MuladdMacro -import FastBroadcast: @.. - -include("algorithms.jl") -include("alg_utils.jl") -include("controllers.jl") -include("dae_caches.jl") -include("dae_perform_step.jl") - -export DABDF2, DImplicitEuler, DFBDF - -end # module OrdinaryDiffEqDAE diff --git a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl deleted file mode 100644 index ff0d60daac..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl +++ /dev/null @@ -1,12 +0,0 @@ -isadaptive(alg::DImplicitEuler) = true -isadaptive(alg::DABDF2) = true -isadaptive(alg::DFBDF) = true - -alg_extrapolates(alg::DImplicitEuler) = true -alg_extrapolates(alg::DABDF2) = true - -alg_order(alg::DImplicitEuler) = 1 -alg_order(alg::DABDF2) = 2 -alg_order(alg::DFBDF) = 1#dummy value - -isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/algorithms.jl b/lib/OrdinaryDiffEqDAE/src/algorithms.jl deleted file mode 100644 index f8584348a5..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/algorithms.jl +++ /dev/null @@ -1,75 +0,0 @@ -struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DImplicitEuler(; - chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -#= -struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, - linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = - DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( - linsolve,nlsolve,precs,extrapolant) -=# - -struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - controller::Symbol -end -function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, controller = :Standard) where {MO} - DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, - controller) -end - -TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/controllers.jl b/lib/OrdinaryDiffEqDAE/src/controllers.jl deleted file mode 100644 index 4ae1a93a28..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/controllers.jl +++ /dev/null @@ -1,130 +0,0 @@ -function step_reject_controller!(integrator, ::DFBDF) - bdf_step_reject_controller!(integrator, integrator.cache.terkm1) -end - -function post_newton_controller!(integrator, alg) - integrator.dt = integrator.dt / integrator.opts.failfactor - nothing -end - -function post_newton_controller!(integrator, alg::DFBDF) - @unpack cache = integrator - if cache.order > 1 && cache.nlsolver.nfails >= 3 - cache.order -= 1 - end - integrator.dt = integrator.dt / integrator.opts.failfactor - integrator.cache.consfailcnt += 1 - integrator.cache.nconsteps = 0 - nothing -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqMutableCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache - k = cache.order - # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] - end - @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqConstantCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache - k = cache.order - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - if u isa Number - for i in 2:(k - 2) - terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] - end - terk_tmp *= abs(dt^(k - 2)) - else - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * - u_history[:, i - 1] - end - terk_tmp = reshape(vc, size(terk_tmp)) - terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) - end - atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function stepsize_controller!(integrator, - alg::DFBDF{max_order}) where { - max_order, -} - @unpack cache = integrator - cache.prev_order = cache.order - k, terk = choose_order!(alg, integrator, cache, Val(max_order)) - if k != cache.order - integrator.cache.nconsteps = 0 - cache.order = k - end - if iszero(terk) - q = inv(integrator.opts.qmax) - else - q = ((2 * terk / (k + 1))^(1 / (k + 1))) - end - integrator.qold = q - q -end - -function step_accept_controller!(integrator, alg::DFBDF{max_order}, - q) where {max_order} - integrator.cache.consfailcnt = 0 - if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min - q = one(q) - end - integrator.cache.nconsteps += 1 - integrator.cache.iters_from_event += 1 - return integrator.dt / q -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_caches.jl b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl deleted file mode 100644 index c432408952..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/dae_caches.jl +++ /dev/null @@ -1,256 +0,0 @@ -@cache mutable struct DImplicitEulerCache{uType, rateType, uNoUnitsType, N} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - uprev2::uType - atmp::uNoUnitsType - k₁::rateType - k₂::rateType - nlsolver::N -end - -mutable struct DImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache - nlsolver::N -end - -function alg_cache(alg::DImplicitEuler, du, u, res_prototype, rate_prototype, - ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - α = 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(false)) - - DImplicitEulerConstantCache(nlsolver) -end - -function alg_cache(alg::DImplicitEuler, du, u, res_prototype, rate_prototype, - ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - α = 1 - k₁ = zero(rate_prototype) - k₂ = zero(rate_prototype) - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(true)) - - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - DImplicitEulerCache(u, uprev, uprev2, atmp, k₁, k₂, nlsolver) -end - -@cache mutable struct DABDF2ConstantCache{N, dtType, rate_prototype} <: - OrdinaryDiffEqConstantCache - nlsolver::N - eulercache::DImplicitEulerConstantCache - dtₙ₋₁::dtType - fsalfirstprev::rate_prototype -end - -function alg_cache(alg::DABDF2, du, u, res_prototype, rate_prototype, - ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 1, 1 - α = 1 // 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(false)) - eulercache = DImplicitEulerConstantCache(nlsolver) - - dtₙ₋₁ = one(dt) - fsalfirstprev = rate_prototype - - DABDF2ConstantCache(nlsolver, eulercache, dtₙ₋₁, fsalfirstprev) -end - -@cache mutable struct DABDF2Cache{uType, rateType, uNoUnitsType, N, dtType} <: - OrdinaryDiffEqMutableCache - uₙ::uType - uₙ₋₁::uType - uₙ₋₂::uType - fsalfirst::rateType - fsalfirstprev::rateType - atmp::uNoUnitsType - nlsolver::N - eulercache::DImplicitEulerCache - dtₙ₋₁::dtType -end - -function alg_cache(alg::DABDF2, du, u, res_prototype, rate_prototype, - ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 1, 1 - α = 1 // 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(true)) - fsalfirst = zero(rate_prototype) - - fsalfirstprev = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - k₁ = zero(rate_prototype) - k₂ = zero(rate_prototype) - - eulercache = DImplicitEulerCache(u, uprev, uprev2, atmp, k₁, k₂, nlsolver) - - dtₙ₋₁ = one(dt) - - DABDF2Cache(u, uprev, uprev2, fsalfirst, fsalfirstprev, atmp, - nlsolver, eulercache, dtₙ₋₁) -end - -@cache mutable struct DFBDFConstantCache{MO, N, tsType, tType, uType, uuType, coeffType, - EEstType, rType, wType} <: - OrdinaryDiffEqConstantCache - nlsolver::N - ts::tsType - ts_tmp::tsType - t_old::tType - u_history::uuType - order::Int - prev_order::Int - u₀::uType - u_corrector::uuType - bdf_coeffs::coeffType - max_order::Val{MO} - nconsteps::Int - consfailcnt::Int - terkm2::EEstType - terkm1::EEstType - terk::EEstType - terkp1::EEstType - r::rType - weights::wType - iters_from_event::Int -end - -function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, - uprev, uprev2, f, t, dt, reltol, p, calck, ::Val{false}) where {MO} - γ, c = 1.0, 1.0 - max_order = MO - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - bdf_coeffs = SA[1 -1 0 0 0 0; - 2//3 -4//3 1//3 0 0 0; - 6//11 -18//11 9//11 -2//11 0 0; - 12//25 -48//25 36//25 -16//25 3//25 0; - 60//137 -300//137 300//137 -200//137 75//137 -12//137] - ts = zero(Vector{typeof(t)}(undef, max_order + 2)) #ts is the successful past points, it will be updated after successful step - ts_tmp = similar(ts) - - u_history = zero(Matrix{eltype(u)}(undef, length(u), max_order + 2)) - order = 1 - prev_order = 1 - u_corrector = similar(u_history) - recursivefill!(u_corrector, zero(eltype(u))) - recursivefill!(u_history, zero(eltype(u_history))) - terkm2 = tTypeNoUnits(1) - terkm1 = tTypeNoUnits(1) - terk = tTypeNoUnits(1) - terkp1 = tTypeNoUnits(1) - r = zero(Vector{typeof(t)}(undef, max_order + 2)) - weights = zero(Vector{typeof(t)}(undef, max_order + 2)) - weights[1] = 1 - nconsteps = 0 - consfailcnt = 0 - t_old = zero(t) - iters_from_event = 0 - u₀ = zero(u) - - DFBDFConstantCache(nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, u₀, - u_corrector, bdf_coeffs, Val(5), nconsteps, consfailcnt, terkm2, - terkm1, terk, terkp1, r, weights, iters_from_event) -end - -@cache mutable struct DFBDFCache{MO, N, rateType, uNoUnitsType, tsType, tType, uType, - uuType, coeffType, EEstType, rType, wType} <: - OrdinaryDiffEqMutableCache - fsalfirst::rateType - nlsolver::N - ts::tsType - ts_tmp::tsType - t_old::tType - u_history::uuType - order::Int - prev_order::Int - u_corrector::uuType - u₀::uType - bdf_coeffs::coeffType - max_order::Val{MO} - nconsteps::Int - consfailcnt::Int - tmp::uType - atmp::uNoUnitsType - terkm2::EEstType - terkm1::EEstType - terk::EEstType - terkp1::EEstType - terk_tmp::uType - terkp1_tmp::uType - r::rType - weights::wType - equi_ts::tsType - iters_from_event::Int -end - -function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, - tTypeNoUnits, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {MO} - γ, c = 1.0, 1.0 - fsalfirst = zero(rate_prototype) - max_order = MO - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - #=bdf_coeffs = SA[1 -1 0 0 0 0 ; - 3//2 -2 1//2 0 0 0 ; - 11//6 -3 3//2 -1//3 0 0 ; - 25//12 -4 3 -4//3 1//4 0 ; - 137//60 -5 5 -10//3 5//4 -1//5]=# - bdf_coeffs = SA[1 -1 0 0 0 0; - 2//3 -4//3 1//3 0 0 0; - 6//11 -18//11 9//11 -2//11 0 0; - 12//25 -48//25 36//25 -16//25 3//25 0; - 60//137 -300//137 300//137 -200//137 75//137 -12//137] - ts = Vector{typeof(t)}(undef, max_order + 2) #ts is the successful past points, it will be updated after successful step - u_history = Matrix{eltype(u)}(undef, length(u), max_order + 2) - order = 1 - prev_order = 1 - u_corrector = similar(u_history) - recursivefill!(ts, zero(t)) - recursivefill!(u_corrector, zero(eltype(u))) - recursivefill!(u_history, zero(eltype(u_history))) - terkm2 = tTypeNoUnits(1) - terkm1 = tTypeNoUnits(1) - terk = tTypeNoUnits(1) - terkp1 = tTypeNoUnits(1) - terk_tmp = similar(u) - terkp1_tmp = similar(u) - r = Vector{typeof(t)}(undef, max_order + 2) - weights = Vector{typeof(t)}(undef, max_order + 2) - recursivefill!(r, zero(t)) - recursivefill!(weights, zero(t)) - weights[1] = 1 - nconsteps = 0 - consfailcnt = 0 - t_old = zero(t) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, zero(uEltypeNoUnits)) - u₀ = similar(u) - equi_ts = similar(ts) - tmp = similar(u) - ts_tmp = similar(ts) - iters_from_event = 0 - - DFBDFCache(fsalfirst, nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, - u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, - terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, - iters_from_event) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl deleted file mode 100644 index 4b4eab7e71..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl +++ /dev/null @@ -1,460 +0,0 @@ -function initialize!(integrator, cache::DImplicitEulerConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.k[1] = integrator.du -end - -function initialize!(integrator, cache::DImplicitEulerCache) - integrator.kshortsize = 2 - @unpack k₁, k₂ = cache - resize!(integrator.k, integrator.kshortsize) - integrator.k .= [k₁, k₂] - integrator.k[1] .= integrator.du - nothing -end - -@muladd function perform_step!(integrator, cache::DImplicitEulerConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack nlsolver = cache - - nlsolver.z = zero(u) - nlsolver.tmp = zero(u) - nlsolver.γ = 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = uprev + z - - if integrator.opts.adaptive && integrator.success_iter > 0 - # local truncation error (LTE) bound by dt^2/2*max|y''(t)| - # use 2nd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s - - tmp = r * - integrator.opts.internalnorm.((u - uprev) / dt1 - (uprev - uprev2) / dt2, t) - atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - else - integrator.EEst = 1 - end - - integrator.u = u - integrator.du = (u - uprev) / dt - - if integrator.opts.calck - integrator.k[2] = integrator.k[1] - integrator.k[1] = integrator.du - end -end - -@muladd function perform_step!(integrator, cache::DImplicitEulerCache, repeat_step = false) - @unpack t, dt, uprev, du, u, f, p = integrator - @unpack atmp, nlsolver = cache - @unpack tmp = nlsolver - - @. nlsolver.z = false - @. nlsolver.tmp = false - nlsolver.γ = 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=uprev + z - @.. broadcast=false du=z * inv(dt) - - if integrator.opts.adaptive && integrator.success_iter > 0 - # local truncation error (LTE) bound by dt^2/2*max|y''(t)| - # use 2nd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s - - @.. broadcast=false tmp=r * integrator.opts.internalnorm( - (u - uprev) / dt1 - - (uprev - uprev2) / dt2, t) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - else - integrator.EEst = 1 - end - - if integrator.opts.calck - integrator.k[2] .= integrator.k[1] - integrator.k[1] .= du - end -end - -function initialize!(integrator, cache::DABDF2ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.k[1] = integrator.du -end - -@muladd function perform_step!(integrator, cache::DABDF2ConstantCache, repeat_step = false) - @unpack t, f, p = integrator - @unpack dtₙ₋₁, nlsolver = cache - dtₙ, uₙ, uₙ₋₁, uₙ₋₂ = integrator.dt, integrator.u, integrator.uprev, integrator.uprev2 - - if integrator.iter == 1 && !integrator.u_modified - cache.dtₙ₋₁ = dtₙ - perform_step!(integrator, cache.eulercache, repeat_step) - integrator.fsalfirst = @.. broadcast=false (integrator.u - integrator.uprev)/dtₙ - cache.fsalfirstprev = integrator.fsalfirst - return - end - - # precalculations - ρ = dtₙ / dtₙ₋₁ - c1 = ρ^2 / (1 + 2ρ) - - nlsolver.γ = (1 + ρ) / (1 + 2ρ) - nlsolver.α = 1 // 1 - - nlsolver.z = zero(uₙ) - - nlsolver.tmp = -c1 * uₙ₋₁ + c1 * uₙ₋₂ - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - uₙ = uₙ₋₁ + z - integrator.fsallast = @.. broadcast=false z/dtₙ - - if integrator.opts.adaptive - tmp = integrator.fsallast - (1 + dtₙ / dtₙ₋₁) * integrator.fsalfirst + - (dtₙ / dtₙ₋₁) * cache.fsalfirstprev - est = (dtₙ₋₁ + dtₙ) / 6 * tmp - atmp = calculate_residuals(est, uₙ₋₁, uₙ, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - ################################### Finalize - - if integrator.EEst < one(integrator.EEst) - cache.fsalfirstprev = integrator.fsalfirst - cache.dtₙ₋₁ = dtₙ - end - - integrator.u = uₙ - integrator.du = du = (nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dtₙ) - - if integrator.opts.calck - integrator.k[2] = integrator.k[1] - integrator.k[1] = integrator.du - end - return -end - -function initialize!(integrator, cache::DABDF2Cache) - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - - integrator.kshortsize = 2 - @unpack k₁, k₂ = cache.eulercache - resize!(integrator.k, integrator.kshortsize) - integrator.k .= [k₁, k₂] - integrator.k[1] .= integrator.du - nothing -end - -@muladd function perform_step!(integrator, cache::DABDF2Cache, repeat_step = false) - @unpack t, dt, du, f, p = integrator - @unpack atmp, dtₙ₋₁, nlsolver = cache - @unpack z, tmp = nlsolver - uₙ, uₙ₋₁, uₙ₋₂, dtₙ = integrator.u, integrator.uprev, integrator.uprev2, integrator.dt - - if integrator.iter == 1 && !integrator.u_modified - cache.dtₙ₋₁ = dtₙ - perform_step!(integrator, cache.eulercache, repeat_step) - @.. broadcast=false integrator.fsalfirst=(uₙ - uₙ₋₁) / dt - cache.fsalfirstprev .= integrator.fsalfirst - return - end - - # precalculations - ρ = dtₙ / dtₙ₋₁ - c1 = ρ^2 / (1 + 2ρ) - - nlsolver.γ = (1 + ρ) / (1 + 2ρ) - nlsolver.α = 1 // 1 - @.. broadcast=false nlsolver.tmp=-c1 * uₙ₋₁ + c1 * uₙ₋₂ - nlsolver.z .= zero(eltype(z)) - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false uₙ=uₙ₋₁ + z - @.. broadcast=false du=(nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dt) - - @.. broadcast=false integrator.fsallast=du - integrator.stats.nf += 1 - if integrator.opts.adaptive - btilde0 = (dtₙ₋₁ + dtₙ) * 1 // 6 - btilde1 = 1 + ρ - btilde2 = ρ - @.. broadcast=false tmp=btilde0 * - (integrator.fsallast - btilde1 * integrator.fsalfirst + - btilde2 * cache.fsalfirstprev) - calculate_residuals!(atmp, tmp, uₙ₋₁, uₙ, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - ################################### Finalize - - if integrator.EEst < one(integrator.EEst) - @.. broadcast=false cache.fsalfirstprev=integrator.fsalfirst - cache.dtₙ₋₁ = dtₙ - end - return -end - -function initialize!(integrator, cache::DFBDFConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.du, integrator.uprev, integrator.p, - integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::DFBDFConstantCache{max_order}, - repeat_step = false) where {max_order} - @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, ts_tmp, iters_from_event, nconsteps = cache - @unpack t, dt, u, f, p, uprev = integrator - - k = order - reinitFBDF!(integrator, cache) - cache.u₀ = zero(u) - if iters_from_event >= 1 - cache.u₀ = calc_Lagrange_interp(k, weights, t + dt, ts, u_history, cache.u₀) - else - cache.u₀ = u - end - markfirststage!(nlsolver) - equi_ts = zeros(k - 1) - for i in 1:(k - 1) - equi_ts[i] = t - dt * i - end - - fill!(u_corrector, zero(eltype(u))) - if u isa Number - for i in 1:(k - 1) - u_corrector[i] = calc_Lagrange_interp(k, weights, equi_ts[i], ts, u_history, - u_corrector[i]) - end - tmp = uprev * bdf_coeffs[k, 2] - for i in 1:(k - 1) - tmp += u_corrector[i] * bdf_coeffs[k, i + 2] - end - else - for i in 1:(k - 1) - @.. broadcast=false @views u_corrector[:, i] = $calc_Lagrange_interp( - k, weights, - equi_ts[i], - ts, - u_history, - u_corrector[:, - i]) - end - tmp = uprev * bdf_coeffs[k, 2] - vc = _vec(tmp) - for i in 1:(k - 1) - vc += @.. broadcast=false u_corrector[:, i]*bdf_coeffs[k, i + 2] - end - tmp = reshape(vc, size(tmp)) - end - - nlsolver.tmp = tmp + cache.u₀ - nlsolver.z = zero(nlsolver.z) - nlsolver.γ = bdf_coeffs[k, 1] - nlsolver.α = 1 // 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = z + cache.u₀ - - for j in 2:k - r[j] = (1 - j) - for i in 2:(k + 1) - r[j] *= ((t + dt - j * dt) - ts[i]) / (i * dt) - end - end - - terkp1 = z - for j in 1:(k + 1) - terkp1 *= j * dt / (t + dt - ts[j]) - end - - lte = -1 / (1 + k) - for j in 2:k - lte -= (bdf_coeffs[k, j] // bdf_coeffs[k, 1]) * r[j] - end - lte *= terkp1 - - if integrator.opts.adaptive - for i in 1:(k + 1) - ts_tmp[i + 1] = ts[i] - end - ts_tmp[1] = t + dt - atmp = calculate_residuals(_vec(lte), _vec(uprev), _vec(u), integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - - terk = estimate_terk(integrator, cache, k + 1, Val(max_order), u) - atmp = calculate_residuals( - _vec(terk), _vec(uprev), _vec(u), integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - cache.terk = integrator.opts.internalnorm(atmp, t) - - if k > 1 - terkm1 = estimate_terk(integrator, cache, k, Val(max_order), u) - atmp = calculate_residuals(_vec(terkm1), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm1 = integrator.opts.internalnorm(atmp, t) - end - if k > 2 - terkm2 = estimate_terk(integrator, cache, k - 1, Val(max_order), u) - atmp = calculate_residuals(_vec(terkm2), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm2 = integrator.opts.internalnorm(atmp, t) - end - if nconsteps > k + 1 && k < max_order - atmp = calculate_residuals(_vec(terkp1), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkp1 = integrator.opts.internalnorm(atmp, t) - else - cache.terkp1 = zero(cache.terk) - end - end - integrator.u = u - integrator.fsallast = integrator.du = (nlsolver.α * z + nlsolver.tmp) * - inv(nlsolver.γ * dt) -end - -function initialize!(integrator, cache::DFBDFCache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - #integrator.f(integrator.fsalfirst, integrator.du, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - #integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::DFBDFCache{max_order}, - repeat_step = false) where {max_order} - @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, terk_tmp, terkp1_tmp, atmp, tmp, equi_ts, u₀, ts_tmp = cache - @unpack t, dt, u, f, p, uprev = integrator - - reinitFBDF!(integrator, cache) - k = order - @.. broadcast=false u₀=zero(u) - if cache.iters_from_event >= 1 - calc_Lagrange_interp!(k, weights, t + dt, ts, u_history, u₀) - else - @.. broadcast=false u₀=u - end - markfirststage!(nlsolver) - - for i in 1:(k - 1) - equi_ts[i] = t - dt * i - end - - fill!(u_corrector, zero(eltype(u))) - for i in 1:(k - 1) - @views calc_Lagrange_interp!(k, weights, equi_ts[i], ts, u_history, - u_corrector[:, i]) - end - - @.. broadcast=false tmp=uprev * bdf_coeffs[k, 2] - vc = _vec(tmp) - for i in 1:(k - 1) - @.. broadcast=false @views vc += u_corrector[:, i] * bdf_coeffs[k, i + 2] - end - - @.. broadcast=false nlsolver.tmp=tmp + u₀ - @.. broadcast=false nlsolver.z=zero(eltype(nlsolver.z)) - nlsolver.γ = bdf_coeffs[k, 1] - nlsolver.α = 1 // 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=z + u₀ - - for j in 2:k - r[j] = (1 - j) - for i in 2:(k + 1) - r[j] *= ((t + dt - j * dt) - ts[i]) / (i * dt) - end - end - - @.. broadcast=false terkp1_tmp=z - for j in 1:(k + 1) - @.. broadcast=false terkp1_tmp*=j * dt / (t + dt - ts[j]) - end - - lte = -1 / (1 + k) - for j in 2:k - lte -= (bdf_coeffs[k, j] // bdf_coeffs[k, 1]) * r[j] - end - @.. broadcast=false terk_tmp=lte * terkp1_tmp - if integrator.opts.adaptive - @unpack abstol, reltol, internalnorm = integrator.opts - for i in 1:(k + 1) - ts_tmp[i + 1] = ts[i] - end - ts_tmp[1] = t + dt - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, - internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - estimate_terk!(integrator, cache, k + 1, Val(max_order)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, - internalnorm, t) - cache.terk = integrator.opts.internalnorm(atmp, t) - - if k > 1 - estimate_terk!(integrator, cache, k, Val(max_order)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm1 = integrator.opts.internalnorm(atmp, t) - end - if k > 2 - estimate_terk!(integrator, cache, k - 1, Val(max_order)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm2 = integrator.opts.internalnorm(atmp, t) - end - if cache.nconsteps > k + 1 && k < max_order - calculate_residuals!(atmp, _vec(terkp1_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkp1 = integrator.opts.internalnorm(atmp, t) - else - cache.terkp1 = zero(cache.terkp1) - end - end - @.. broadcast=false integrator.fsallast=integrator.du = (nlsolver.α * z + - nlsolver.tmp) * - inv(nlsolver.γ * dt) #TODO Lorenz plot seems not smooth -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl deleted file mode 100644 index 398aa310be..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl +++ /dev/null @@ -1,60 +0,0 @@ -using OrdinaryDiffEq, LinearAlgebra, ForwardDiff, Test - -function rober(du, u, p, t) - y₁, y₂, y₃ = u - k₁, k₂, k₃ = p - du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ - du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du[3] = y₁ + y₂ + y₃ - 1 - nothing -end -function rober(u, p, t) - y₁, y₂, y₃ = u - k₁, k₂, k₃ = p - [-k₁ * y₁ + k₃ * y₂ * y₃, - k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2, - y₁ + y₂ + y₃ - 1] -end -M = [1.0 0 0 - 0 1.0 0 - 0 0 0] -roberf = ODEFunction(rober, mass_matrix = M) -roberf_oop = ODEFunction{false}(rober, mass_matrix = M) -prob_mm = ODEProblem(roberf, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) -prob_mm_oop = ODEProblem(roberf_oop, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rodas5P(), reltol = 1e-8, abstol = 1e-8) -sol = solve(prob_mm_oop, Rodas5P(), reltol = 1e-8, abstol = 1e-8) - -function f(out, du, u, p, t) - out[1] = -p[1] * u[1] + p[3] * u[2] * u[3] - du[1] - out[2] = +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2] - out[3] = u[1] + u[2] + u[3] - 1.0 -end -function f(du, u, p, t) - [-p[1] * u[1] + p[3] * u[2] * u[3] - du[1], - +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2], - u[1] + u[2] + u[3] - 1.0] -end -p = [0.04, 3e7, 1e4] -u₀ = [1.0, 0, 0] -du₀ = [-0.04, 0.04, 0.0] -tspan = (0.0, 100000.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) -prob_oop = DAEProblem{false}(f, du₀, u₀, tspan, p, differential_vars = differential_vars) -sol1 = solve(prob, DFBDF(), dt = 1e-5, abstol = 1e-8, reltol = 1e-8) - -# These tests flex differentiation of the solver and through the initialization -# To only test the solver part and isolate potential issues, set the initialization to consistent -@testset "Inplace: $(isinplace(_prob)), DAEProblem: $(_prob isa DAEProblem), BrownBasic: $(initalg isa BrownFullBasicInit), Autodiff: $autodiff" for _prob in [ - prob, prob_mm, prob_oop, prob_mm_oop], - initalg in [BrownFullBasicInit(), ShampineCollocationInit()], autodiff in [true, false] - - alg = _prob isa DAEProblem ? DFBDF(; autodiff) : Rodas5P(; autodiff) - function f(p) - sol = solve(remake(_prob, p = p), alg, abstol = 1e-14, - reltol = 1e-14, initializealg = initalg) - sum(sol) - end - @test ForwardDiff.gradient(f, [0.04, 3e7, 1e4])≈[0, 0, 0] atol=1e-8 -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl deleted file mode 100644 index e3ef2dd474..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl +++ /dev/null @@ -1,56 +0,0 @@ -using OrdinaryDiffEq, DiffEqDevTools -using Test, Random -Random.seed!(100) - -dts = 1 .// 2 .^ (9:-1:5) -testTol = 0.2 - -f_dae_linear = (res, du, u, p, t) -> (@. res = du - u) -f_dae_linear_analytic = (du0, u0, p, t) -> @. u0 * exp(t) -prob_dae_linear_iip = DAEProblem( - DAEFunction(f_dae_linear; - analytic = f_dae_linear_analytic), - [1.0, 1.0], [1.0, 1.0], (0.0, 1.0)) - -@testset "DAE Solver Convergence Tests (in-place)" begin - prob = prob_dae_linear_iip - - sim11 = test_convergence(dts, prob, DImplicitEuler()) - @test sim11.𝒪est[:final]≈1 atol=testTol - - sim12 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) - @test sim12.𝒪est[:final]≈1 atol=testTol - - sim13 = test_convergence(dts, prob, DABDF2()) - @test sim13.𝒪est[:final]≈2 atol=testTol - - sim14 = test_convergence(dts, prob, DABDF2(; autodiff = false)) - @test sim14.𝒪est[:final]≈2 atol=testTol - - @test_nowarn solve(prob, DFBDF()) -end - -f_dae_linear = (du, u, p, t) -> (@. du - u) -f_dae_linear_analytic = (du0, u0, p, t) -> @. u0 * exp(t) -prob_dae_linear_oop = DAEProblem( - DAEFunction(f_dae_linear; - analytic = f_dae_linear_analytic), - 1.0, 1.0, (0.0, 1.0)) - -@testset "DAE Solver Convergence Tests (out-of-place)" begin - prob = prob_dae_linear_oop - - sim21 = test_convergence(dts, prob, DImplicitEuler()) - @test sim21.𝒪est[:final]≈1 atol=testTol - - sim22 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) - @test sim22.𝒪est[:final]≈1 atol=testTol - - sim23 = test_convergence(dts, prob, DABDF2()) - @test sim23.𝒪est[:final]≈2 atol=testTol - - sim24 = test_convergence(dts, prob, DABDF2(; autodiff = false)) - @test sim24.𝒪est[:final]≈2 atol=testTol - - @test_nowarn solve(prob, DFBDF()) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_event.jl b/lib/OrdinaryDiffEqDAE/test/dae_event.jl deleted file mode 100644 index c20b600670..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_event.jl +++ /dev/null @@ -1,30 +0,0 @@ -using OrdinaryDiffEq, Test - -f = function (out, du, u, p, t) - out[1] = -p[1] * u[1] + p[3] * u[2] * u[3] - du[1] - out[2] = +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2] - out[3] = u[1] + u[2] + u[3] - p[4] -end -u₀ = [1.0, 0, 0] -du₀ = [0.0, 0.0, 0.0] -p = [0.04, 3.0e7, 1.0e4, 1.0] -tspan = (0.0, 100.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) -condition(u, t, integrator) = t in [50.0] -affect!(integrator) = integrator.p[4] = 2.0 -cb = DiscreteCallback(condition, affect!) - -#= -# Regression test -using Sundials -sol = solve(prob, IDA(), callback=cb, tstops=[50.0],abstol=1e-14,reltol=1e-14) -=# - -p = [0.04, 3.0e7, 1.0e4, 1.0] -prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) -sol = solve(prob, DFBDF(), callback = cb, tstops = [50.0], abstol = 1e-12, reltol = 1e-12) -@test sol.t[end] == 100.0 -@test sol[end][1]≈0.686300529575259 atol=1e-7 -@test sol[end][2]≈2.0797982209353813e-6 atol=1e-7 -@test sol[end][3]≈1.31369739062652 atol=1e-7 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl deleted file mode 100644 index 5cf37c27f4..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl +++ /dev/null @@ -1,268 +0,0 @@ -using OrdinaryDiffEq, StaticArrays, LinearAlgebra, Test - -## Mass Matrix - -function rober_oop(u, p, t) - y₁, y₂, y₃ = u - k₁, k₂, k₃ = p - du1 = -k₁ * y₁ + k₃ * y₂ * y₃ - du2 = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du3 = y₁ + y₂ + y₃ - 1 - [du1, du2, du3] -end -M = [1.0 0 0 - 0 1.0 0 - 0 0 0] -f_oop = ODEFunction(rober_oop, mass_matrix = M) -prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rosenbrock23(autodiff = false), reltol = 1e-8, abstol = 1e-8) -@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! -sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8, - initializealg = ShampineCollocationInit()) -@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! - -prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8) -@test sum(sol[1]) ≈ 1 -@test sol[1] ≈ [1.0, 0.0, 0.0] -for alg in [Rosenbrock23(autodiff = false), Trapezoid()] - local sol - sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, - initializealg = ShampineCollocationInit()) - @test sum(sol[1]) ≈ 1 -end - -function rober(du, u, p, t) - y₁, y₂, y₃ = u - k₁, k₂, k₃ = p - du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ - du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du[3] = y₁ + y₂ + y₃ - 1 - nothing -end -M = [1.0 0 0 - 0 1.0 0 - 0 0 0] -f = ODEFunction(rober, mass_matrix = M) -prob_mm = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rodas5(autodiff = false), reltol = 1e-8, abstol = 1e-8) -@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! -sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8, - initializealg = ShampineCollocationInit()) -@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! - -prob_mm = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8) -@test sum(sol[1]) ≈ 1 -@test sol[1] ≈ [1.0, 0.0, 0.0] - -for alg in [Rodas5(autodiff = false), Trapezoid()] - local sol - sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, - initializealg = ShampineCollocationInit()) - @test sum(sol[1]) ≈ 1 -end - -function rober_no_p(du, u, p, t) - y₁, y₂, y₃ = u - (k₁, k₂, k₃) = (0.04, 3e7, 1e4) - du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ - du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du[3] = y₁ + y₂ + y₃ - 1 - nothing -end - -function rober_oop_no_p(du, u, p, t) - y₁, y₂, y₃ = u - (k₁, k₂, k₃) = (0.04, 3e7, 1e4) - du1 = -k₁ * y₁ + k₃ * y₂ * y₃ - du2 = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du3 = y₁ + y₂ + y₃ - 1 - [du1, du2, du3] -end - -# test oop and iip ODE initialization with parameters without eltype/length -struct UnusedParam -end -for f in ( - ODEFunction(rober_no_p, mass_matrix = M), ODEFunction(rober_oop_no_p, mass_matrix = M)) - local prob, probp - prob = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5)) - probp = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5), UnusedParam) - for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) - isapprox(init(prob, Rodas5(), abstol = 1e-10; initializealg).u, - init(prob, Rodas5(), abstol = 1e-10; initializealg).u) - end -end - -## DAEProblem - -f = function (du, u, p, t) - out1 = -0.04u[1] + 1e4 * u[2] * u[3] - du[1] - out2 = +0.04u[1] - 3e7 * u[2]^2 - 1e4 * u[2] * u[3] - du[2] - out3 = u[1] + u[2] + u[3] - 1.0 - [out1, out2, out3] -end - -u₀ = [1.0, 0, 0] -du₀ = [0.0, 0.0, 0.0] -tspan = (0.0, 100000.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -integrator = init(prob, DImplicitEuler()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -integrator = init(prob, DFBDF()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -u₀ = [1.0, 0, 0.2] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) -@test integrator.u≈[1.0, 0, 0.0] atol=1e-9 -integrator = init(prob, DABDF2(), initializealg = ShampineCollocationInit()) -@test !(integrator.u ≈ [1.0, 0, 0.0]) - -u₀ = [1.0, 0, 0.2] -prob = DAEProblem(f, du₀, u₀, tspan) -integrator = init(prob, DABDF2()) -@test !(integrator.u ≈ [1.0, 0, 0.0]) - -f = function (out, du, u, p, t) - out[1] = -0.04u[1] + 1e4 * u[2] * u[3] - du[1] - out[2] = +0.04u[1] - 3e7 * u[2]^2 - 1e4 * u[2] * u[3] - du[2] - out[3] = u[1] + u[2] + u[3] - 1.0 -end - -u₀ = [1.0, 0, 0] -du₀ = [0.0, 0.0, 0.0] -tspan = (0.0, 100000.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) -integrator2 = init(prob, DABDF2(autodiff = false)) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -@test integrator2.du[1]≈-0.04 atol=1e-99 -@test integrator2.du[2]≈0.04 atol=1e-9 -@test integrator2.u≈u₀ atol=1e-9 - -integrator = init(prob, DImplicitEuler()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -integrator = init(prob, DFBDF()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -u₀ = [1.0, 0, 0.2] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) -@test integrator.u≈[1.0, 0, 0.0] atol=1e-9 -integrator = init(prob, DABDF2(), initializealg = ShampineCollocationInit()) -@test !(integrator.u ≈ [1.0, 0, 0.0]) - -u₀ = [1.0, 0, 0.2] -prob = DAEProblem(f, du₀, u₀, tspan) -integrator = init(prob, DABDF2()) -@test !(integrator.u ≈ [1.0, 0, 0.0]) - -# Need to be able to find the consistent solution of this problem, broken right now -# analytical solution: -# u[1](t) -> cos(t) -# u[2](t) -> -sin(t) -# u[3](t) -> 2cos(t) -f = function (out, du, u, p, t) - out[1] = du[1] - u[2] - out[2] = du[2] + u[3] - cos(t) - out[3] = u[1] - cos(t) -end - -u₀ = [1.0, 0.0, 0.0] -du₀ = [0.0, 0.0, 0.0] -tspan = (0.0, 1.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2(); initializealg = ShampineCollocationInit()) - -@test integrator.du[1]≈0.0 atol=1e-9 -@test_broken integrator.du[2]≈-1.0 atol=1e-9 -@test_broken integrator.u[3]≈2.0 atol=1e-9 - -# test iip dae initialization with parameters without eltype/length -probp = DAEProblem(f, du₀, u₀, tspan, UnusedParam(), differential_vars = differential_vars) -for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) - @test isapprox( - init(probp, DABDF2(); initializealg).u, init(prob, DABDF2(); initializealg).u) -end - -f = function (du, u, p, t) - du - u -end - -u₀ = SVector(1.0) -du₀ = SVector(0.0) -tspan = (0.0, 1.0) -differential_vars = SVector(true) -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) - -@test integrator.du≈[1.0] atol=1e-9 - -f = function (du, u, p, t) - du .- u -end - -u₀ = SA[1.0, 1.0] -du₀ = SA[0.0, 0.0] -tspan = (0.0, 1.0) -differential_vars = [true, true] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) - -@test integrator.du[1]≈1.0 atol=1e-9 -@test integrator.du[2]≈1.0 atol=1e-9 -# test oop DAE initialization with parameters without eltype/length -probp = DAEProblem(f, du₀, u₀, tspan, UnusedParam(), differential_vars = differential_vars) -for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) - @test isapprox( - init(probp, DABDF2(); initializealg).u, init(prob, DABDF2(); initializealg).u) -end - -# to test that we get the right NL solve we need a broken solver. -struct BrokenNLSolve <: SciMLBase.AbstractNonlinearAlgorithm - BrokenNLSolve(; kwargs...) = new() -end -function SciMLBase.__solve(prob::NonlinearProblem, - alg::BrokenNLSolve, args...; - kwargs...) - u = fill(reinterpret(Float64, 0xDEADBEEFDEADBEEF), 3) - SciMLBase.build_solution(prob, alg, u, copy(u); - retcode = ReturnCode.Success) -end -function f2(u, p, t) - u -end -f = ODEFunction(f2, mass_matrix = Diagonal([1.0, 1.0, 0.0])) -prob = ODEProblem(f, ones(3), (0.0, 1.0)) -integrator = init(prob, Rodas5P(), - initializealg = ShampineCollocationInit(1.0, BrokenNLSolve())) -@test all(isequal(reinterpret(Float64, 0xDEADBEEFDEADBEEF)), integrator.u) \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl deleted file mode 100644 index 33913925e2..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl +++ /dev/null @@ -1,78 +0,0 @@ -using ModelingToolkit, OrdinaryDiffEq, Test - -@parameters t g e b -@variables v(t) w(t) F(t) -@derivatives D' ~ t -single_neuron_eqs = [ - D(v) ~ min(max(-2 - v, v), 2 - v) - w + F, # add the flux term - D(w) ~ e * (v - g * w + b) -] -n1 = ODESystem(single_neuron_eqs, t, [v, w, F], [g, e, b], name = :n1) -n2 = ODESystem(single_neuron_eqs, t, [v, w, F], [g, e, b], name = :n2) -@parameters D Dk -connections = [0 ~ n1.F - D * Dk * max(n1.v - n2.v, 0) - 0 ~ n2.F - D * max(n2.v - n1.v, 0)] -connected = ODESystem(connections, t, [], [D, Dk], systems = [n1, n2], name = :connected) -connected = complete(connected) - -u0 = [ - n1.v => -2, - n1.w => -2 / 3, - n1.F => 0, - n2.v => -2, - n2.w => -0.7, - n2.F => 0 -] -tspan = (0.0, 1750.0) -p0 = [ - n1.g => 0.8, - n1.e => 0.04, - n1.b => 0, - n2.g => 0.8, - n2.e => 0.04, - n2.b => 0.2, - D => 0.047, - Dk => 1 -] - -prob = ODEProblem(connected, u0, tspan, p0) -sol = solve(prob, Rodas5(), initializealg = BrownFullBasicInit()) -@test prob.u0 == sol[1] -sol = solve(prob, Rodas5(), initializealg = ShampineCollocationInit()) -@test prob.u0 == sol[1] -#test initialization when given a specific nonlinear solver -using NonlinearSolve -sol = solve(prob, Rodas5(), initializealg = BrownFullBasicInit(1e-10, RobustMultiNewton())) -@test prob.u0 == sol[1] - -# Initialize on ODEs -# https://github.com/SciML/ModelingToolkit.jl/issues/2508 - -function testsys(du, u, p, t) - du[1] = -2 -end -function initsys(du, u, p) - du[1] = -1 + u[1] -end -nlprob = NonlinearProblem(initsys, [0.0]) -initprobmap(nlprob) = nlprob.u -sol = solve(nlprob) - -_f = ODEFunction(testsys; initializeprob = nlprob, initializeprobmap = initprobmap) -prob = ODEProblem(_f, [0.0], (0.0, 1.0)) -sol = solve(prob, Tsit5()) -@test SciMLBase.successful_retcode(sol) -@test sol[1] == [1.0] - -prob = ODEProblem(_f, [0.0], (0.0, 1.0)) -sol = solve(prob, Tsit5(), dt = 1e-10) -@test SciMLBase.successful_retcode(sol) -@test sol[1] == [1.0] -@test sol[2] ≈ [0.9999999998] -@test sol[end] ≈ [-1.0] - -sol = solve(prob, Rodas5P(), dt = 1e-10) -@test SciMLBase.successful_retcode(sol) -@test sol[1] == [1.0] -@test sol[2] ≈ [0.9999999998] -@test sol[end] ≈ [-1.0] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/hard_dae.jl b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl deleted file mode 100644 index f47b226ce1..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/hard_dae.jl +++ /dev/null @@ -1,275 +0,0 @@ -using OrdinaryDiffEq -using LinearAlgebra -using NLsolve -using Test - -p_inv = [500.0 - 0.084 - 4.69 - 2.0 - 400.0 - 20.0 - 0.2 - 1000.0 - 0.59 - 736.0 - 0.0 - 0.0 - 0.2 - 1.27 - 14.3 - 0.0 - 50.0 - 0.2 - 0.08 - 0.003 - 0.074 - 0.2 - 0.01 # Matt - 1.0 # V_ref - 1.0 # ω ref - 0.7 # Pref - 0 # Q_ref - 0.5 #Xtrans - 0.0 # Rtrans - 1.01 #Vm - 0.0] # Vθ - -function vsm(dx, x, p, t) - #PARAMETERS - ω_lp = p[1] - kp_pll = p[2] - ki_pll = p[3] - Ta = p[4] - kd = p[5] - kω = p[6] - kq = p[7] - ωf = p[8] - kpv = p[9] - kiv = p[10] - kffv = p[11] - rv = p[12] - lv = p[13] - kpc = p[14] - kic = p[15] - kffi = p[16] - ωad = p[17] - kad = p[18] - lf = p[19] - rf = p[20] - cf = p[21] - lg = p[22] - rg = p[23] - Vref = p[24] - ωref = p[25] - Pref = p[26] - Qref = p[27] - Xtrans = p[28] - Rtrans = p[29] - Vm = p[30] - Vθ = p[31] - - #STATE INDEX AND STATES - i__vi_filter, vi_filter = 1, x[1] - i__γd_ic, γd_ic = 2, x[2] - i__vq_pll, vq_pll = 3, x[3] - i__γq_ic, γq_ic = 4, x[4] - i__ir_filter, ir_filter = 5, x[5] - i__ξd_ic, ξd_ic = 6, x[6] - i__ϕd_ic, ϕd_ic = 7, x[7] - i__ε_pll, ε_pll = 8, x[8] - i__ir_cnv, ir_cnv = 9, x[9] - i__vr_filter, vr_filter = 10, x[10] - i__ω_oc, ω_oc = 11, x[11] - i__ξq_ic, ξq_ic = 12, x[12] - i__vd_pll, vd_pll = 13, x[13] - i__q_oc, q_oc = 14, x[14] - i__ϕq_ic, ϕq_ic = 15, x[15] - i__θ_pll, θ_pll = 16, x[16] - i__θ_oc, θ_oc = 17, x[17] - i__ii_cnv, ii_cnv = 18, x[18] - i__ii_filter, ii_filter = 19, x[19] - i__ir_source, ir_source = 20, x[20] - i__ii_source, ii_source = 21, x[21] - - ω_base = 60.0 * 2 * pi - ω_sys = 1.0 - - #PLL - δω_pll = kp_pll * atan(vq_pll / vd_pll) + ki_pll * ε_pll - ω_pll = δω_pll + ω_sys - vd_filt_pll = sin(θ_pll + pi / 2) * vr_filter - cos(θ_pll + pi / 2) * vi_filter - vq_filt_pll = cos(θ_pll + pi / 2) * vr_filter + sin(θ_pll + pi / 2) * vi_filter - - dx[i__vd_pll] = ω_lp * (vd_filt_pll - vd_pll) #docs:(1a) - dx[i__vq_pll] = ω_lp * (vq_filt_pll - vq_pll) #docs:(1b) - dx[i__ε_pll] = atan(vq_pll / vd_pll) #docs:(1c) - dx[i__θ_pll] = ω_base * δω_pll #docs:(1d) - - #OUTER LOOP CONTROL - pe = vr_filter * ir_filter + vi_filter * ii_filter #docs:(2d) - qe = vi_filter * ir_filter - vr_filter * ii_filter #docs:(2e) - v_ref_olc = Vref + kq * (Qref - q_oc) - - dx[i__ω_oc] = (Pref - pe - kd * (ω_oc - ω_pll) - kω * (ω_oc - ωref)) / Ta #docs:(2a) - dx[i__θ_oc] = ω_base * (ω_oc - ω_sys) #docs:(2b) - dx[i__q_oc] = ωf * (qe - q_oc) #docs:(2c) - - #INNER LOOP CONTROL - #reference transformations - vd_filt_olc = sin(θ_oc + pi / 2) * vr_filter - cos(θ_oc + pi / 2) * vi_filter - vq_filt_olc = cos(θ_oc + pi / 2) * vr_filter + sin(θ_oc + pi / 2) * vi_filter - id_filt_olc = sin(θ_oc + pi / 2) * ir_filter - cos(θ_oc + pi / 2) * ii_filter - iq_filt_olc = cos(θ_oc + pi / 2) * ir_filter + sin(θ_oc + pi / 2) * ii_filter - id_cnv_olc = sin(θ_oc + pi / 2) * ir_cnv - cos(θ_oc + pi / 2) * ii_cnv - iq_cnv_olc = cos(θ_oc + pi / 2) * ir_cnv + sin(θ_oc + pi / 2) * ii_cnv - - #Voltage control equations - Vd_filter_ref = v_ref_olc - rv * id_filt_olc + ω_oc * lv * iq_filt_olc #docs:(3g) - Vq_filter_ref = -rv * iq_filt_olc - ω_oc * lv * id_filt_olc #docs:(3h) - dx[i__ξd_ic] = Vd_filter_ref - vd_filt_olc #docs:(3a) - dx[i__ξq_ic] = Vq_filter_ref - vq_filt_olc #docs:(3b) - - #current control equations - Id_cnv_ref = (kpv * (Vd_filter_ref - vd_filt_olc) + kiv * ξd_ic - #docs:(3i) - cf * ω_oc * vq_filt_olc + kffi * id_filt_olc) - Iq_cnv_ref = (kpv * (Vq_filter_ref - vq_filt_olc) + - kiv * ξq_ic + #docs:(3j) - cf * ω_oc * vd_filt_olc + - kffi * iq_filt_olc) - dx[i__γd_ic] = Id_cnv_ref - id_cnv_olc #docs:(3c) - dx[i__γq_ic] = Iq_cnv_ref - iq_cnv_olc #docs:(3d) - - #active damping equations - Vd_cnv_ref = (kpc * (Id_cnv_ref - id_cnv_olc) + kic * γd_ic - lf * ω_oc * iq_cnv_olc + #docs:(3k) - kffv * vd_filt_olc - kad * (vd_filt_olc - ϕd_ic)) - Vq_cnv_ref = (kpc * (Iq_cnv_ref - iq_cnv_olc) + - kic * γq_ic + - lf * ω_oc * id_cnv_olc + #docs:(3l) - kffv * vq_filt_olc - kad * (vq_filt_olc - ϕq_ic)) - dx[i__ϕd_ic] = ωad * (vd_filt_olc - ϕd_ic) #docs:(3e) - dx[i__ϕq_ic] = ωad * (vq_filt_olc - ϕq_ic) #docs:(3f) - - #LCL FILTER - #reference transformations - Vr_cnv = sin(θ_oc + pi / 2) * Vd_cnv_ref + cos(θ_oc + pi / 2) * Vq_cnv_ref - Vi_cnv = -cos(θ_oc + pi / 2) * Vd_cnv_ref + sin(θ_oc + pi / 2) * Vq_cnv_ref - - Vr_pcc = Vm * cos(Vθ) - Vi_pcc = Vm * sin(Vθ) - - dx[i__ir_cnv] = (ω_base / lf) * #docs:(5a) - (Vr_cnv - vr_filter - rf * ir_cnv + ω_sys * lf * ii_cnv) - dx[i__ii_cnv] = (ω_base / lf) * #docs:(5b) - (Vi_cnv - vi_filter - rf * ii_cnv - ω_sys * lf * ir_cnv) - dx[i__vr_filter] = (ω_base / cf) * #docs:(5c) - (ir_cnv - ir_filter + ω_sys * cf * vi_filter) - dx[i__vi_filter] = (ω_base / cf) * #docs:(5d) - (ii_cnv - ii_filter - ω_sys * cf * vr_filter) - dx[i__ir_filter] = (ω_base / lg) * #docs:(5e) - (vr_filter - Vr_pcc - rg * ir_filter + ω_sys * lg * ii_filter) - dx[i__ii_filter] = +(ω_base / lg) * #docs:(5f) - (vi_filter - Vi_pcc - rg * ii_filter - ω_sys * lg * ir_filter) - - # Network interface algebraic equations 0 = I - YV - line_currents = ((Vr_cnv + Vi_cnv * 1im) - (Vr_pcc + Vi_pcc * 1im)) / - (Rtrans + Xtrans * 1im) - dx[i__ii_source] = ii_source - imag(line_currents) - dx[i__ir_source] = ir_source - real(line_currents) - return -end - -u0 = [0.0, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 1.0, - 1.0, - 0.0, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.0, - 1.0, - 0.0 -] -init_f! = (dx, x) -> vsm(dx, x, p_inv, 0) -res = nlsolve(init_f!, u0) - -M = diagm(ones(21)) -#Last 2 equations are algebraic -M[20, 20] = M[21, 21] = 0.0 - -f = ODEFunction(vsm, mass_matrix = M) - -condition(u, t, integrator) = t == 1.0 -affect!(integrator) = integrator.p[28] += 0.2 -cb = DiscreteCallback(condition, affect!) - -prob = ODEProblem(f, deepcopy(res.zero), (0, 20.0), deepcopy(p_inv)) -refsol = solve(prob, Rodas4(), saveat = 0.1, callback = cb, tstops = [1.0], reltol = 1e-12, - abstol = 1e-17) - -for solver in (Rodas4, Rodas4P, Rodas5, Rodas5P, FBDF, QNDF, Rosenbrock23) - @show solver - prob = ODEProblem(f, deepcopy(res.zero), (0, 20.0), deepcopy(p_inv)) - sol = solve( - prob, solver(), saveat = 0.1, callback = cb, tstops = [1.0], reltol = 1e-14, - abstol = 1e-14) - @test sol.retcode == ReturnCode.Success - @test sol.t[end] == 20.0 - @test maximum(sol - refsol) < 1e-11 -end - -function hardstop!(du, u, p, t) - pm, pg = p - y, f_wall, dy = u - du[1] = dy - du[2] = ifelse(y <= 0, y, f_wall) - du[3] = (-ifelse(t < 2, -pg * pm, pg * pm) - f_wall) / (-pm) -end - -hardstop!(u, p, t) = (du = similar(u); hardstop!(du, u, p, t); du) - -fun = ODEFunction(hardstop!, mass_matrix = Diagonal([1, 0, 1])) -prob1 = ODEProblem(fun, [5, 0, 0.0], (0, 4.0), [100, 10.0]) -prob2 = ODEProblem(fun, [5, 0, 0.0], (0, 4.0), [100, 10.0]) -for prob in [prob1, prob2] - @test solve(prob, ImplicitEuler(), dt = 1 / 2^10, adaptive = false).retcode == - ReturnCode.ConvergenceFailure -end - -condition2 = (u, t, integrator) -> t == 2 -affect2! = integrator -> integrator.u[1] = 1e-6 -cb = DiscreteCallback(condition2, affect2!) - -@isdefined(N_FAILS) || const N_FAILS = Ref(0) -function choice_function(integrator) - integrator.do_error_check = false - if integrator.force_stepfail - N_FAILS[] += 1 - else - N_FAILS[] = 0 - end - - (N_FAILS[] > 3) + 1 -end -simple_implicit_euler = ImplicitEuler(nlsolve = NLNewton(check_div = false, - always_new = true)) -alg_switch = CompositeAlgorithm((ImplicitEuler(), simple_implicit_euler), choice_function) - -for prob in [prob1, prob2], alg in [simple_implicit_euler, alg_switch] - sol = solve(prob, alg, callback = cb, dt = 1 / 2^10, adaptive = false) - @test sol.retcode == ReturnCode.Success - @test sol(0, idxs = 1) == 5 - @test sol(2, idxs = 1) == 0 - @test sol(4, idxs = 1) > 10 -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl deleted file mode 100644 index a639da4027..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/runtest.jl +++ /dev/null @@ -1,2 +0,0 @@ -using SafeTestsets - diff --git a/test/runtests.jl b/test/runtests.jl index fd03660767..1edccc79e5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -147,9 +147,9 @@ end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceV" || GROUP == "Interface") @time @safetestset "Interpolation Derivative Error Tests" include("interface/interpolation_derivative_error_tests.jl") @time @safetestset "AD Tests" include("interface/ad_tests.jl") - @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl") + @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl") @time @safetestset "Newton Tests" include("interface/newton_tests.jl") - @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl") + @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl") end if !is_APPVEYOR && @@ -173,8 +173,8 @@ end @time @safetestset "Reverse Directioned Event Tests" include("integrators/rev_events_tests.jl") @time @safetestset "Differentiation Direction Tests" include("integrators/diffdir_tests.jl") @time @safetestset "Resize Tests" include("integrators/resize_tests.jl") - @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl") - @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_event.jl") + @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl") + @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_event.jl") @time @safetestset "Cache Tests" include("integrators/ode_cache_tests.jl") @time @safetestset "Add Steps Tests" include("integrators/ode_add_steps_tests.jl") @time @safetestset "IMEX Split Function Tests" include("integrators/split_ode_tests.jl") @@ -185,7 +185,7 @@ end @time @safetestset "Special Interp Tests" include("regression/special_interps.jl") @time @safetestset "Inplace Tests" include("regression/ode_inplace_tests.jl") @time @safetestset "Adaptive Tests" include("regression/ode_adaptive_tests.jl") - @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqDAE/test/hard_dae.jl") + @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqBDF/test/hard_dae.jl") end if !is_APPVEYOR && (GROUP == "All" || GROUP == "Regression_II" || GROUP == "Regression") @@ -199,7 +199,7 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_I" @time @safetestset "Partitioned Methods Tests" include("algconvergence/partitioned_methods_tests.jl") @time @safetestset "Convergence Tests" include("algconvergence/ode_convergence_tests.jl") - @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl") + @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl") @time @safetestset "Non-autonomous Convergence Tests" include("algconvergence/non-autonomous_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("algconvergence/adams_tests.jl") @time @safetestset "Nordsieck Tests" include("algconvergence/nordsieck_tests.jl") From 933ad5fee221a822e32c0a91ae983c1b2e853ce2 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Fri, 26 Jul 2024 23:33:54 -0400 Subject: [PATCH 31/45] Update lib/OrdinaryDiffEqBDF/src/algorithms.jl --- lib/OrdinaryDiffEqBDF/src/algorithms.jl | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index 0ed740a489..71900e4925 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -426,19 +426,6 @@ function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = V nlsolve, precs, extrapolant, controller) end -#= -struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, - linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = - DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( - linsolve,nlsolve,precs,extrapolant) -=# struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} max_order::Val{MO} From 1c88338d242015a058ca1338bb1b338bcd877ee3 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 02:03:40 +0530 Subject: [PATCH 32/45] Added DAE solvers --- lib/OrdinaryDiffEqDAE/Project.toml | 20 + .../src/OrdinaryDiffEqDAE.jl | 16 + lib/OrdinaryDiffEqDAE/src/alg_utils.jl | 12 + lib/OrdinaryDiffEqDAE/src/algorithms.jl | 75 +++ lib/OrdinaryDiffEqDAE/src/controllers.jl | 130 +++++ lib/OrdinaryDiffEqDAE/src/dae_caches.jl | 256 ++++++++++ lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl | 460 ++++++++++++++++++ src/OrdinaryDiffEq.jl | 10 + 8 files changed, 979 insertions(+) create mode 100644 lib/OrdinaryDiffEqDAE/Project.toml create mode 100644 lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/algorithms.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/controllers.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/dae_caches.jl create mode 100644 lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml new file mode 100644 index 0000000000..ee3e8c74e7 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/Project.toml @@ -0,0 +1,20 @@ +name = "OrdinaryDiffEqDAE" +uuid = "7d2d7016-1c68-401d-834f-6be2c6dc7d88" +authors = ["ParamThakkar123 "] +version = "1.0.0" + +[deps] +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[compat] +julia = "1.10" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl new file mode 100644 index 0000000000..0be59f3cbf --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -0,0 +1,16 @@ +module OrdinaryDiffEqDAE + +import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, + DEFAULT_PRECS, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache +using TruncatedStacktraces + +include("algorithms.jl") +include("alg_utils.jl") +include("controllers.jl") +include("dae_caches.jl") +include("dae_perform_step.jl") + +export DABDF2, DImplicitEuler, DFBDF + +end # module OrdinaryDiffEqDAE diff --git a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl new file mode 100644 index 0000000000..ff0d60daac --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl @@ -0,0 +1,12 @@ +isadaptive(alg::DImplicitEuler) = true +isadaptive(alg::DABDF2) = true +isadaptive(alg::DFBDF) = true + +alg_extrapolates(alg::DImplicitEuler) = true +alg_extrapolates(alg::DABDF2) = true + +alg_order(alg::DImplicitEuler) = 1 +alg_order(alg::DABDF2) = 2 +alg_order(alg::DFBDF) = 1#dummy value + +isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/algorithms.jl b/lib/OrdinaryDiffEqDAE/src/algorithms.jl new file mode 100644 index 0000000000..f8584348a5 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/algorithms.jl @@ -0,0 +1,75 @@ +struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DImplicitEuler(; + chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :Standard) + DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, precs, extrapolant, controller) +end + +#= +struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, + linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = + DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( + linsolve,nlsolve,precs,extrapolant) +=# + +struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + controller::Symbol +end +function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, controller = :Standard) where {MO} + DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, + controller) +end + +TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/controllers.jl b/lib/OrdinaryDiffEqDAE/src/controllers.jl new file mode 100644 index 0000000000..4ae1a93a28 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/controllers.jl @@ -0,0 +1,130 @@ +function step_reject_controller!(integrator, ::DFBDF) + bdf_step_reject_controller!(integrator, integrator.cache.terkm1) +end + +function post_newton_controller!(integrator, alg) + integrator.dt = integrator.dt / integrator.opts.failfactor + nothing +end + +function post_newton_controller!(integrator, alg::DFBDF) + @unpack cache = integrator + if cache.order > 1 && cache.nlsolver.nfails >= 3 + cache.order -= 1 + end + integrator.dt = integrator.dt / integrator.opts.failfactor + integrator.cache.consfailcnt += 1 + integrator.cache.nconsteps = 0 + nothing +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqMutableCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache + k = cache.order + # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] + end + @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function choose_order!(alg::DFBDF, integrator, + cache::OrdinaryDiffEqConstantCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache + k = cache.order + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + if u isa Number + for i in 2:(k - 2) + terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] + end + terk_tmp *= abs(dt^(k - 2)) + else + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * + u_history[:, i - 1] + end + terk_tmp = reshape(vc, size(terk_tmp)) + terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) + end + atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function stepsize_controller!(integrator, + alg::DFBDF{max_order}) where { + max_order, +} + @unpack cache = integrator + cache.prev_order = cache.order + k, terk = choose_order!(alg, integrator, cache, Val(max_order)) + if k != cache.order + integrator.cache.nconsteps = 0 + cache.order = k + end + if iszero(terk) + q = inv(integrator.opts.qmax) + else + q = ((2 * terk / (k + 1))^(1 / (k + 1))) + end + integrator.qold = q + q +end + +function step_accept_controller!(integrator, alg::DFBDF{max_order}, + q) where {max_order} + integrator.cache.consfailcnt = 0 + if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min + q = one(q) + end + integrator.cache.nconsteps += 1 + integrator.cache.iters_from_event += 1 + return integrator.dt / q +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_caches.jl b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl new file mode 100644 index 0000000000..c432408952 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl @@ -0,0 +1,256 @@ +@cache mutable struct DImplicitEulerCache{uType, rateType, uNoUnitsType, N} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + uprev2::uType + atmp::uNoUnitsType + k₁::rateType + k₂::rateType + nlsolver::N +end + +mutable struct DImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache + nlsolver::N +end + +function alg_cache(alg::DImplicitEuler, du, u, res_prototype, rate_prototype, + ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + α = 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(false)) + + DImplicitEulerConstantCache(nlsolver) +end + +function alg_cache(alg::DImplicitEuler, du, u, res_prototype, rate_prototype, + ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + α = 1 + k₁ = zero(rate_prototype) + k₂ = zero(rate_prototype) + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(true)) + + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + DImplicitEulerCache(u, uprev, uprev2, atmp, k₁, k₂, nlsolver) +end + +@cache mutable struct DABDF2ConstantCache{N, dtType, rate_prototype} <: + OrdinaryDiffEqConstantCache + nlsolver::N + eulercache::DImplicitEulerConstantCache + dtₙ₋₁::dtType + fsalfirstprev::rate_prototype +end + +function alg_cache(alg::DABDF2, du, u, res_prototype, rate_prototype, + ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 1, 1 + α = 1 // 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(false)) + eulercache = DImplicitEulerConstantCache(nlsolver) + + dtₙ₋₁ = one(dt) + fsalfirstprev = rate_prototype + + DABDF2ConstantCache(nlsolver, eulercache, dtₙ₋₁, fsalfirstprev) +end + +@cache mutable struct DABDF2Cache{uType, rateType, uNoUnitsType, N, dtType} <: + OrdinaryDiffEqMutableCache + uₙ::uType + uₙ₋₁::uType + uₙ₋₂::uType + fsalfirst::rateType + fsalfirstprev::rateType + atmp::uNoUnitsType + nlsolver::N + eulercache::DImplicitEulerCache + dtₙ₋₁::dtType +end + +function alg_cache(alg::DABDF2, du, u, res_prototype, rate_prototype, + ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 1, 1 + α = 1 // 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(true)) + fsalfirst = zero(rate_prototype) + + fsalfirstprev = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + k₁ = zero(rate_prototype) + k₂ = zero(rate_prototype) + + eulercache = DImplicitEulerCache(u, uprev, uprev2, atmp, k₁, k₂, nlsolver) + + dtₙ₋₁ = one(dt) + + DABDF2Cache(u, uprev, uprev2, fsalfirst, fsalfirstprev, atmp, + nlsolver, eulercache, dtₙ₋₁) +end + +@cache mutable struct DFBDFConstantCache{MO, N, tsType, tType, uType, uuType, coeffType, + EEstType, rType, wType} <: + OrdinaryDiffEqConstantCache + nlsolver::N + ts::tsType + ts_tmp::tsType + t_old::tType + u_history::uuType + order::Int + prev_order::Int + u₀::uType + u_corrector::uuType + bdf_coeffs::coeffType + max_order::Val{MO} + nconsteps::Int + consfailcnt::Int + terkm2::EEstType + terkm1::EEstType + terk::EEstType + terkp1::EEstType + r::rType + weights::wType + iters_from_event::Int +end + +function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, + uprev, uprev2, f, t, dt, reltol, p, calck, ::Val{false}) where {MO} + γ, c = 1.0, 1.0 + max_order = MO + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + bdf_coeffs = SA[1 -1 0 0 0 0; + 2//3 -4//3 1//3 0 0 0; + 6//11 -18//11 9//11 -2//11 0 0; + 12//25 -48//25 36//25 -16//25 3//25 0; + 60//137 -300//137 300//137 -200//137 75//137 -12//137] + ts = zero(Vector{typeof(t)}(undef, max_order + 2)) #ts is the successful past points, it will be updated after successful step + ts_tmp = similar(ts) + + u_history = zero(Matrix{eltype(u)}(undef, length(u), max_order + 2)) + order = 1 + prev_order = 1 + u_corrector = similar(u_history) + recursivefill!(u_corrector, zero(eltype(u))) + recursivefill!(u_history, zero(eltype(u_history))) + terkm2 = tTypeNoUnits(1) + terkm1 = tTypeNoUnits(1) + terk = tTypeNoUnits(1) + terkp1 = tTypeNoUnits(1) + r = zero(Vector{typeof(t)}(undef, max_order + 2)) + weights = zero(Vector{typeof(t)}(undef, max_order + 2)) + weights[1] = 1 + nconsteps = 0 + consfailcnt = 0 + t_old = zero(t) + iters_from_event = 0 + u₀ = zero(u) + + DFBDFConstantCache(nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, u₀, + u_corrector, bdf_coeffs, Val(5), nconsteps, consfailcnt, terkm2, + terkm1, terk, terkp1, r, weights, iters_from_event) +end + +@cache mutable struct DFBDFCache{MO, N, rateType, uNoUnitsType, tsType, tType, uType, + uuType, coeffType, EEstType, rType, wType} <: + OrdinaryDiffEqMutableCache + fsalfirst::rateType + nlsolver::N + ts::tsType + ts_tmp::tsType + t_old::tType + u_history::uuType + order::Int + prev_order::Int + u_corrector::uuType + u₀::uType + bdf_coeffs::coeffType + max_order::Val{MO} + nconsteps::Int + consfailcnt::Int + tmp::uType + atmp::uNoUnitsType + terkm2::EEstType + terkm1::EEstType + terk::EEstType + terkp1::EEstType + terk_tmp::uType + terkp1_tmp::uType + r::rType + weights::wType + equi_ts::tsType + iters_from_event::Int +end + +function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, + tTypeNoUnits, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {MO} + γ, c = 1.0, 1.0 + fsalfirst = zero(rate_prototype) + max_order = MO + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + #=bdf_coeffs = SA[1 -1 0 0 0 0 ; + 3//2 -2 1//2 0 0 0 ; + 11//6 -3 3//2 -1//3 0 0 ; + 25//12 -4 3 -4//3 1//4 0 ; + 137//60 -5 5 -10//3 5//4 -1//5]=# + bdf_coeffs = SA[1 -1 0 0 0 0; + 2//3 -4//3 1//3 0 0 0; + 6//11 -18//11 9//11 -2//11 0 0; + 12//25 -48//25 36//25 -16//25 3//25 0; + 60//137 -300//137 300//137 -200//137 75//137 -12//137] + ts = Vector{typeof(t)}(undef, max_order + 2) #ts is the successful past points, it will be updated after successful step + u_history = Matrix{eltype(u)}(undef, length(u), max_order + 2) + order = 1 + prev_order = 1 + u_corrector = similar(u_history) + recursivefill!(ts, zero(t)) + recursivefill!(u_corrector, zero(eltype(u))) + recursivefill!(u_history, zero(eltype(u_history))) + terkm2 = tTypeNoUnits(1) + terkm1 = tTypeNoUnits(1) + terk = tTypeNoUnits(1) + terkp1 = tTypeNoUnits(1) + terk_tmp = similar(u) + terkp1_tmp = similar(u) + r = Vector{typeof(t)}(undef, max_order + 2) + weights = Vector{typeof(t)}(undef, max_order + 2) + recursivefill!(r, zero(t)) + recursivefill!(weights, zero(t)) + weights[1] = 1 + nconsteps = 0 + consfailcnt = 0 + t_old = zero(t) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, zero(uEltypeNoUnits)) + u₀ = similar(u) + equi_ts = similar(ts) + tmp = similar(u) + ts_tmp = similar(ts) + iters_from_event = 0 + + DFBDFCache(fsalfirst, nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, + u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, + terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, + iters_from_event) +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl new file mode 100644 index 0000000000..4b4eab7e71 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl @@ -0,0 +1,460 @@ +function initialize!(integrator, cache::DImplicitEulerConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.k[1] = integrator.du +end + +function initialize!(integrator, cache::DImplicitEulerCache) + integrator.kshortsize = 2 + @unpack k₁, k₂ = cache + resize!(integrator.k, integrator.kshortsize) + integrator.k .= [k₁, k₂] + integrator.k[1] .= integrator.du + nothing +end + +@muladd function perform_step!(integrator, cache::DImplicitEulerConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack nlsolver = cache + + nlsolver.z = zero(u) + nlsolver.tmp = zero(u) + nlsolver.γ = 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = uprev + z + + if integrator.opts.adaptive && integrator.success_iter > 0 + # local truncation error (LTE) bound by dt^2/2*max|y''(t)| + # use 2nd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s + + tmp = r * + integrator.opts.internalnorm.((u - uprev) / dt1 - (uprev - uprev2) / dt2, t) + atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + else + integrator.EEst = 1 + end + + integrator.u = u + integrator.du = (u - uprev) / dt + + if integrator.opts.calck + integrator.k[2] = integrator.k[1] + integrator.k[1] = integrator.du + end +end + +@muladd function perform_step!(integrator, cache::DImplicitEulerCache, repeat_step = false) + @unpack t, dt, uprev, du, u, f, p = integrator + @unpack atmp, nlsolver = cache + @unpack tmp = nlsolver + + @. nlsolver.z = false + @. nlsolver.tmp = false + nlsolver.γ = 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=uprev + z + @.. broadcast=false du=z * inv(dt) + + if integrator.opts.adaptive && integrator.success_iter > 0 + # local truncation error (LTE) bound by dt^2/2*max|y''(t)| + # use 2nd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s + + @.. broadcast=false tmp=r * integrator.opts.internalnorm( + (u - uprev) / dt1 - + (uprev - uprev2) / dt2, t) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + else + integrator.EEst = 1 + end + + if integrator.opts.calck + integrator.k[2] .= integrator.k[1] + integrator.k[1] .= du + end +end + +function initialize!(integrator, cache::DABDF2ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.k[1] = integrator.du +end + +@muladd function perform_step!(integrator, cache::DABDF2ConstantCache, repeat_step = false) + @unpack t, f, p = integrator + @unpack dtₙ₋₁, nlsolver = cache + dtₙ, uₙ, uₙ₋₁, uₙ₋₂ = integrator.dt, integrator.u, integrator.uprev, integrator.uprev2 + + if integrator.iter == 1 && !integrator.u_modified + cache.dtₙ₋₁ = dtₙ + perform_step!(integrator, cache.eulercache, repeat_step) + integrator.fsalfirst = @.. broadcast=false (integrator.u - integrator.uprev)/dtₙ + cache.fsalfirstprev = integrator.fsalfirst + return + end + + # precalculations + ρ = dtₙ / dtₙ₋₁ + c1 = ρ^2 / (1 + 2ρ) + + nlsolver.γ = (1 + ρ) / (1 + 2ρ) + nlsolver.α = 1 // 1 + + nlsolver.z = zero(uₙ) + + nlsolver.tmp = -c1 * uₙ₋₁ + c1 * uₙ₋₂ + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + uₙ = uₙ₋₁ + z + integrator.fsallast = @.. broadcast=false z/dtₙ + + if integrator.opts.adaptive + tmp = integrator.fsallast - (1 + dtₙ / dtₙ₋₁) * integrator.fsalfirst + + (dtₙ / dtₙ₋₁) * cache.fsalfirstprev + est = (dtₙ₋₁ + dtₙ) / 6 * tmp + atmp = calculate_residuals(est, uₙ₋₁, uₙ, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + ################################### Finalize + + if integrator.EEst < one(integrator.EEst) + cache.fsalfirstprev = integrator.fsalfirst + cache.dtₙ₋₁ = dtₙ + end + + integrator.u = uₙ + integrator.du = du = (nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dtₙ) + + if integrator.opts.calck + integrator.k[2] = integrator.k[1] + integrator.k[1] = integrator.du + end + return +end + +function initialize!(integrator, cache::DABDF2Cache) + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + + integrator.kshortsize = 2 + @unpack k₁, k₂ = cache.eulercache + resize!(integrator.k, integrator.kshortsize) + integrator.k .= [k₁, k₂] + integrator.k[1] .= integrator.du + nothing +end + +@muladd function perform_step!(integrator, cache::DABDF2Cache, repeat_step = false) + @unpack t, dt, du, f, p = integrator + @unpack atmp, dtₙ₋₁, nlsolver = cache + @unpack z, tmp = nlsolver + uₙ, uₙ₋₁, uₙ₋₂, dtₙ = integrator.u, integrator.uprev, integrator.uprev2, integrator.dt + + if integrator.iter == 1 && !integrator.u_modified + cache.dtₙ₋₁ = dtₙ + perform_step!(integrator, cache.eulercache, repeat_step) + @.. broadcast=false integrator.fsalfirst=(uₙ - uₙ₋₁) / dt + cache.fsalfirstprev .= integrator.fsalfirst + return + end + + # precalculations + ρ = dtₙ / dtₙ₋₁ + c1 = ρ^2 / (1 + 2ρ) + + nlsolver.γ = (1 + ρ) / (1 + 2ρ) + nlsolver.α = 1 // 1 + @.. broadcast=false nlsolver.tmp=-c1 * uₙ₋₁ + c1 * uₙ₋₂ + nlsolver.z .= zero(eltype(z)) + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false uₙ=uₙ₋₁ + z + @.. broadcast=false du=(nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dt) + + @.. broadcast=false integrator.fsallast=du + integrator.stats.nf += 1 + if integrator.opts.adaptive + btilde0 = (dtₙ₋₁ + dtₙ) * 1 // 6 + btilde1 = 1 + ρ + btilde2 = ρ + @.. broadcast=false tmp=btilde0 * + (integrator.fsallast - btilde1 * integrator.fsalfirst + + btilde2 * cache.fsalfirstprev) + calculate_residuals!(atmp, tmp, uₙ₋₁, uₙ, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + ################################### Finalize + + if integrator.EEst < one(integrator.EEst) + @.. broadcast=false cache.fsalfirstprev=integrator.fsalfirst + cache.dtₙ₋₁ = dtₙ + end + return +end + +function initialize!(integrator, cache::DFBDFConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.du, integrator.uprev, integrator.p, + integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::DFBDFConstantCache{max_order}, + repeat_step = false) where {max_order} + @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, ts_tmp, iters_from_event, nconsteps = cache + @unpack t, dt, u, f, p, uprev = integrator + + k = order + reinitFBDF!(integrator, cache) + cache.u₀ = zero(u) + if iters_from_event >= 1 + cache.u₀ = calc_Lagrange_interp(k, weights, t + dt, ts, u_history, cache.u₀) + else + cache.u₀ = u + end + markfirststage!(nlsolver) + equi_ts = zeros(k - 1) + for i in 1:(k - 1) + equi_ts[i] = t - dt * i + end + + fill!(u_corrector, zero(eltype(u))) + if u isa Number + for i in 1:(k - 1) + u_corrector[i] = calc_Lagrange_interp(k, weights, equi_ts[i], ts, u_history, + u_corrector[i]) + end + tmp = uprev * bdf_coeffs[k, 2] + for i in 1:(k - 1) + tmp += u_corrector[i] * bdf_coeffs[k, i + 2] + end + else + for i in 1:(k - 1) + @.. broadcast=false @views u_corrector[:, i] = $calc_Lagrange_interp( + k, weights, + equi_ts[i], + ts, + u_history, + u_corrector[:, + i]) + end + tmp = uprev * bdf_coeffs[k, 2] + vc = _vec(tmp) + for i in 1:(k - 1) + vc += @.. broadcast=false u_corrector[:, i]*bdf_coeffs[k, i + 2] + end + tmp = reshape(vc, size(tmp)) + end + + nlsolver.tmp = tmp + cache.u₀ + nlsolver.z = zero(nlsolver.z) + nlsolver.γ = bdf_coeffs[k, 1] + nlsolver.α = 1 // 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = z + cache.u₀ + + for j in 2:k + r[j] = (1 - j) + for i in 2:(k + 1) + r[j] *= ((t + dt - j * dt) - ts[i]) / (i * dt) + end + end + + terkp1 = z + for j in 1:(k + 1) + terkp1 *= j * dt / (t + dt - ts[j]) + end + + lte = -1 / (1 + k) + for j in 2:k + lte -= (bdf_coeffs[k, j] // bdf_coeffs[k, 1]) * r[j] + end + lte *= terkp1 + + if integrator.opts.adaptive + for i in 1:(k + 1) + ts_tmp[i + 1] = ts[i] + end + ts_tmp[1] = t + dt + atmp = calculate_residuals(_vec(lte), _vec(uprev), _vec(u), integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + + terk = estimate_terk(integrator, cache, k + 1, Val(max_order), u) + atmp = calculate_residuals( + _vec(terk), _vec(uprev), _vec(u), integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + cache.terk = integrator.opts.internalnorm(atmp, t) + + if k > 1 + terkm1 = estimate_terk(integrator, cache, k, Val(max_order), u) + atmp = calculate_residuals(_vec(terkm1), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm1 = integrator.opts.internalnorm(atmp, t) + end + if k > 2 + terkm2 = estimate_terk(integrator, cache, k - 1, Val(max_order), u) + atmp = calculate_residuals(_vec(terkm2), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm2 = integrator.opts.internalnorm(atmp, t) + end + if nconsteps > k + 1 && k < max_order + atmp = calculate_residuals(_vec(terkp1), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkp1 = integrator.opts.internalnorm(atmp, t) + else + cache.terkp1 = zero(cache.terk) + end + end + integrator.u = u + integrator.fsallast = integrator.du = (nlsolver.α * z + nlsolver.tmp) * + inv(nlsolver.γ * dt) +end + +function initialize!(integrator, cache::DFBDFCache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + #integrator.f(integrator.fsalfirst, integrator.du, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + #integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::DFBDFCache{max_order}, + repeat_step = false) where {max_order} + @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, terk_tmp, terkp1_tmp, atmp, tmp, equi_ts, u₀, ts_tmp = cache + @unpack t, dt, u, f, p, uprev = integrator + + reinitFBDF!(integrator, cache) + k = order + @.. broadcast=false u₀=zero(u) + if cache.iters_from_event >= 1 + calc_Lagrange_interp!(k, weights, t + dt, ts, u_history, u₀) + else + @.. broadcast=false u₀=u + end + markfirststage!(nlsolver) + + for i in 1:(k - 1) + equi_ts[i] = t - dt * i + end + + fill!(u_corrector, zero(eltype(u))) + for i in 1:(k - 1) + @views calc_Lagrange_interp!(k, weights, equi_ts[i], ts, u_history, + u_corrector[:, i]) + end + + @.. broadcast=false tmp=uprev * bdf_coeffs[k, 2] + vc = _vec(tmp) + for i in 1:(k - 1) + @.. broadcast=false @views vc += u_corrector[:, i] * bdf_coeffs[k, i + 2] + end + + @.. broadcast=false nlsolver.tmp=tmp + u₀ + @.. broadcast=false nlsolver.z=zero(eltype(nlsolver.z)) + nlsolver.γ = bdf_coeffs[k, 1] + nlsolver.α = 1 // 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=z + u₀ + + for j in 2:k + r[j] = (1 - j) + for i in 2:(k + 1) + r[j] *= ((t + dt - j * dt) - ts[i]) / (i * dt) + end + end + + @.. broadcast=false terkp1_tmp=z + for j in 1:(k + 1) + @.. broadcast=false terkp1_tmp*=j * dt / (t + dt - ts[j]) + end + + lte = -1 / (1 + k) + for j in 2:k + lte -= (bdf_coeffs[k, j] // bdf_coeffs[k, 1]) * r[j] + end + @.. broadcast=false terk_tmp=lte * terkp1_tmp + if integrator.opts.adaptive + @unpack abstol, reltol, internalnorm = integrator.opts + for i in 1:(k + 1) + ts_tmp[i + 1] = ts[i] + end + ts_tmp[1] = t + dt + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, + internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + estimate_terk!(integrator, cache, k + 1, Val(max_order)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, + internalnorm, t) + cache.terk = integrator.opts.internalnorm(atmp, t) + + if k > 1 + estimate_terk!(integrator, cache, k, Val(max_order)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm1 = integrator.opts.internalnorm(atmp, t) + end + if k > 2 + estimate_terk!(integrator, cache, k - 1, Val(max_order)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm2 = integrator.opts.internalnorm(atmp, t) + end + if cache.nconsteps > k + 1 && k < max_order + calculate_residuals!(atmp, _vec(terkp1_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkp1 = integrator.opts.internalnorm(atmp, t) + else + cache.terkp1 = zero(cache.terkp1) + end + end + @.. broadcast=false integrator.fsallast=integrator.du = (nlsolver.α * z + + nlsolver.tmp) * + inv(nlsolver.γ * dt) #TODO Lorenz plot seems not smooth +end \ No newline at end of file diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 5f91695273..54c46c83a6 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -289,6 +289,16 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_finite_difference_weights, estimate_terk, calc_Lagrange_interp, bdf_step_reject_controller! +<<<<<<< HEAD +======= + +include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") +using ..OrdinaryDiffEqDAE +export DImplicitEuler, DABDF2, DFBDF +include("nlsolve/newton.jl") + +import PrecompileTools +>>>>>>> b150b887 (Added DAE solvers) using ..OrdinaryDiffEqBDF: post_newton_controller! include("integrators/integrator_utils.jl") From c299567b8851d0296e230577361fe0fbed5c3b46 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 02:17:41 +0530 Subject: [PATCH 33/45] @unpack --- .../src/OrdinaryDiffEqDAE.jl | 3 +- lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl | 60 ++++ .../test/dae_convergence_tests.jl | 56 ++++ lib/OrdinaryDiffEqDAE/test/dae_event.jl | 30 ++ .../test/dae_initialization_tests.jl | 268 +++++++++++++++++ .../test/dae_initialize_integration.jl | 78 +++++ lib/OrdinaryDiffEqDAE/test/hard_dae.jl | 275 ++++++++++++++++++ lib/OrdinaryDiffEqDAE/test/runtest.jl | 0 test/runtests.jl | 19 ++ 9 files changed, 788 insertions(+), 1 deletion(-) create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_event.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/hard_dae.jl create mode 100644 lib/OrdinaryDiffEqDAE/test/runtest.jl diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 0be59f3cbf..ed77fee311 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -2,7 +2,8 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + @unpack using TruncatedStacktraces include("algorithms.jl") diff --git a/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl new file mode 100644 index 0000000000..398aa310be --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl @@ -0,0 +1,60 @@ +using OrdinaryDiffEq, LinearAlgebra, ForwardDiff, Test + +function rober(du, u, p, t) + y₁, y₂, y₃ = u + k₁, k₂, k₃ = p + du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ + du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du[3] = y₁ + y₂ + y₃ - 1 + nothing +end +function rober(u, p, t) + y₁, y₂, y₃ = u + k₁, k₂, k₃ = p + [-k₁ * y₁ + k₃ * y₂ * y₃, + k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2, + y₁ + y₂ + y₃ - 1] +end +M = [1.0 0 0 + 0 1.0 0 + 0 0 0] +roberf = ODEFunction(rober, mass_matrix = M) +roberf_oop = ODEFunction{false}(rober, mass_matrix = M) +prob_mm = ODEProblem(roberf, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) +prob_mm_oop = ODEProblem(roberf_oop, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rodas5P(), reltol = 1e-8, abstol = 1e-8) +sol = solve(prob_mm_oop, Rodas5P(), reltol = 1e-8, abstol = 1e-8) + +function f(out, du, u, p, t) + out[1] = -p[1] * u[1] + p[3] * u[2] * u[3] - du[1] + out[2] = +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2] + out[3] = u[1] + u[2] + u[3] - 1.0 +end +function f(du, u, p, t) + [-p[1] * u[1] + p[3] * u[2] * u[3] - du[1], + +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2], + u[1] + u[2] + u[3] - 1.0] +end +p = [0.04, 3e7, 1e4] +u₀ = [1.0, 0, 0] +du₀ = [-0.04, 0.04, 0.0] +tspan = (0.0, 100000.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) +prob_oop = DAEProblem{false}(f, du₀, u₀, tspan, p, differential_vars = differential_vars) +sol1 = solve(prob, DFBDF(), dt = 1e-5, abstol = 1e-8, reltol = 1e-8) + +# These tests flex differentiation of the solver and through the initialization +# To only test the solver part and isolate potential issues, set the initialization to consistent +@testset "Inplace: $(isinplace(_prob)), DAEProblem: $(_prob isa DAEProblem), BrownBasic: $(initalg isa BrownFullBasicInit), Autodiff: $autodiff" for _prob in [ + prob, prob_mm, prob_oop, prob_mm_oop], + initalg in [BrownFullBasicInit(), ShampineCollocationInit()], autodiff in [true, false] + + alg = _prob isa DAEProblem ? DFBDF(; autodiff) : Rodas5P(; autodiff) + function f(p) + sol = solve(remake(_prob, p = p), alg, abstol = 1e-14, + reltol = 1e-14, initializealg = initalg) + sum(sol) + end + @test ForwardDiff.gradient(f, [0.04, 3e7, 1e4])≈[0, 0, 0] atol=1e-8 +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl new file mode 100644 index 0000000000..e3ef2dd474 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl @@ -0,0 +1,56 @@ +using OrdinaryDiffEq, DiffEqDevTools +using Test, Random +Random.seed!(100) + +dts = 1 .// 2 .^ (9:-1:5) +testTol = 0.2 + +f_dae_linear = (res, du, u, p, t) -> (@. res = du - u) +f_dae_linear_analytic = (du0, u0, p, t) -> @. u0 * exp(t) +prob_dae_linear_iip = DAEProblem( + DAEFunction(f_dae_linear; + analytic = f_dae_linear_analytic), + [1.0, 1.0], [1.0, 1.0], (0.0, 1.0)) + +@testset "DAE Solver Convergence Tests (in-place)" begin + prob = prob_dae_linear_iip + + sim11 = test_convergence(dts, prob, DImplicitEuler()) + @test sim11.𝒪est[:final]≈1 atol=testTol + + sim12 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) + @test sim12.𝒪est[:final]≈1 atol=testTol + + sim13 = test_convergence(dts, prob, DABDF2()) + @test sim13.𝒪est[:final]≈2 atol=testTol + + sim14 = test_convergence(dts, prob, DABDF2(; autodiff = false)) + @test sim14.𝒪est[:final]≈2 atol=testTol + + @test_nowarn solve(prob, DFBDF()) +end + +f_dae_linear = (du, u, p, t) -> (@. du - u) +f_dae_linear_analytic = (du0, u0, p, t) -> @. u0 * exp(t) +prob_dae_linear_oop = DAEProblem( + DAEFunction(f_dae_linear; + analytic = f_dae_linear_analytic), + 1.0, 1.0, (0.0, 1.0)) + +@testset "DAE Solver Convergence Tests (out-of-place)" begin + prob = prob_dae_linear_oop + + sim21 = test_convergence(dts, prob, DImplicitEuler()) + @test sim21.𝒪est[:final]≈1 atol=testTol + + sim22 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) + @test sim22.𝒪est[:final]≈1 atol=testTol + + sim23 = test_convergence(dts, prob, DABDF2()) + @test sim23.𝒪est[:final]≈2 atol=testTol + + sim24 = test_convergence(dts, prob, DABDF2(; autodiff = false)) + @test sim24.𝒪est[:final]≈2 atol=testTol + + @test_nowarn solve(prob, DFBDF()) +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_event.jl b/lib/OrdinaryDiffEqDAE/test/dae_event.jl new file mode 100644 index 0000000000..c20b600670 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_event.jl @@ -0,0 +1,30 @@ +using OrdinaryDiffEq, Test + +f = function (out, du, u, p, t) + out[1] = -p[1] * u[1] + p[3] * u[2] * u[3] - du[1] + out[2] = +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2] + out[3] = u[1] + u[2] + u[3] - p[4] +end +u₀ = [1.0, 0, 0] +du₀ = [0.0, 0.0, 0.0] +p = [0.04, 3.0e7, 1.0e4, 1.0] +tspan = (0.0, 100.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) +condition(u, t, integrator) = t in [50.0] +affect!(integrator) = integrator.p[4] = 2.0 +cb = DiscreteCallback(condition, affect!) + +#= +# Regression test +using Sundials +sol = solve(prob, IDA(), callback=cb, tstops=[50.0],abstol=1e-14,reltol=1e-14) +=# + +p = [0.04, 3.0e7, 1.0e4, 1.0] +prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) +sol = solve(prob, DFBDF(), callback = cb, tstops = [50.0], abstol = 1e-12, reltol = 1e-12) +@test sol.t[end] == 100.0 +@test sol[end][1]≈0.686300529575259 atol=1e-7 +@test sol[end][2]≈2.0797982209353813e-6 atol=1e-7 +@test sol[end][3]≈1.31369739062652 atol=1e-7 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl new file mode 100644 index 0000000000..5cf37c27f4 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl @@ -0,0 +1,268 @@ +using OrdinaryDiffEq, StaticArrays, LinearAlgebra, Test + +## Mass Matrix + +function rober_oop(u, p, t) + y₁, y₂, y₃ = u + k₁, k₂, k₃ = p + du1 = -k₁ * y₁ + k₃ * y₂ * y₃ + du2 = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du3 = y₁ + y₂ + y₃ - 1 + [du1, du2, du3] +end +M = [1.0 0 0 + 0 1.0 0 + 0 0 0] +f_oop = ODEFunction(rober_oop, mass_matrix = M) +prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rosenbrock23(autodiff = false), reltol = 1e-8, abstol = 1e-8) +@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! +sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8, + initializealg = ShampineCollocationInit()) +@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! + +prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8) +@test sum(sol[1]) ≈ 1 +@test sol[1] ≈ [1.0, 0.0, 0.0] +for alg in [Rosenbrock23(autodiff = false), Trapezoid()] + local sol + sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, + initializealg = ShampineCollocationInit()) + @test sum(sol[1]) ≈ 1 +end + +function rober(du, u, p, t) + y₁, y₂, y₃ = u + k₁, k₂, k₃ = p + du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ + du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du[3] = y₁ + y₂ + y₃ - 1 + nothing +end +M = [1.0 0 0 + 0 1.0 0 + 0 0 0] +f = ODEFunction(rober, mass_matrix = M) +prob_mm = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rodas5(autodiff = false), reltol = 1e-8, abstol = 1e-8) +@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! +sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8, + initializealg = ShampineCollocationInit()) +@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! + +prob_mm = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5), (0.04, 3e7, 1e4)) +sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8) +@test sum(sol[1]) ≈ 1 +@test sol[1] ≈ [1.0, 0.0, 0.0] + +for alg in [Rodas5(autodiff = false), Trapezoid()] + local sol + sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, + initializealg = ShampineCollocationInit()) + @test sum(sol[1]) ≈ 1 +end + +function rober_no_p(du, u, p, t) + y₁, y₂, y₃ = u + (k₁, k₂, k₃) = (0.04, 3e7, 1e4) + du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ + du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du[3] = y₁ + y₂ + y₃ - 1 + nothing +end + +function rober_oop_no_p(du, u, p, t) + y₁, y₂, y₃ = u + (k₁, k₂, k₃) = (0.04, 3e7, 1e4) + du1 = -k₁ * y₁ + k₃ * y₂ * y₃ + du2 = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 + du3 = y₁ + y₂ + y₃ - 1 + [du1, du2, du3] +end + +# test oop and iip ODE initialization with parameters without eltype/length +struct UnusedParam +end +for f in ( + ODEFunction(rober_no_p, mass_matrix = M), ODEFunction(rober_oop_no_p, mass_matrix = M)) + local prob, probp + prob = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5)) + probp = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5), UnusedParam) + for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) + isapprox(init(prob, Rodas5(), abstol = 1e-10; initializealg).u, + init(prob, Rodas5(), abstol = 1e-10; initializealg).u) + end +end + +## DAEProblem + +f = function (du, u, p, t) + out1 = -0.04u[1] + 1e4 * u[2] * u[3] - du[1] + out2 = +0.04u[1] - 3e7 * u[2]^2 - 1e4 * u[2] * u[3] - du[2] + out3 = u[1] + u[2] + u[3] - 1.0 + [out1, out2, out3] +end + +u₀ = [1.0, 0, 0] +du₀ = [0.0, 0.0, 0.0] +tspan = (0.0, 100000.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +integrator = init(prob, DImplicitEuler()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +integrator = init(prob, DFBDF()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +u₀ = [1.0, 0, 0.2] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) +@test integrator.u≈[1.0, 0, 0.0] atol=1e-9 +integrator = init(prob, DABDF2(), initializealg = ShampineCollocationInit()) +@test !(integrator.u ≈ [1.0, 0, 0.0]) + +u₀ = [1.0, 0, 0.2] +prob = DAEProblem(f, du₀, u₀, tspan) +integrator = init(prob, DABDF2()) +@test !(integrator.u ≈ [1.0, 0, 0.0]) + +f = function (out, du, u, p, t) + out[1] = -0.04u[1] + 1e4 * u[2] * u[3] - du[1] + out[2] = +0.04u[1] - 3e7 * u[2]^2 - 1e4 * u[2] * u[3] - du[2] + out[3] = u[1] + u[2] + u[3] - 1.0 +end + +u₀ = [1.0, 0, 0] +du₀ = [0.0, 0.0, 0.0] +tspan = (0.0, 100000.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) +integrator2 = init(prob, DABDF2(autodiff = false)) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +@test integrator2.du[1]≈-0.04 atol=1e-99 +@test integrator2.du[2]≈0.04 atol=1e-9 +@test integrator2.u≈u₀ atol=1e-9 + +integrator = init(prob, DImplicitEuler()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +integrator = init(prob, DFBDF()) + +@test integrator.du[1]≈-0.04 atol=1e-9 +@test integrator.du[2]≈0.04 atol=1e-9 +@test integrator.u≈u₀ atol=1e-9 + +u₀ = [1.0, 0, 0.2] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) +@test integrator.u≈[1.0, 0, 0.0] atol=1e-9 +integrator = init(prob, DABDF2(), initializealg = ShampineCollocationInit()) +@test !(integrator.u ≈ [1.0, 0, 0.0]) + +u₀ = [1.0, 0, 0.2] +prob = DAEProblem(f, du₀, u₀, tspan) +integrator = init(prob, DABDF2()) +@test !(integrator.u ≈ [1.0, 0, 0.0]) + +# Need to be able to find the consistent solution of this problem, broken right now +# analytical solution: +# u[1](t) -> cos(t) +# u[2](t) -> -sin(t) +# u[3](t) -> 2cos(t) +f = function (out, du, u, p, t) + out[1] = du[1] - u[2] + out[2] = du[2] + u[3] - cos(t) + out[3] = u[1] - cos(t) +end + +u₀ = [1.0, 0.0, 0.0] +du₀ = [0.0, 0.0, 0.0] +tspan = (0.0, 1.0) +differential_vars = [true, true, false] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2(); initializealg = ShampineCollocationInit()) + +@test integrator.du[1]≈0.0 atol=1e-9 +@test_broken integrator.du[2]≈-1.0 atol=1e-9 +@test_broken integrator.u[3]≈2.0 atol=1e-9 + +# test iip dae initialization with parameters without eltype/length +probp = DAEProblem(f, du₀, u₀, tspan, UnusedParam(), differential_vars = differential_vars) +for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) + @test isapprox( + init(probp, DABDF2(); initializealg).u, init(prob, DABDF2(); initializealg).u) +end + +f = function (du, u, p, t) + du - u +end + +u₀ = SVector(1.0) +du₀ = SVector(0.0) +tspan = (0.0, 1.0) +differential_vars = SVector(true) +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) + +@test integrator.du≈[1.0] atol=1e-9 + +f = function (du, u, p, t) + du .- u +end + +u₀ = SA[1.0, 1.0] +du₀ = SA[0.0, 0.0] +tspan = (0.0, 1.0) +differential_vars = [true, true] +prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) +integrator = init(prob, DABDF2()) + +@test integrator.du[1]≈1.0 atol=1e-9 +@test integrator.du[2]≈1.0 atol=1e-9 +# test oop DAE initialization with parameters without eltype/length +probp = DAEProblem(f, du₀, u₀, tspan, UnusedParam(), differential_vars = differential_vars) +for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) + @test isapprox( + init(probp, DABDF2(); initializealg).u, init(prob, DABDF2(); initializealg).u) +end + +# to test that we get the right NL solve we need a broken solver. +struct BrokenNLSolve <: SciMLBase.AbstractNonlinearAlgorithm + BrokenNLSolve(; kwargs...) = new() +end +function SciMLBase.__solve(prob::NonlinearProblem, + alg::BrokenNLSolve, args...; + kwargs...) + u = fill(reinterpret(Float64, 0xDEADBEEFDEADBEEF), 3) + SciMLBase.build_solution(prob, alg, u, copy(u); + retcode = ReturnCode.Success) +end +function f2(u, p, t) + u +end +f = ODEFunction(f2, mass_matrix = Diagonal([1.0, 1.0, 0.0])) +prob = ODEProblem(f, ones(3), (0.0, 1.0)) +integrator = init(prob, Rodas5P(), + initializealg = ShampineCollocationInit(1.0, BrokenNLSolve())) +@test all(isequal(reinterpret(Float64, 0xDEADBEEFDEADBEEF)), integrator.u) \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl new file mode 100644 index 0000000000..33913925e2 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl @@ -0,0 +1,78 @@ +using ModelingToolkit, OrdinaryDiffEq, Test + +@parameters t g e b +@variables v(t) w(t) F(t) +@derivatives D' ~ t +single_neuron_eqs = [ + D(v) ~ min(max(-2 - v, v), 2 - v) - w + F, # add the flux term + D(w) ~ e * (v - g * w + b) +] +n1 = ODESystem(single_neuron_eqs, t, [v, w, F], [g, e, b], name = :n1) +n2 = ODESystem(single_neuron_eqs, t, [v, w, F], [g, e, b], name = :n2) +@parameters D Dk +connections = [0 ~ n1.F - D * Dk * max(n1.v - n2.v, 0) + 0 ~ n2.F - D * max(n2.v - n1.v, 0)] +connected = ODESystem(connections, t, [], [D, Dk], systems = [n1, n2], name = :connected) +connected = complete(connected) + +u0 = [ + n1.v => -2, + n1.w => -2 / 3, + n1.F => 0, + n2.v => -2, + n2.w => -0.7, + n2.F => 0 +] +tspan = (0.0, 1750.0) +p0 = [ + n1.g => 0.8, + n1.e => 0.04, + n1.b => 0, + n2.g => 0.8, + n2.e => 0.04, + n2.b => 0.2, + D => 0.047, + Dk => 1 +] + +prob = ODEProblem(connected, u0, tspan, p0) +sol = solve(prob, Rodas5(), initializealg = BrownFullBasicInit()) +@test prob.u0 == sol[1] +sol = solve(prob, Rodas5(), initializealg = ShampineCollocationInit()) +@test prob.u0 == sol[1] +#test initialization when given a specific nonlinear solver +using NonlinearSolve +sol = solve(prob, Rodas5(), initializealg = BrownFullBasicInit(1e-10, RobustMultiNewton())) +@test prob.u0 == sol[1] + +# Initialize on ODEs +# https://github.com/SciML/ModelingToolkit.jl/issues/2508 + +function testsys(du, u, p, t) + du[1] = -2 +end +function initsys(du, u, p) + du[1] = -1 + u[1] +end +nlprob = NonlinearProblem(initsys, [0.0]) +initprobmap(nlprob) = nlprob.u +sol = solve(nlprob) + +_f = ODEFunction(testsys; initializeprob = nlprob, initializeprobmap = initprobmap) +prob = ODEProblem(_f, [0.0], (0.0, 1.0)) +sol = solve(prob, Tsit5()) +@test SciMLBase.successful_retcode(sol) +@test sol[1] == [1.0] + +prob = ODEProblem(_f, [0.0], (0.0, 1.0)) +sol = solve(prob, Tsit5(), dt = 1e-10) +@test SciMLBase.successful_retcode(sol) +@test sol[1] == [1.0] +@test sol[2] ≈ [0.9999999998] +@test sol[end] ≈ [-1.0] + +sol = solve(prob, Rodas5P(), dt = 1e-10) +@test SciMLBase.successful_retcode(sol) +@test sol[1] == [1.0] +@test sol[2] ≈ [0.9999999998] +@test sol[end] ≈ [-1.0] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/hard_dae.jl b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl new file mode 100644 index 0000000000..f47b226ce1 --- /dev/null +++ b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl @@ -0,0 +1,275 @@ +using OrdinaryDiffEq +using LinearAlgebra +using NLsolve +using Test + +p_inv = [500.0 + 0.084 + 4.69 + 2.0 + 400.0 + 20.0 + 0.2 + 1000.0 + 0.59 + 736.0 + 0.0 + 0.0 + 0.2 + 1.27 + 14.3 + 0.0 + 50.0 + 0.2 + 0.08 + 0.003 + 0.074 + 0.2 + 0.01 # Matt + 1.0 # V_ref + 1.0 # ω ref + 0.7 # Pref + 0 # Q_ref + 0.5 #Xtrans + 0.0 # Rtrans + 1.01 #Vm + 0.0] # Vθ + +function vsm(dx, x, p, t) + #PARAMETERS + ω_lp = p[1] + kp_pll = p[2] + ki_pll = p[3] + Ta = p[4] + kd = p[5] + kω = p[6] + kq = p[7] + ωf = p[8] + kpv = p[9] + kiv = p[10] + kffv = p[11] + rv = p[12] + lv = p[13] + kpc = p[14] + kic = p[15] + kffi = p[16] + ωad = p[17] + kad = p[18] + lf = p[19] + rf = p[20] + cf = p[21] + lg = p[22] + rg = p[23] + Vref = p[24] + ωref = p[25] + Pref = p[26] + Qref = p[27] + Xtrans = p[28] + Rtrans = p[29] + Vm = p[30] + Vθ = p[31] + + #STATE INDEX AND STATES + i__vi_filter, vi_filter = 1, x[1] + i__γd_ic, γd_ic = 2, x[2] + i__vq_pll, vq_pll = 3, x[3] + i__γq_ic, γq_ic = 4, x[4] + i__ir_filter, ir_filter = 5, x[5] + i__ξd_ic, ξd_ic = 6, x[6] + i__ϕd_ic, ϕd_ic = 7, x[7] + i__ε_pll, ε_pll = 8, x[8] + i__ir_cnv, ir_cnv = 9, x[9] + i__vr_filter, vr_filter = 10, x[10] + i__ω_oc, ω_oc = 11, x[11] + i__ξq_ic, ξq_ic = 12, x[12] + i__vd_pll, vd_pll = 13, x[13] + i__q_oc, q_oc = 14, x[14] + i__ϕq_ic, ϕq_ic = 15, x[15] + i__θ_pll, θ_pll = 16, x[16] + i__θ_oc, θ_oc = 17, x[17] + i__ii_cnv, ii_cnv = 18, x[18] + i__ii_filter, ii_filter = 19, x[19] + i__ir_source, ir_source = 20, x[20] + i__ii_source, ii_source = 21, x[21] + + ω_base = 60.0 * 2 * pi + ω_sys = 1.0 + + #PLL + δω_pll = kp_pll * atan(vq_pll / vd_pll) + ki_pll * ε_pll + ω_pll = δω_pll + ω_sys + vd_filt_pll = sin(θ_pll + pi / 2) * vr_filter - cos(θ_pll + pi / 2) * vi_filter + vq_filt_pll = cos(θ_pll + pi / 2) * vr_filter + sin(θ_pll + pi / 2) * vi_filter + + dx[i__vd_pll] = ω_lp * (vd_filt_pll - vd_pll) #docs:(1a) + dx[i__vq_pll] = ω_lp * (vq_filt_pll - vq_pll) #docs:(1b) + dx[i__ε_pll] = atan(vq_pll / vd_pll) #docs:(1c) + dx[i__θ_pll] = ω_base * δω_pll #docs:(1d) + + #OUTER LOOP CONTROL + pe = vr_filter * ir_filter + vi_filter * ii_filter #docs:(2d) + qe = vi_filter * ir_filter - vr_filter * ii_filter #docs:(2e) + v_ref_olc = Vref + kq * (Qref - q_oc) + + dx[i__ω_oc] = (Pref - pe - kd * (ω_oc - ω_pll) - kω * (ω_oc - ωref)) / Ta #docs:(2a) + dx[i__θ_oc] = ω_base * (ω_oc - ω_sys) #docs:(2b) + dx[i__q_oc] = ωf * (qe - q_oc) #docs:(2c) + + #INNER LOOP CONTROL + #reference transformations + vd_filt_olc = sin(θ_oc + pi / 2) * vr_filter - cos(θ_oc + pi / 2) * vi_filter + vq_filt_olc = cos(θ_oc + pi / 2) * vr_filter + sin(θ_oc + pi / 2) * vi_filter + id_filt_olc = sin(θ_oc + pi / 2) * ir_filter - cos(θ_oc + pi / 2) * ii_filter + iq_filt_olc = cos(θ_oc + pi / 2) * ir_filter + sin(θ_oc + pi / 2) * ii_filter + id_cnv_olc = sin(θ_oc + pi / 2) * ir_cnv - cos(θ_oc + pi / 2) * ii_cnv + iq_cnv_olc = cos(θ_oc + pi / 2) * ir_cnv + sin(θ_oc + pi / 2) * ii_cnv + + #Voltage control equations + Vd_filter_ref = v_ref_olc - rv * id_filt_olc + ω_oc * lv * iq_filt_olc #docs:(3g) + Vq_filter_ref = -rv * iq_filt_olc - ω_oc * lv * id_filt_olc #docs:(3h) + dx[i__ξd_ic] = Vd_filter_ref - vd_filt_olc #docs:(3a) + dx[i__ξq_ic] = Vq_filter_ref - vq_filt_olc #docs:(3b) + + #current control equations + Id_cnv_ref = (kpv * (Vd_filter_ref - vd_filt_olc) + kiv * ξd_ic - #docs:(3i) + cf * ω_oc * vq_filt_olc + kffi * id_filt_olc) + Iq_cnv_ref = (kpv * (Vq_filter_ref - vq_filt_olc) + + kiv * ξq_ic + #docs:(3j) + cf * ω_oc * vd_filt_olc + + kffi * iq_filt_olc) + dx[i__γd_ic] = Id_cnv_ref - id_cnv_olc #docs:(3c) + dx[i__γq_ic] = Iq_cnv_ref - iq_cnv_olc #docs:(3d) + + #active damping equations + Vd_cnv_ref = (kpc * (Id_cnv_ref - id_cnv_olc) + kic * γd_ic - lf * ω_oc * iq_cnv_olc + #docs:(3k) + kffv * vd_filt_olc - kad * (vd_filt_olc - ϕd_ic)) + Vq_cnv_ref = (kpc * (Iq_cnv_ref - iq_cnv_olc) + + kic * γq_ic + + lf * ω_oc * id_cnv_olc + #docs:(3l) + kffv * vq_filt_olc - kad * (vq_filt_olc - ϕq_ic)) + dx[i__ϕd_ic] = ωad * (vd_filt_olc - ϕd_ic) #docs:(3e) + dx[i__ϕq_ic] = ωad * (vq_filt_olc - ϕq_ic) #docs:(3f) + + #LCL FILTER + #reference transformations + Vr_cnv = sin(θ_oc + pi / 2) * Vd_cnv_ref + cos(θ_oc + pi / 2) * Vq_cnv_ref + Vi_cnv = -cos(θ_oc + pi / 2) * Vd_cnv_ref + sin(θ_oc + pi / 2) * Vq_cnv_ref + + Vr_pcc = Vm * cos(Vθ) + Vi_pcc = Vm * sin(Vθ) + + dx[i__ir_cnv] = (ω_base / lf) * #docs:(5a) + (Vr_cnv - vr_filter - rf * ir_cnv + ω_sys * lf * ii_cnv) + dx[i__ii_cnv] = (ω_base / lf) * #docs:(5b) + (Vi_cnv - vi_filter - rf * ii_cnv - ω_sys * lf * ir_cnv) + dx[i__vr_filter] = (ω_base / cf) * #docs:(5c) + (ir_cnv - ir_filter + ω_sys * cf * vi_filter) + dx[i__vi_filter] = (ω_base / cf) * #docs:(5d) + (ii_cnv - ii_filter - ω_sys * cf * vr_filter) + dx[i__ir_filter] = (ω_base / lg) * #docs:(5e) + (vr_filter - Vr_pcc - rg * ir_filter + ω_sys * lg * ii_filter) + dx[i__ii_filter] = +(ω_base / lg) * #docs:(5f) + (vi_filter - Vi_pcc - rg * ii_filter - ω_sys * lg * ir_filter) + + # Network interface algebraic equations 0 = I - YV + line_currents = ((Vr_cnv + Vi_cnv * 1im) - (Vr_pcc + Vi_pcc * 1im)) / + (Rtrans + Xtrans * 1im) + dx[i__ii_source] = ii_source - imag(line_currents) + dx[i__ir_source] = ir_source - real(line_currents) + return +end + +u0 = [0.0, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 1.0, + 1.0, + 0.0, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.01, + 0.0, + 1.0, + 0.0 +] +init_f! = (dx, x) -> vsm(dx, x, p_inv, 0) +res = nlsolve(init_f!, u0) + +M = diagm(ones(21)) +#Last 2 equations are algebraic +M[20, 20] = M[21, 21] = 0.0 + +f = ODEFunction(vsm, mass_matrix = M) + +condition(u, t, integrator) = t == 1.0 +affect!(integrator) = integrator.p[28] += 0.2 +cb = DiscreteCallback(condition, affect!) + +prob = ODEProblem(f, deepcopy(res.zero), (0, 20.0), deepcopy(p_inv)) +refsol = solve(prob, Rodas4(), saveat = 0.1, callback = cb, tstops = [1.0], reltol = 1e-12, + abstol = 1e-17) + +for solver in (Rodas4, Rodas4P, Rodas5, Rodas5P, FBDF, QNDF, Rosenbrock23) + @show solver + prob = ODEProblem(f, deepcopy(res.zero), (0, 20.0), deepcopy(p_inv)) + sol = solve( + prob, solver(), saveat = 0.1, callback = cb, tstops = [1.0], reltol = 1e-14, + abstol = 1e-14) + @test sol.retcode == ReturnCode.Success + @test sol.t[end] == 20.0 + @test maximum(sol - refsol) < 1e-11 +end + +function hardstop!(du, u, p, t) + pm, pg = p + y, f_wall, dy = u + du[1] = dy + du[2] = ifelse(y <= 0, y, f_wall) + du[3] = (-ifelse(t < 2, -pg * pm, pg * pm) - f_wall) / (-pm) +end + +hardstop!(u, p, t) = (du = similar(u); hardstop!(du, u, p, t); du) + +fun = ODEFunction(hardstop!, mass_matrix = Diagonal([1, 0, 1])) +prob1 = ODEProblem(fun, [5, 0, 0.0], (0, 4.0), [100, 10.0]) +prob2 = ODEProblem(fun, [5, 0, 0.0], (0, 4.0), [100, 10.0]) +for prob in [prob1, prob2] + @test solve(prob, ImplicitEuler(), dt = 1 / 2^10, adaptive = false).retcode == + ReturnCode.ConvergenceFailure +end + +condition2 = (u, t, integrator) -> t == 2 +affect2! = integrator -> integrator.u[1] = 1e-6 +cb = DiscreteCallback(condition2, affect2!) + +@isdefined(N_FAILS) || const N_FAILS = Ref(0) +function choice_function(integrator) + integrator.do_error_check = false + if integrator.force_stepfail + N_FAILS[] += 1 + else + N_FAILS[] = 0 + end + + (N_FAILS[] > 3) + 1 +end +simple_implicit_euler = ImplicitEuler(nlsolve = NLNewton(check_div = false, + always_new = true)) +alg_switch = CompositeAlgorithm((ImplicitEuler(), simple_implicit_euler), choice_function) + +for prob in [prob1, prob2], alg in [simple_implicit_euler, alg_switch] + sol = solve(prob, alg, callback = cb, dt = 1 / 2^10, adaptive = false) + @test sol.retcode == ReturnCode.Success + @test sol(0, idxs = 1) == 5 + @test sol(2, idxs = 1) == 0 + @test sol(4, idxs = 1) > 10 +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/runtests.jl b/test/runtests.jl index 1edccc79e5..dff44a6753 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -147,9 +147,15 @@ end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceV" || GROUP == "Interface") @time @safetestset "Interpolation Derivative Error Tests" include("interface/interpolation_derivative_error_tests.jl") @time @safetestset "AD Tests" include("interface/ad_tests.jl") +<<<<<<< HEAD @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl") @time @safetestset "Newton Tests" include("interface/newton_tests.jl") @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl") +======= + @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl") + @time @safetestset "Newton Tests" include("interface/newton_tests.jl") + @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl") +>>>>>>> 09f9af8c (@unpack) end if !is_APPVEYOR && @@ -173,8 +179,13 @@ end @time @safetestset "Reverse Directioned Event Tests" include("integrators/rev_events_tests.jl") @time @safetestset "Differentiation Direction Tests" include("integrators/diffdir_tests.jl") @time @safetestset "Resize Tests" include("integrators/resize_tests.jl") +<<<<<<< HEAD @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl") @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_event.jl") +======= + @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl") + @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_event.jl") +>>>>>>> 09f9af8c (@unpack) @time @safetestset "Cache Tests" include("integrators/ode_cache_tests.jl") @time @safetestset "Add Steps Tests" include("integrators/ode_add_steps_tests.jl") @time @safetestset "IMEX Split Function Tests" include("integrators/split_ode_tests.jl") @@ -185,7 +196,11 @@ end @time @safetestset "Special Interp Tests" include("regression/special_interps.jl") @time @safetestset "Inplace Tests" include("regression/ode_inplace_tests.jl") @time @safetestset "Adaptive Tests" include("regression/ode_adaptive_tests.jl") +<<<<<<< HEAD @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqBDF/test/hard_dae.jl") +======= + @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqDAE/test/hard_dae.jl") +>>>>>>> 09f9af8c (@unpack) end if !is_APPVEYOR && (GROUP == "All" || GROUP == "Regression_II" || GROUP == "Regression") @@ -199,7 +214,11 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_I" @time @safetestset "Partitioned Methods Tests" include("algconvergence/partitioned_methods_tests.jl") @time @safetestset "Convergence Tests" include("algconvergence/ode_convergence_tests.jl") +<<<<<<< HEAD @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl") +======= + @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl") +>>>>>>> 09f9af8c (@unpack) @time @safetestset "Non-autonomous Convergence Tests" include("algconvergence/non-autonomous_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("algconvergence/adams_tests.jl") @time @safetestset "Nordsieck Tests" include("algconvergence/nordsieck_tests.jl") From 615b6b9c5d12360b121b5314740ace2c6761350b Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:19:15 +0530 Subject: [PATCH 34/45] @.. --- lib/OrdinaryDiffEqDAE/Project.toml | 1 + lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml index ee3e8c74e7..b15e3bbe39 100644 --- a/lib/OrdinaryDiffEqDAE/Project.toml +++ b/lib/OrdinaryDiffEqDAE/Project.toml @@ -6,6 +6,7 @@ version = "1.0.0" [deps] OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" [extras] DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index ed77fee311..82a1d7d496 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -5,6 +5,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack using TruncatedStacktraces +import FastBroadCast: @.. include("algorithms.jl") include("alg_utils.jl") From ef8eaf8d2bd33faef86612825c275c7c4c1829ea Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:41:13 +0530 Subject: [PATCH 35/45] @.. --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- lib/OrdinaryDiffEqDAE/test/runtest.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 82a1d7d496..9643b52c2d 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -5,7 +5,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack using TruncatedStacktraces -import FastBroadCast: @.. +import FastBroadcast: @.. include("algorithms.jl") include("alg_utils.jl") diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl index e69de29bb2..a639da4027 100644 --- a/lib/OrdinaryDiffEqDAE/test/runtest.jl +++ b/lib/OrdinaryDiffEqDAE/test/runtest.jl @@ -0,0 +1,2 @@ +using SafeTestsets + From 09fb53674fc8e1ffebe0e793f35cd34bfd7f92af Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:43:51 +0530 Subject: [PATCH 36/45] @cache --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 9643b52c2d..374e6b772b 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -3,7 +3,7 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack + @unpack, @cache using TruncatedStacktraces import FastBroadcast: @.. From 27ed5322edcc6aacdeb37ebd528a73c2f1a3a9ba Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:46:02 +0530 Subject: [PATCH 37/45] MuladdMacro --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 374e6b772b..0657ec30b9 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -4,7 +4,7 @@ import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @unpack, @cache -using TruncatedStacktraces +using TruncatedStacktraces, MuladdMacro import FastBroadcast: @.. include("algorithms.jl") From 8cc8b863a10481aa4549684b8b29b6cdc9062789 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 10:56:06 +0530 Subject: [PATCH 38/45] controllers --- lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl index 0657ec30b9..9017917bb8 100644 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl @@ -3,7 +3,9 @@ module OrdinaryDiffEqDAE import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, DEFAULT_PRECS, OrdinaryDiffEqConstantCache, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack, @cache + @unpack, @cache, default_controller, stepsize_controller!, + step_accept_controller!, + step_reject_controller!, post_newton_controller! using TruncatedStacktraces, MuladdMacro import FastBroadcast: @.. From 6b4941be2288f4e1d92a2804f26daffabccbf0ed Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 23 Jul 2024 11:13:21 +0530 Subject: [PATCH 39/45] post_newton_controller! --- src/OrdinaryDiffEq.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 54c46c83a6..7e6c5b3072 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -295,6 +295,10 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") using ..OrdinaryDiffEqDAE export DImplicitEuler, DABDF2, DFBDF + + +using ..OrdinaryDiffEqDAE: post_newton_controller! +include("integrators/integrator_utils.jl") include("nlsolve/newton.jl") import PrecompileTools From 181633f33acdffed189640023539933460fec651 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Fri, 26 Jul 2024 22:20:47 +0530 Subject: [PATCH 40/45] DAE added to BDF --- lib/OrdinaryDiffEqBDF/src/algorithms.jl | 13 + lib/OrdinaryDiffEqBDF/test/runtest.jl | 9 +- lib/OrdinaryDiffEqDAE/Project.toml | 21 - .../src/OrdinaryDiffEqDAE.jl | 20 - lib/OrdinaryDiffEqDAE/src/alg_utils.jl | 12 - lib/OrdinaryDiffEqDAE/src/algorithms.jl | 75 --- lib/OrdinaryDiffEqDAE/src/controllers.jl | 130 ----- lib/OrdinaryDiffEqDAE/src/dae_caches.jl | 256 ---------- lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl | 460 ------------------ lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl | 60 --- .../test/dae_convergence_tests.jl | 56 --- lib/OrdinaryDiffEqDAE/test/dae_event.jl | 30 -- .../test/dae_initialization_tests.jl | 268 ---------- .../test/dae_initialize_integration.jl | 78 --- lib/OrdinaryDiffEqDAE/test/hard_dae.jl | 275 ----------- lib/OrdinaryDiffEqDAE/test/runtest.jl | 2 - src/OrdinaryDiffEq.jl | 7 +- test/runtests.jl | 19 + 18 files changed, 34 insertions(+), 1757 deletions(-) delete mode 100644 lib/OrdinaryDiffEqDAE/Project.toml delete mode 100644 lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/controllers.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/dae_caches.jl delete mode 100644 lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_event.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/hard_dae.jl delete mode 100644 lib/OrdinaryDiffEqDAE/test/runtest.jl diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index 71900e4925..0ed740a489 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -426,6 +426,19 @@ function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = V nlsolve, precs, extrapolant, controller) end +#= +struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, + linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = + DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( + linsolve,nlsolve,precs,extrapolant) +=# struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} max_order::Val{MO} diff --git a/lib/OrdinaryDiffEqBDF/test/runtest.jl b/lib/OrdinaryDiffEqBDF/test/runtest.jl index 71d30a6a01..eaddde84ae 100644 --- a/lib/OrdinaryDiffEqBDF/test/runtest.jl +++ b/lib/OrdinaryDiffEqBDF/test/runtest.jl @@ -1,8 +1 @@ -using SafeTestsets - -@time @safetestset "DAE AD Tests" include("dae_ad_tests.jl") -@time @safetestset "DAE Initialize Integration" include("dae_initialize_integration.jl") -@time @safetestset "DAE Initialization Tests" include("dae_initialization_tests.jl") -@time @safetestset "DAE Event Tests" include("dae_event.jl") -@time @safetestset "Hard DAE Tests" include("hard_dae.jl") -@time @safetestset "DAE Convergence Tests" include("dae_convergence_tests.jl") +using SafeTestsets \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/Project.toml b/lib/OrdinaryDiffEqDAE/Project.toml deleted file mode 100644 index b15e3bbe39..0000000000 --- a/lib/OrdinaryDiffEqDAE/Project.toml +++ /dev/null @@ -1,21 +0,0 @@ -name = "OrdinaryDiffEqDAE" -uuid = "7d2d7016-1c68-401d-834f-6be2c6dc7d88" -authors = ["ParamThakkar123 "] -version = "1.0.0" - -[deps] -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[compat] -julia = "1.10" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl b/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl deleted file mode 100644 index 9017917bb8..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl +++ /dev/null @@ -1,20 +0,0 @@ -module OrdinaryDiffEqDAE - -import OrdinaryDiffEq: _unwrap_val, NLNewton, DAEAlgorithm, - DEFAULT_PRECS, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - @unpack, @cache, default_controller, stepsize_controller!, - step_accept_controller!, - step_reject_controller!, post_newton_controller! -using TruncatedStacktraces, MuladdMacro -import FastBroadcast: @.. - -include("algorithms.jl") -include("alg_utils.jl") -include("controllers.jl") -include("dae_caches.jl") -include("dae_perform_step.jl") - -export DABDF2, DImplicitEuler, DFBDF - -end # module OrdinaryDiffEqDAE diff --git a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl b/lib/OrdinaryDiffEqDAE/src/alg_utils.jl deleted file mode 100644 index ff0d60daac..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/alg_utils.jl +++ /dev/null @@ -1,12 +0,0 @@ -isadaptive(alg::DImplicitEuler) = true -isadaptive(alg::DABDF2) = true -isadaptive(alg::DFBDF) = true - -alg_extrapolates(alg::DImplicitEuler) = true -alg_extrapolates(alg::DABDF2) = true - -alg_order(alg::DImplicitEuler) = 1 -alg_order(alg::DABDF2) = 2 -alg_order(alg::DFBDF) = 1#dummy value - -isfsal(alg::DImplicitEuler) = false \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/algorithms.jl b/lib/OrdinaryDiffEqDAE/src/algorithms.jl deleted file mode 100644 index f8584348a5..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/algorithms.jl +++ /dev/null @@ -1,75 +0,0 @@ -struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DImplicitEuler(; - chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :Standard) - DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) -end - -#= -struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, - linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = - DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( - linsolve,nlsolve,precs,extrapolant) -=# - -struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - controller::Symbol -end -function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, controller = :Standard) where {MO} - DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, - controller) -end - -TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/controllers.jl b/lib/OrdinaryDiffEqDAE/src/controllers.jl deleted file mode 100644 index 4ae1a93a28..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/controllers.jl +++ /dev/null @@ -1,130 +0,0 @@ -function step_reject_controller!(integrator, ::DFBDF) - bdf_step_reject_controller!(integrator, integrator.cache.terkm1) -end - -function post_newton_controller!(integrator, alg) - integrator.dt = integrator.dt / integrator.opts.failfactor - nothing -end - -function post_newton_controller!(integrator, alg::DFBDF) - @unpack cache = integrator - if cache.order > 1 && cache.nlsolver.nfails >= 3 - cache.order -= 1 - end - integrator.dt = integrator.dt / integrator.opts.failfactor - integrator.cache.consfailcnt += 1 - integrator.cache.nconsteps = 0 - nothing -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqMutableCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache - k = cache.order - # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] - end - @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function choose_order!(alg::DFBDF, integrator, - cache::OrdinaryDiffEqConstantCache, - ::Val{max_order}) where {max_order} - @unpack t, dt, u, cache, uprev = integrator - @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache - k = cache.order - if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && - ((k == 1 && terk > terkp1) || - (k == 2 && terkm1 > terk > terkp1) || - (k > 2 && terkm2 > terkm1 > terk > terkp1)) - k += 1 - terk = terkp1 - else - while !(terkm2 > terkm1 > terk > terkp1) && k > 2 - terkp1 = terk - terk = terkm1 - terkm1 = terkm2 - fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, - Val(max_order)) - terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u - if u isa Number - for i in 2:(k - 2) - terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] - end - terk_tmp *= abs(dt^(k - 2)) - else - vc = _vec(terk_tmp) - for i in 2:(k - 2) - @.. broadcast=false @views vc += fd_weights[i, k - 2] * - u_history[:, i - 1] - end - terk_tmp = reshape(vc, size(terk_tmp)) - terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) - end - atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - terkm2 = integrator.opts.internalnorm(atmp, t) - k -= 1 - end - end - return k, terk -end - -function stepsize_controller!(integrator, - alg::DFBDF{max_order}) where { - max_order, -} - @unpack cache = integrator - cache.prev_order = cache.order - k, terk = choose_order!(alg, integrator, cache, Val(max_order)) - if k != cache.order - integrator.cache.nconsteps = 0 - cache.order = k - end - if iszero(terk) - q = inv(integrator.opts.qmax) - else - q = ((2 * terk / (k + 1))^(1 / (k + 1))) - end - integrator.qold = q - q -end - -function step_accept_controller!(integrator, alg::DFBDF{max_order}, - q) where {max_order} - integrator.cache.consfailcnt = 0 - if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min - q = one(q) - end - integrator.cache.nconsteps += 1 - integrator.cache.iters_from_event += 1 - return integrator.dt / q -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_caches.jl b/lib/OrdinaryDiffEqDAE/src/dae_caches.jl deleted file mode 100644 index c432408952..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/dae_caches.jl +++ /dev/null @@ -1,256 +0,0 @@ -@cache mutable struct DImplicitEulerCache{uType, rateType, uNoUnitsType, N} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - uprev2::uType - atmp::uNoUnitsType - k₁::rateType - k₂::rateType - nlsolver::N -end - -mutable struct DImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache - nlsolver::N -end - -function alg_cache(alg::DImplicitEuler, du, u, res_prototype, rate_prototype, - ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - α = 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(false)) - - DImplicitEulerConstantCache(nlsolver) -end - -function alg_cache(alg::DImplicitEuler, du, u, res_prototype, rate_prototype, - ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - α = 1 - k₁ = zero(rate_prototype) - k₂ = zero(rate_prototype) - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(true)) - - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - DImplicitEulerCache(u, uprev, uprev2, atmp, k₁, k₂, nlsolver) -end - -@cache mutable struct DABDF2ConstantCache{N, dtType, rate_prototype} <: - OrdinaryDiffEqConstantCache - nlsolver::N - eulercache::DImplicitEulerConstantCache - dtₙ₋₁::dtType - fsalfirstprev::rate_prototype -end - -function alg_cache(alg::DABDF2, du, u, res_prototype, rate_prototype, - ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 1, 1 - α = 1 // 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(false)) - eulercache = DImplicitEulerConstantCache(nlsolver) - - dtₙ₋₁ = one(dt) - fsalfirstprev = rate_prototype - - DABDF2ConstantCache(nlsolver, eulercache, dtₙ₋₁, fsalfirstprev) -end - -@cache mutable struct DABDF2Cache{uType, rateType, uNoUnitsType, N, dtType} <: - OrdinaryDiffEqMutableCache - uₙ::uType - uₙ₋₁::uType - uₙ₋₂::uType - fsalfirst::rateType - fsalfirstprev::rateType - atmp::uNoUnitsType - nlsolver::N - eulercache::DImplicitEulerCache - dtₙ₋₁::dtType -end - -function alg_cache(alg::DABDF2, du, u, res_prototype, rate_prototype, - ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 1, 1 - α = 1 // 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, res_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, α, Val(true)) - fsalfirst = zero(rate_prototype) - - fsalfirstprev = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - k₁ = zero(rate_prototype) - k₂ = zero(rate_prototype) - - eulercache = DImplicitEulerCache(u, uprev, uprev2, atmp, k₁, k₂, nlsolver) - - dtₙ₋₁ = one(dt) - - DABDF2Cache(u, uprev, uprev2, fsalfirst, fsalfirstprev, atmp, - nlsolver, eulercache, dtₙ₋₁) -end - -@cache mutable struct DFBDFConstantCache{MO, N, tsType, tType, uType, uuType, coeffType, - EEstType, rType, wType} <: - OrdinaryDiffEqConstantCache - nlsolver::N - ts::tsType - ts_tmp::tsType - t_old::tType - u_history::uuType - order::Int - prev_order::Int - u₀::uType - u_corrector::uuType - bdf_coeffs::coeffType - max_order::Val{MO} - nconsteps::Int - consfailcnt::Int - terkm2::EEstType - terkm1::EEstType - terk::EEstType - terkp1::EEstType - r::rType - weights::wType - iters_from_event::Int -end - -function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, - uprev, uprev2, f, t, dt, reltol, p, calck, ::Val{false}) where {MO} - γ, c = 1.0, 1.0 - max_order = MO - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - bdf_coeffs = SA[1 -1 0 0 0 0; - 2//3 -4//3 1//3 0 0 0; - 6//11 -18//11 9//11 -2//11 0 0; - 12//25 -48//25 36//25 -16//25 3//25 0; - 60//137 -300//137 300//137 -200//137 75//137 -12//137] - ts = zero(Vector{typeof(t)}(undef, max_order + 2)) #ts is the successful past points, it will be updated after successful step - ts_tmp = similar(ts) - - u_history = zero(Matrix{eltype(u)}(undef, length(u), max_order + 2)) - order = 1 - prev_order = 1 - u_corrector = similar(u_history) - recursivefill!(u_corrector, zero(eltype(u))) - recursivefill!(u_history, zero(eltype(u_history))) - terkm2 = tTypeNoUnits(1) - terkm1 = tTypeNoUnits(1) - terk = tTypeNoUnits(1) - terkp1 = tTypeNoUnits(1) - r = zero(Vector{typeof(t)}(undef, max_order + 2)) - weights = zero(Vector{typeof(t)}(undef, max_order + 2)) - weights[1] = 1 - nconsteps = 0 - consfailcnt = 0 - t_old = zero(t) - iters_from_event = 0 - u₀ = zero(u) - - DFBDFConstantCache(nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, u₀, - u_corrector, bdf_coeffs, Val(5), nconsteps, consfailcnt, terkm2, - terkm1, terk, terkp1, r, weights, iters_from_event) -end - -@cache mutable struct DFBDFCache{MO, N, rateType, uNoUnitsType, tsType, tType, uType, - uuType, coeffType, EEstType, rType, wType} <: - OrdinaryDiffEqMutableCache - fsalfirst::rateType - nlsolver::N - ts::tsType - ts_tmp::tsType - t_old::tType - u_history::uuType - order::Int - prev_order::Int - u_corrector::uuType - u₀::uType - bdf_coeffs::coeffType - max_order::Val{MO} - nconsteps::Int - consfailcnt::Int - tmp::uType - atmp::uNoUnitsType - terkm2::EEstType - terkm1::EEstType - terk::EEstType - terkp1::EEstType - terk_tmp::uType - terkp1_tmp::uType - r::rType - weights::wType - equi_ts::tsType - iters_from_event::Int -end - -function alg_cache(alg::DFBDF{MO}, du, u, res_prototype, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, - tTypeNoUnits, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {MO} - γ, c = 1.0, 1.0 - fsalfirst = zero(rate_prototype) - max_order = MO - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - #=bdf_coeffs = SA[1 -1 0 0 0 0 ; - 3//2 -2 1//2 0 0 0 ; - 11//6 -3 3//2 -1//3 0 0 ; - 25//12 -4 3 -4//3 1//4 0 ; - 137//60 -5 5 -10//3 5//4 -1//5]=# - bdf_coeffs = SA[1 -1 0 0 0 0; - 2//3 -4//3 1//3 0 0 0; - 6//11 -18//11 9//11 -2//11 0 0; - 12//25 -48//25 36//25 -16//25 3//25 0; - 60//137 -300//137 300//137 -200//137 75//137 -12//137] - ts = Vector{typeof(t)}(undef, max_order + 2) #ts is the successful past points, it will be updated after successful step - u_history = Matrix{eltype(u)}(undef, length(u), max_order + 2) - order = 1 - prev_order = 1 - u_corrector = similar(u_history) - recursivefill!(ts, zero(t)) - recursivefill!(u_corrector, zero(eltype(u))) - recursivefill!(u_history, zero(eltype(u_history))) - terkm2 = tTypeNoUnits(1) - terkm1 = tTypeNoUnits(1) - terk = tTypeNoUnits(1) - terkp1 = tTypeNoUnits(1) - terk_tmp = similar(u) - terkp1_tmp = similar(u) - r = Vector{typeof(t)}(undef, max_order + 2) - weights = Vector{typeof(t)}(undef, max_order + 2) - recursivefill!(r, zero(t)) - recursivefill!(weights, zero(t)) - weights[1] = 1 - nconsteps = 0 - consfailcnt = 0 - t_old = zero(t) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, zero(uEltypeNoUnits)) - u₀ = similar(u) - equi_ts = similar(ts) - tmp = similar(u) - ts_tmp = similar(ts) - iters_from_event = 0 - - DFBDFCache(fsalfirst, nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, - u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, - terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, - iters_from_event) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl b/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl deleted file mode 100644 index 4b4eab7e71..0000000000 --- a/lib/OrdinaryDiffEqDAE/src/dae_perform_step.jl +++ /dev/null @@ -1,460 +0,0 @@ -function initialize!(integrator, cache::DImplicitEulerConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.k[1] = integrator.du -end - -function initialize!(integrator, cache::DImplicitEulerCache) - integrator.kshortsize = 2 - @unpack k₁, k₂ = cache - resize!(integrator.k, integrator.kshortsize) - integrator.k .= [k₁, k₂] - integrator.k[1] .= integrator.du - nothing -end - -@muladd function perform_step!(integrator, cache::DImplicitEulerConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack nlsolver = cache - - nlsolver.z = zero(u) - nlsolver.tmp = zero(u) - nlsolver.γ = 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = uprev + z - - if integrator.opts.adaptive && integrator.success_iter > 0 - # local truncation error (LTE) bound by dt^2/2*max|y''(t)| - # use 2nd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s - - tmp = r * - integrator.opts.internalnorm.((u - uprev) / dt1 - (uprev - uprev2) / dt2, t) - atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - else - integrator.EEst = 1 - end - - integrator.u = u - integrator.du = (u - uprev) / dt - - if integrator.opts.calck - integrator.k[2] = integrator.k[1] - integrator.k[1] = integrator.du - end -end - -@muladd function perform_step!(integrator, cache::DImplicitEulerCache, repeat_step = false) - @unpack t, dt, uprev, du, u, f, p = integrator - @unpack atmp, nlsolver = cache - @unpack tmp = nlsolver - - @. nlsolver.z = false - @. nlsolver.tmp = false - nlsolver.γ = 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=uprev + z - @.. broadcast=false du=z * inv(dt) - - if integrator.opts.adaptive && integrator.success_iter > 0 - # local truncation error (LTE) bound by dt^2/2*max|y''(t)| - # use 2nd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s - - @.. broadcast=false tmp=r * integrator.opts.internalnorm( - (u - uprev) / dt1 - - (uprev - uprev2) / dt2, t) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - else - integrator.EEst = 1 - end - - if integrator.opts.calck - integrator.k[2] .= integrator.k[1] - integrator.k[1] .= du - end -end - -function initialize!(integrator, cache::DABDF2ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.k[1] = integrator.du -end - -@muladd function perform_step!(integrator, cache::DABDF2ConstantCache, repeat_step = false) - @unpack t, f, p = integrator - @unpack dtₙ₋₁, nlsolver = cache - dtₙ, uₙ, uₙ₋₁, uₙ₋₂ = integrator.dt, integrator.u, integrator.uprev, integrator.uprev2 - - if integrator.iter == 1 && !integrator.u_modified - cache.dtₙ₋₁ = dtₙ - perform_step!(integrator, cache.eulercache, repeat_step) - integrator.fsalfirst = @.. broadcast=false (integrator.u - integrator.uprev)/dtₙ - cache.fsalfirstprev = integrator.fsalfirst - return - end - - # precalculations - ρ = dtₙ / dtₙ₋₁ - c1 = ρ^2 / (1 + 2ρ) - - nlsolver.γ = (1 + ρ) / (1 + 2ρ) - nlsolver.α = 1 // 1 - - nlsolver.z = zero(uₙ) - - nlsolver.tmp = -c1 * uₙ₋₁ + c1 * uₙ₋₂ - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - uₙ = uₙ₋₁ + z - integrator.fsallast = @.. broadcast=false z/dtₙ - - if integrator.opts.adaptive - tmp = integrator.fsallast - (1 + dtₙ / dtₙ₋₁) * integrator.fsalfirst + - (dtₙ / dtₙ₋₁) * cache.fsalfirstprev - est = (dtₙ₋₁ + dtₙ) / 6 * tmp - atmp = calculate_residuals(est, uₙ₋₁, uₙ, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - ################################### Finalize - - if integrator.EEst < one(integrator.EEst) - cache.fsalfirstprev = integrator.fsalfirst - cache.dtₙ₋₁ = dtₙ - end - - integrator.u = uₙ - integrator.du = du = (nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dtₙ) - - if integrator.opts.calck - integrator.k[2] = integrator.k[1] - integrator.k[1] = integrator.du - end - return -end - -function initialize!(integrator, cache::DABDF2Cache) - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - - integrator.kshortsize = 2 - @unpack k₁, k₂ = cache.eulercache - resize!(integrator.k, integrator.kshortsize) - integrator.k .= [k₁, k₂] - integrator.k[1] .= integrator.du - nothing -end - -@muladd function perform_step!(integrator, cache::DABDF2Cache, repeat_step = false) - @unpack t, dt, du, f, p = integrator - @unpack atmp, dtₙ₋₁, nlsolver = cache - @unpack z, tmp = nlsolver - uₙ, uₙ₋₁, uₙ₋₂, dtₙ = integrator.u, integrator.uprev, integrator.uprev2, integrator.dt - - if integrator.iter == 1 && !integrator.u_modified - cache.dtₙ₋₁ = dtₙ - perform_step!(integrator, cache.eulercache, repeat_step) - @.. broadcast=false integrator.fsalfirst=(uₙ - uₙ₋₁) / dt - cache.fsalfirstprev .= integrator.fsalfirst - return - end - - # precalculations - ρ = dtₙ / dtₙ₋₁ - c1 = ρ^2 / (1 + 2ρ) - - nlsolver.γ = (1 + ρ) / (1 + 2ρ) - nlsolver.α = 1 // 1 - @.. broadcast=false nlsolver.tmp=-c1 * uₙ₋₁ + c1 * uₙ₋₂ - nlsolver.z .= zero(eltype(z)) - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false uₙ=uₙ₋₁ + z - @.. broadcast=false du=(nlsolver.α * z + nlsolver.tmp) * inv(nlsolver.γ * dt) - - @.. broadcast=false integrator.fsallast=du - integrator.stats.nf += 1 - if integrator.opts.adaptive - btilde0 = (dtₙ₋₁ + dtₙ) * 1 // 6 - btilde1 = 1 + ρ - btilde2 = ρ - @.. broadcast=false tmp=btilde0 * - (integrator.fsallast - btilde1 * integrator.fsalfirst + - btilde2 * cache.fsalfirstprev) - calculate_residuals!(atmp, tmp, uₙ₋₁, uₙ, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - ################################### Finalize - - if integrator.EEst < one(integrator.EEst) - @.. broadcast=false cache.fsalfirstprev=integrator.fsalfirst - cache.dtₙ₋₁ = dtₙ - end - return -end - -function initialize!(integrator, cache::DFBDFConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.du, integrator.uprev, integrator.p, - integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::DFBDFConstantCache{max_order}, - repeat_step = false) where {max_order} - @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, ts_tmp, iters_from_event, nconsteps = cache - @unpack t, dt, u, f, p, uprev = integrator - - k = order - reinitFBDF!(integrator, cache) - cache.u₀ = zero(u) - if iters_from_event >= 1 - cache.u₀ = calc_Lagrange_interp(k, weights, t + dt, ts, u_history, cache.u₀) - else - cache.u₀ = u - end - markfirststage!(nlsolver) - equi_ts = zeros(k - 1) - for i in 1:(k - 1) - equi_ts[i] = t - dt * i - end - - fill!(u_corrector, zero(eltype(u))) - if u isa Number - for i in 1:(k - 1) - u_corrector[i] = calc_Lagrange_interp(k, weights, equi_ts[i], ts, u_history, - u_corrector[i]) - end - tmp = uprev * bdf_coeffs[k, 2] - for i in 1:(k - 1) - tmp += u_corrector[i] * bdf_coeffs[k, i + 2] - end - else - for i in 1:(k - 1) - @.. broadcast=false @views u_corrector[:, i] = $calc_Lagrange_interp( - k, weights, - equi_ts[i], - ts, - u_history, - u_corrector[:, - i]) - end - tmp = uprev * bdf_coeffs[k, 2] - vc = _vec(tmp) - for i in 1:(k - 1) - vc += @.. broadcast=false u_corrector[:, i]*bdf_coeffs[k, i + 2] - end - tmp = reshape(vc, size(tmp)) - end - - nlsolver.tmp = tmp + cache.u₀ - nlsolver.z = zero(nlsolver.z) - nlsolver.γ = bdf_coeffs[k, 1] - nlsolver.α = 1 // 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = z + cache.u₀ - - for j in 2:k - r[j] = (1 - j) - for i in 2:(k + 1) - r[j] *= ((t + dt - j * dt) - ts[i]) / (i * dt) - end - end - - terkp1 = z - for j in 1:(k + 1) - terkp1 *= j * dt / (t + dt - ts[j]) - end - - lte = -1 / (1 + k) - for j in 2:k - lte -= (bdf_coeffs[k, j] // bdf_coeffs[k, 1]) * r[j] - end - lte *= terkp1 - - if integrator.opts.adaptive - for i in 1:(k + 1) - ts_tmp[i + 1] = ts[i] - end - ts_tmp[1] = t + dt - atmp = calculate_residuals(_vec(lte), _vec(uprev), _vec(u), integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - - terk = estimate_terk(integrator, cache, k + 1, Val(max_order), u) - atmp = calculate_residuals( - _vec(terk), _vec(uprev), _vec(u), integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - cache.terk = integrator.opts.internalnorm(atmp, t) - - if k > 1 - terkm1 = estimate_terk(integrator, cache, k, Val(max_order), u) - atmp = calculate_residuals(_vec(terkm1), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm1 = integrator.opts.internalnorm(atmp, t) - end - if k > 2 - terkm2 = estimate_terk(integrator, cache, k - 1, Val(max_order), u) - atmp = calculate_residuals(_vec(terkm2), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm2 = integrator.opts.internalnorm(atmp, t) - end - if nconsteps > k + 1 && k < max_order - atmp = calculate_residuals(_vec(terkp1), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkp1 = integrator.opts.internalnorm(atmp, t) - else - cache.terkp1 = zero(cache.terk) - end - end - integrator.u = u - integrator.fsallast = integrator.du = (nlsolver.α * z + nlsolver.tmp) * - inv(nlsolver.γ * dt) -end - -function initialize!(integrator, cache::DFBDFCache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - #integrator.f(integrator.fsalfirst, integrator.du, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - #integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::DFBDFCache{max_order}, - repeat_step = false) where {max_order} - @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, terk_tmp, terkp1_tmp, atmp, tmp, equi_ts, u₀, ts_tmp = cache - @unpack t, dt, u, f, p, uprev = integrator - - reinitFBDF!(integrator, cache) - k = order - @.. broadcast=false u₀=zero(u) - if cache.iters_from_event >= 1 - calc_Lagrange_interp!(k, weights, t + dt, ts, u_history, u₀) - else - @.. broadcast=false u₀=u - end - markfirststage!(nlsolver) - - for i in 1:(k - 1) - equi_ts[i] = t - dt * i - end - - fill!(u_corrector, zero(eltype(u))) - for i in 1:(k - 1) - @views calc_Lagrange_interp!(k, weights, equi_ts[i], ts, u_history, - u_corrector[:, i]) - end - - @.. broadcast=false tmp=uprev * bdf_coeffs[k, 2] - vc = _vec(tmp) - for i in 1:(k - 1) - @.. broadcast=false @views vc += u_corrector[:, i] * bdf_coeffs[k, i + 2] - end - - @.. broadcast=false nlsolver.tmp=tmp + u₀ - @.. broadcast=false nlsolver.z=zero(eltype(nlsolver.z)) - nlsolver.γ = bdf_coeffs[k, 1] - nlsolver.α = 1 // 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=z + u₀ - - for j in 2:k - r[j] = (1 - j) - for i in 2:(k + 1) - r[j] *= ((t + dt - j * dt) - ts[i]) / (i * dt) - end - end - - @.. broadcast=false terkp1_tmp=z - for j in 1:(k + 1) - @.. broadcast=false terkp1_tmp*=j * dt / (t + dt - ts[j]) - end - - lte = -1 / (1 + k) - for j in 2:k - lte -= (bdf_coeffs[k, j] // bdf_coeffs[k, 1]) * r[j] - end - @.. broadcast=false terk_tmp=lte * terkp1_tmp - if integrator.opts.adaptive - @unpack abstol, reltol, internalnorm = integrator.opts - for i in 1:(k + 1) - ts_tmp[i + 1] = ts[i] - end - ts_tmp[1] = t + dt - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, - internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - estimate_terk!(integrator, cache, k + 1, Val(max_order)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, - internalnorm, t) - cache.terk = integrator.opts.internalnorm(atmp, t) - - if k > 1 - estimate_terk!(integrator, cache, k, Val(max_order)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm1 = integrator.opts.internalnorm(atmp, t) - end - if k > 2 - estimate_terk!(integrator, cache, k - 1, Val(max_order)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm2 = integrator.opts.internalnorm(atmp, t) - end - if cache.nconsteps > k + 1 && k < max_order - calculate_residuals!(atmp, _vec(terkp1_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkp1 = integrator.opts.internalnorm(atmp, t) - else - cache.terkp1 = zero(cache.terkp1) - end - end - @.. broadcast=false integrator.fsallast=integrator.du = (nlsolver.α * z + - nlsolver.tmp) * - inv(nlsolver.γ * dt) #TODO Lorenz plot seems not smooth -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl deleted file mode 100644 index 398aa310be..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl +++ /dev/null @@ -1,60 +0,0 @@ -using OrdinaryDiffEq, LinearAlgebra, ForwardDiff, Test - -function rober(du, u, p, t) - y₁, y₂, y₃ = u - k₁, k₂, k₃ = p - du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ - du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du[3] = y₁ + y₂ + y₃ - 1 - nothing -end -function rober(u, p, t) - y₁, y₂, y₃ = u - k₁, k₂, k₃ = p - [-k₁ * y₁ + k₃ * y₂ * y₃, - k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2, - y₁ + y₂ + y₃ - 1] -end -M = [1.0 0 0 - 0 1.0 0 - 0 0 0] -roberf = ODEFunction(rober, mass_matrix = M) -roberf_oop = ODEFunction{false}(rober, mass_matrix = M) -prob_mm = ODEProblem(roberf, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) -prob_mm_oop = ODEProblem(roberf_oop, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rodas5P(), reltol = 1e-8, abstol = 1e-8) -sol = solve(prob_mm_oop, Rodas5P(), reltol = 1e-8, abstol = 1e-8) - -function f(out, du, u, p, t) - out[1] = -p[1] * u[1] + p[3] * u[2] * u[3] - du[1] - out[2] = +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2] - out[3] = u[1] + u[2] + u[3] - 1.0 -end -function f(du, u, p, t) - [-p[1] * u[1] + p[3] * u[2] * u[3] - du[1], - +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2], - u[1] + u[2] + u[3] - 1.0] -end -p = [0.04, 3e7, 1e4] -u₀ = [1.0, 0, 0] -du₀ = [-0.04, 0.04, 0.0] -tspan = (0.0, 100000.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) -prob_oop = DAEProblem{false}(f, du₀, u₀, tspan, p, differential_vars = differential_vars) -sol1 = solve(prob, DFBDF(), dt = 1e-5, abstol = 1e-8, reltol = 1e-8) - -# These tests flex differentiation of the solver and through the initialization -# To only test the solver part and isolate potential issues, set the initialization to consistent -@testset "Inplace: $(isinplace(_prob)), DAEProblem: $(_prob isa DAEProblem), BrownBasic: $(initalg isa BrownFullBasicInit), Autodiff: $autodiff" for _prob in [ - prob, prob_mm, prob_oop, prob_mm_oop], - initalg in [BrownFullBasicInit(), ShampineCollocationInit()], autodiff in [true, false] - - alg = _prob isa DAEProblem ? DFBDF(; autodiff) : Rodas5P(; autodiff) - function f(p) - sol = solve(remake(_prob, p = p), alg, abstol = 1e-14, - reltol = 1e-14, initializealg = initalg) - sum(sol) - end - @test ForwardDiff.gradient(f, [0.04, 3e7, 1e4])≈[0, 0, 0] atol=1e-8 -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl deleted file mode 100644 index e3ef2dd474..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl +++ /dev/null @@ -1,56 +0,0 @@ -using OrdinaryDiffEq, DiffEqDevTools -using Test, Random -Random.seed!(100) - -dts = 1 .// 2 .^ (9:-1:5) -testTol = 0.2 - -f_dae_linear = (res, du, u, p, t) -> (@. res = du - u) -f_dae_linear_analytic = (du0, u0, p, t) -> @. u0 * exp(t) -prob_dae_linear_iip = DAEProblem( - DAEFunction(f_dae_linear; - analytic = f_dae_linear_analytic), - [1.0, 1.0], [1.0, 1.0], (0.0, 1.0)) - -@testset "DAE Solver Convergence Tests (in-place)" begin - prob = prob_dae_linear_iip - - sim11 = test_convergence(dts, prob, DImplicitEuler()) - @test sim11.𝒪est[:final]≈1 atol=testTol - - sim12 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) - @test sim12.𝒪est[:final]≈1 atol=testTol - - sim13 = test_convergence(dts, prob, DABDF2()) - @test sim13.𝒪est[:final]≈2 atol=testTol - - sim14 = test_convergence(dts, prob, DABDF2(; autodiff = false)) - @test sim14.𝒪est[:final]≈2 atol=testTol - - @test_nowarn solve(prob, DFBDF()) -end - -f_dae_linear = (du, u, p, t) -> (@. du - u) -f_dae_linear_analytic = (du0, u0, p, t) -> @. u0 * exp(t) -prob_dae_linear_oop = DAEProblem( - DAEFunction(f_dae_linear; - analytic = f_dae_linear_analytic), - 1.0, 1.0, (0.0, 1.0)) - -@testset "DAE Solver Convergence Tests (out-of-place)" begin - prob = prob_dae_linear_oop - - sim21 = test_convergence(dts, prob, DImplicitEuler()) - @test sim21.𝒪est[:final]≈1 atol=testTol - - sim22 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) - @test sim22.𝒪est[:final]≈1 atol=testTol - - sim23 = test_convergence(dts, prob, DABDF2()) - @test sim23.𝒪est[:final]≈2 atol=testTol - - sim24 = test_convergence(dts, prob, DABDF2(; autodiff = false)) - @test sim24.𝒪est[:final]≈2 atol=testTol - - @test_nowarn solve(prob, DFBDF()) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_event.jl b/lib/OrdinaryDiffEqDAE/test/dae_event.jl deleted file mode 100644 index c20b600670..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_event.jl +++ /dev/null @@ -1,30 +0,0 @@ -using OrdinaryDiffEq, Test - -f = function (out, du, u, p, t) - out[1] = -p[1] * u[1] + p[3] * u[2] * u[3] - du[1] - out[2] = +p[1] * u[1] - p[2] * u[2]^2 - p[3] * u[2] * u[3] - du[2] - out[3] = u[1] + u[2] + u[3] - p[4] -end -u₀ = [1.0, 0, 0] -du₀ = [0.0, 0.0, 0.0] -p = [0.04, 3.0e7, 1.0e4, 1.0] -tspan = (0.0, 100.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) -condition(u, t, integrator) = t in [50.0] -affect!(integrator) = integrator.p[4] = 2.0 -cb = DiscreteCallback(condition, affect!) - -#= -# Regression test -using Sundials -sol = solve(prob, IDA(), callback=cb, tstops=[50.0],abstol=1e-14,reltol=1e-14) -=# - -p = [0.04, 3.0e7, 1.0e4, 1.0] -prob = DAEProblem(f, du₀, u₀, tspan, p, differential_vars = differential_vars) -sol = solve(prob, DFBDF(), callback = cb, tstops = [50.0], abstol = 1e-12, reltol = 1e-12) -@test sol.t[end] == 100.0 -@test sol[end][1]≈0.686300529575259 atol=1e-7 -@test sol[end][2]≈2.0797982209353813e-6 atol=1e-7 -@test sol[end][3]≈1.31369739062652 atol=1e-7 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl deleted file mode 100644 index 5cf37c27f4..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl +++ /dev/null @@ -1,268 +0,0 @@ -using OrdinaryDiffEq, StaticArrays, LinearAlgebra, Test - -## Mass Matrix - -function rober_oop(u, p, t) - y₁, y₂, y₃ = u - k₁, k₂, k₃ = p - du1 = -k₁ * y₁ + k₃ * y₂ * y₃ - du2 = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du3 = y₁ + y₂ + y₃ - 1 - [du1, du2, du3] -end -M = [1.0 0 0 - 0 1.0 0 - 0 0 0] -f_oop = ODEFunction(rober_oop, mass_matrix = M) -prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rosenbrock23(autodiff = false), reltol = 1e-8, abstol = 1e-8) -@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! -sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8, - initializealg = ShampineCollocationInit()) -@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! - -prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8) -@test sum(sol[1]) ≈ 1 -@test sol[1] ≈ [1.0, 0.0, 0.0] -for alg in [Rosenbrock23(autodiff = false), Trapezoid()] - local sol - sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, - initializealg = ShampineCollocationInit()) - @test sum(sol[1]) ≈ 1 -end - -function rober(du, u, p, t) - y₁, y₂, y₃ = u - k₁, k₂, k₃ = p - du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ - du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du[3] = y₁ + y₂ + y₃ - 1 - nothing -end -M = [1.0 0 0 - 0 1.0 0 - 0 0 0] -f = ODEFunction(rober, mass_matrix = M) -prob_mm = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rodas5(autodiff = false), reltol = 1e-8, abstol = 1e-8) -@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! -sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8, - initializealg = ShampineCollocationInit()) -@test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! - -prob_mm = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8) -@test sum(sol[1]) ≈ 1 -@test sol[1] ≈ [1.0, 0.0, 0.0] - -for alg in [Rodas5(autodiff = false), Trapezoid()] - local sol - sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, - initializealg = ShampineCollocationInit()) - @test sum(sol[1]) ≈ 1 -end - -function rober_no_p(du, u, p, t) - y₁, y₂, y₃ = u - (k₁, k₂, k₃) = (0.04, 3e7, 1e4) - du[1] = -k₁ * y₁ + k₃ * y₂ * y₃ - du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du[3] = y₁ + y₂ + y₃ - 1 - nothing -end - -function rober_oop_no_p(du, u, p, t) - y₁, y₂, y₃ = u - (k₁, k₂, k₃) = (0.04, 3e7, 1e4) - du1 = -k₁ * y₁ + k₃ * y₂ * y₃ - du2 = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2 - du3 = y₁ + y₂ + y₃ - 1 - [du1, du2, du3] -end - -# test oop and iip ODE initialization with parameters without eltype/length -struct UnusedParam -end -for f in ( - ODEFunction(rober_no_p, mass_matrix = M), ODEFunction(rober_oop_no_p, mass_matrix = M)) - local prob, probp - prob = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5)) - probp = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5), UnusedParam) - for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) - isapprox(init(prob, Rodas5(), abstol = 1e-10; initializealg).u, - init(prob, Rodas5(), abstol = 1e-10; initializealg).u) - end -end - -## DAEProblem - -f = function (du, u, p, t) - out1 = -0.04u[1] + 1e4 * u[2] * u[3] - du[1] - out2 = +0.04u[1] - 3e7 * u[2]^2 - 1e4 * u[2] * u[3] - du[2] - out3 = u[1] + u[2] + u[3] - 1.0 - [out1, out2, out3] -end - -u₀ = [1.0, 0, 0] -du₀ = [0.0, 0.0, 0.0] -tspan = (0.0, 100000.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -integrator = init(prob, DImplicitEuler()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -integrator = init(prob, DFBDF()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -u₀ = [1.0, 0, 0.2] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) -@test integrator.u≈[1.0, 0, 0.0] atol=1e-9 -integrator = init(prob, DABDF2(), initializealg = ShampineCollocationInit()) -@test !(integrator.u ≈ [1.0, 0, 0.0]) - -u₀ = [1.0, 0, 0.2] -prob = DAEProblem(f, du₀, u₀, tspan) -integrator = init(prob, DABDF2()) -@test !(integrator.u ≈ [1.0, 0, 0.0]) - -f = function (out, du, u, p, t) - out[1] = -0.04u[1] + 1e4 * u[2] * u[3] - du[1] - out[2] = +0.04u[1] - 3e7 * u[2]^2 - 1e4 * u[2] * u[3] - du[2] - out[3] = u[1] + u[2] + u[3] - 1.0 -end - -u₀ = [1.0, 0, 0] -du₀ = [0.0, 0.0, 0.0] -tspan = (0.0, 100000.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) -integrator2 = init(prob, DABDF2(autodiff = false)) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -@test integrator2.du[1]≈-0.04 atol=1e-99 -@test integrator2.du[2]≈0.04 atol=1e-9 -@test integrator2.u≈u₀ atol=1e-9 - -integrator = init(prob, DImplicitEuler()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -integrator = init(prob, DFBDF()) - -@test integrator.du[1]≈-0.04 atol=1e-9 -@test integrator.du[2]≈0.04 atol=1e-9 -@test integrator.u≈u₀ atol=1e-9 - -u₀ = [1.0, 0, 0.2] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) -@test integrator.u≈[1.0, 0, 0.0] atol=1e-9 -integrator = init(prob, DABDF2(), initializealg = ShampineCollocationInit()) -@test !(integrator.u ≈ [1.0, 0, 0.0]) - -u₀ = [1.0, 0, 0.2] -prob = DAEProblem(f, du₀, u₀, tspan) -integrator = init(prob, DABDF2()) -@test !(integrator.u ≈ [1.0, 0, 0.0]) - -# Need to be able to find the consistent solution of this problem, broken right now -# analytical solution: -# u[1](t) -> cos(t) -# u[2](t) -> -sin(t) -# u[3](t) -> 2cos(t) -f = function (out, du, u, p, t) - out[1] = du[1] - u[2] - out[2] = du[2] + u[3] - cos(t) - out[3] = u[1] - cos(t) -end - -u₀ = [1.0, 0.0, 0.0] -du₀ = [0.0, 0.0, 0.0] -tspan = (0.0, 1.0) -differential_vars = [true, true, false] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2(); initializealg = ShampineCollocationInit()) - -@test integrator.du[1]≈0.0 atol=1e-9 -@test_broken integrator.du[2]≈-1.0 atol=1e-9 -@test_broken integrator.u[3]≈2.0 atol=1e-9 - -# test iip dae initialization with parameters without eltype/length -probp = DAEProblem(f, du₀, u₀, tspan, UnusedParam(), differential_vars = differential_vars) -for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) - @test isapprox( - init(probp, DABDF2(); initializealg).u, init(prob, DABDF2(); initializealg).u) -end - -f = function (du, u, p, t) - du - u -end - -u₀ = SVector(1.0) -du₀ = SVector(0.0) -tspan = (0.0, 1.0) -differential_vars = SVector(true) -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) - -@test integrator.du≈[1.0] atol=1e-9 - -f = function (du, u, p, t) - du .- u -end - -u₀ = SA[1.0, 1.0] -du₀ = SA[0.0, 0.0] -tspan = (0.0, 1.0) -differential_vars = [true, true] -prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) -integrator = init(prob, DABDF2()) - -@test integrator.du[1]≈1.0 atol=1e-9 -@test integrator.du[2]≈1.0 atol=1e-9 -# test oop DAE initialization with parameters without eltype/length -probp = DAEProblem(f, du₀, u₀, tspan, UnusedParam(), differential_vars = differential_vars) -for initializealg in (ShampineCollocationInit(), BrownFullBasicInit()) - @test isapprox( - init(probp, DABDF2(); initializealg).u, init(prob, DABDF2(); initializealg).u) -end - -# to test that we get the right NL solve we need a broken solver. -struct BrokenNLSolve <: SciMLBase.AbstractNonlinearAlgorithm - BrokenNLSolve(; kwargs...) = new() -end -function SciMLBase.__solve(prob::NonlinearProblem, - alg::BrokenNLSolve, args...; - kwargs...) - u = fill(reinterpret(Float64, 0xDEADBEEFDEADBEEF), 3) - SciMLBase.build_solution(prob, alg, u, copy(u); - retcode = ReturnCode.Success) -end -function f2(u, p, t) - u -end -f = ODEFunction(f2, mass_matrix = Diagonal([1.0, 1.0, 0.0])) -prob = ODEProblem(f, ones(3), (0.0, 1.0)) -integrator = init(prob, Rodas5P(), - initializealg = ShampineCollocationInit(1.0, BrokenNLSolve())) -@test all(isequal(reinterpret(Float64, 0xDEADBEEFDEADBEEF)), integrator.u) \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl b/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl deleted file mode 100644 index 33913925e2..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl +++ /dev/null @@ -1,78 +0,0 @@ -using ModelingToolkit, OrdinaryDiffEq, Test - -@parameters t g e b -@variables v(t) w(t) F(t) -@derivatives D' ~ t -single_neuron_eqs = [ - D(v) ~ min(max(-2 - v, v), 2 - v) - w + F, # add the flux term - D(w) ~ e * (v - g * w + b) -] -n1 = ODESystem(single_neuron_eqs, t, [v, w, F], [g, e, b], name = :n1) -n2 = ODESystem(single_neuron_eqs, t, [v, w, F], [g, e, b], name = :n2) -@parameters D Dk -connections = [0 ~ n1.F - D * Dk * max(n1.v - n2.v, 0) - 0 ~ n2.F - D * max(n2.v - n1.v, 0)] -connected = ODESystem(connections, t, [], [D, Dk], systems = [n1, n2], name = :connected) -connected = complete(connected) - -u0 = [ - n1.v => -2, - n1.w => -2 / 3, - n1.F => 0, - n2.v => -2, - n2.w => -0.7, - n2.F => 0 -] -tspan = (0.0, 1750.0) -p0 = [ - n1.g => 0.8, - n1.e => 0.04, - n1.b => 0, - n2.g => 0.8, - n2.e => 0.04, - n2.b => 0.2, - D => 0.047, - Dk => 1 -] - -prob = ODEProblem(connected, u0, tspan, p0) -sol = solve(prob, Rodas5(), initializealg = BrownFullBasicInit()) -@test prob.u0 == sol[1] -sol = solve(prob, Rodas5(), initializealg = ShampineCollocationInit()) -@test prob.u0 == sol[1] -#test initialization when given a specific nonlinear solver -using NonlinearSolve -sol = solve(prob, Rodas5(), initializealg = BrownFullBasicInit(1e-10, RobustMultiNewton())) -@test prob.u0 == sol[1] - -# Initialize on ODEs -# https://github.com/SciML/ModelingToolkit.jl/issues/2508 - -function testsys(du, u, p, t) - du[1] = -2 -end -function initsys(du, u, p) - du[1] = -1 + u[1] -end -nlprob = NonlinearProblem(initsys, [0.0]) -initprobmap(nlprob) = nlprob.u -sol = solve(nlprob) - -_f = ODEFunction(testsys; initializeprob = nlprob, initializeprobmap = initprobmap) -prob = ODEProblem(_f, [0.0], (0.0, 1.0)) -sol = solve(prob, Tsit5()) -@test SciMLBase.successful_retcode(sol) -@test sol[1] == [1.0] - -prob = ODEProblem(_f, [0.0], (0.0, 1.0)) -sol = solve(prob, Tsit5(), dt = 1e-10) -@test SciMLBase.successful_retcode(sol) -@test sol[1] == [1.0] -@test sol[2] ≈ [0.9999999998] -@test sol[end] ≈ [-1.0] - -sol = solve(prob, Rodas5P(), dt = 1e-10) -@test SciMLBase.successful_retcode(sol) -@test sol[1] == [1.0] -@test sol[2] ≈ [0.9999999998] -@test sol[end] ≈ [-1.0] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/hard_dae.jl b/lib/OrdinaryDiffEqDAE/test/hard_dae.jl deleted file mode 100644 index f47b226ce1..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/hard_dae.jl +++ /dev/null @@ -1,275 +0,0 @@ -using OrdinaryDiffEq -using LinearAlgebra -using NLsolve -using Test - -p_inv = [500.0 - 0.084 - 4.69 - 2.0 - 400.0 - 20.0 - 0.2 - 1000.0 - 0.59 - 736.0 - 0.0 - 0.0 - 0.2 - 1.27 - 14.3 - 0.0 - 50.0 - 0.2 - 0.08 - 0.003 - 0.074 - 0.2 - 0.01 # Matt - 1.0 # V_ref - 1.0 # ω ref - 0.7 # Pref - 0 # Q_ref - 0.5 #Xtrans - 0.0 # Rtrans - 1.01 #Vm - 0.0] # Vθ - -function vsm(dx, x, p, t) - #PARAMETERS - ω_lp = p[1] - kp_pll = p[2] - ki_pll = p[3] - Ta = p[4] - kd = p[5] - kω = p[6] - kq = p[7] - ωf = p[8] - kpv = p[9] - kiv = p[10] - kffv = p[11] - rv = p[12] - lv = p[13] - kpc = p[14] - kic = p[15] - kffi = p[16] - ωad = p[17] - kad = p[18] - lf = p[19] - rf = p[20] - cf = p[21] - lg = p[22] - rg = p[23] - Vref = p[24] - ωref = p[25] - Pref = p[26] - Qref = p[27] - Xtrans = p[28] - Rtrans = p[29] - Vm = p[30] - Vθ = p[31] - - #STATE INDEX AND STATES - i__vi_filter, vi_filter = 1, x[1] - i__γd_ic, γd_ic = 2, x[2] - i__vq_pll, vq_pll = 3, x[3] - i__γq_ic, γq_ic = 4, x[4] - i__ir_filter, ir_filter = 5, x[5] - i__ξd_ic, ξd_ic = 6, x[6] - i__ϕd_ic, ϕd_ic = 7, x[7] - i__ε_pll, ε_pll = 8, x[8] - i__ir_cnv, ir_cnv = 9, x[9] - i__vr_filter, vr_filter = 10, x[10] - i__ω_oc, ω_oc = 11, x[11] - i__ξq_ic, ξq_ic = 12, x[12] - i__vd_pll, vd_pll = 13, x[13] - i__q_oc, q_oc = 14, x[14] - i__ϕq_ic, ϕq_ic = 15, x[15] - i__θ_pll, θ_pll = 16, x[16] - i__θ_oc, θ_oc = 17, x[17] - i__ii_cnv, ii_cnv = 18, x[18] - i__ii_filter, ii_filter = 19, x[19] - i__ir_source, ir_source = 20, x[20] - i__ii_source, ii_source = 21, x[21] - - ω_base = 60.0 * 2 * pi - ω_sys = 1.0 - - #PLL - δω_pll = kp_pll * atan(vq_pll / vd_pll) + ki_pll * ε_pll - ω_pll = δω_pll + ω_sys - vd_filt_pll = sin(θ_pll + pi / 2) * vr_filter - cos(θ_pll + pi / 2) * vi_filter - vq_filt_pll = cos(θ_pll + pi / 2) * vr_filter + sin(θ_pll + pi / 2) * vi_filter - - dx[i__vd_pll] = ω_lp * (vd_filt_pll - vd_pll) #docs:(1a) - dx[i__vq_pll] = ω_lp * (vq_filt_pll - vq_pll) #docs:(1b) - dx[i__ε_pll] = atan(vq_pll / vd_pll) #docs:(1c) - dx[i__θ_pll] = ω_base * δω_pll #docs:(1d) - - #OUTER LOOP CONTROL - pe = vr_filter * ir_filter + vi_filter * ii_filter #docs:(2d) - qe = vi_filter * ir_filter - vr_filter * ii_filter #docs:(2e) - v_ref_olc = Vref + kq * (Qref - q_oc) - - dx[i__ω_oc] = (Pref - pe - kd * (ω_oc - ω_pll) - kω * (ω_oc - ωref)) / Ta #docs:(2a) - dx[i__θ_oc] = ω_base * (ω_oc - ω_sys) #docs:(2b) - dx[i__q_oc] = ωf * (qe - q_oc) #docs:(2c) - - #INNER LOOP CONTROL - #reference transformations - vd_filt_olc = sin(θ_oc + pi / 2) * vr_filter - cos(θ_oc + pi / 2) * vi_filter - vq_filt_olc = cos(θ_oc + pi / 2) * vr_filter + sin(θ_oc + pi / 2) * vi_filter - id_filt_olc = sin(θ_oc + pi / 2) * ir_filter - cos(θ_oc + pi / 2) * ii_filter - iq_filt_olc = cos(θ_oc + pi / 2) * ir_filter + sin(θ_oc + pi / 2) * ii_filter - id_cnv_olc = sin(θ_oc + pi / 2) * ir_cnv - cos(θ_oc + pi / 2) * ii_cnv - iq_cnv_olc = cos(θ_oc + pi / 2) * ir_cnv + sin(θ_oc + pi / 2) * ii_cnv - - #Voltage control equations - Vd_filter_ref = v_ref_olc - rv * id_filt_olc + ω_oc * lv * iq_filt_olc #docs:(3g) - Vq_filter_ref = -rv * iq_filt_olc - ω_oc * lv * id_filt_olc #docs:(3h) - dx[i__ξd_ic] = Vd_filter_ref - vd_filt_olc #docs:(3a) - dx[i__ξq_ic] = Vq_filter_ref - vq_filt_olc #docs:(3b) - - #current control equations - Id_cnv_ref = (kpv * (Vd_filter_ref - vd_filt_olc) + kiv * ξd_ic - #docs:(3i) - cf * ω_oc * vq_filt_olc + kffi * id_filt_olc) - Iq_cnv_ref = (kpv * (Vq_filter_ref - vq_filt_olc) + - kiv * ξq_ic + #docs:(3j) - cf * ω_oc * vd_filt_olc + - kffi * iq_filt_olc) - dx[i__γd_ic] = Id_cnv_ref - id_cnv_olc #docs:(3c) - dx[i__γq_ic] = Iq_cnv_ref - iq_cnv_olc #docs:(3d) - - #active damping equations - Vd_cnv_ref = (kpc * (Id_cnv_ref - id_cnv_olc) + kic * γd_ic - lf * ω_oc * iq_cnv_olc + #docs:(3k) - kffv * vd_filt_olc - kad * (vd_filt_olc - ϕd_ic)) - Vq_cnv_ref = (kpc * (Iq_cnv_ref - iq_cnv_olc) + - kic * γq_ic + - lf * ω_oc * id_cnv_olc + #docs:(3l) - kffv * vq_filt_olc - kad * (vq_filt_olc - ϕq_ic)) - dx[i__ϕd_ic] = ωad * (vd_filt_olc - ϕd_ic) #docs:(3e) - dx[i__ϕq_ic] = ωad * (vq_filt_olc - ϕq_ic) #docs:(3f) - - #LCL FILTER - #reference transformations - Vr_cnv = sin(θ_oc + pi / 2) * Vd_cnv_ref + cos(θ_oc + pi / 2) * Vq_cnv_ref - Vi_cnv = -cos(θ_oc + pi / 2) * Vd_cnv_ref + sin(θ_oc + pi / 2) * Vq_cnv_ref - - Vr_pcc = Vm * cos(Vθ) - Vi_pcc = Vm * sin(Vθ) - - dx[i__ir_cnv] = (ω_base / lf) * #docs:(5a) - (Vr_cnv - vr_filter - rf * ir_cnv + ω_sys * lf * ii_cnv) - dx[i__ii_cnv] = (ω_base / lf) * #docs:(5b) - (Vi_cnv - vi_filter - rf * ii_cnv - ω_sys * lf * ir_cnv) - dx[i__vr_filter] = (ω_base / cf) * #docs:(5c) - (ir_cnv - ir_filter + ω_sys * cf * vi_filter) - dx[i__vi_filter] = (ω_base / cf) * #docs:(5d) - (ii_cnv - ii_filter - ω_sys * cf * vr_filter) - dx[i__ir_filter] = (ω_base / lg) * #docs:(5e) - (vr_filter - Vr_pcc - rg * ir_filter + ω_sys * lg * ii_filter) - dx[i__ii_filter] = +(ω_base / lg) * #docs:(5f) - (vi_filter - Vi_pcc - rg * ii_filter - ω_sys * lg * ir_filter) - - # Network interface algebraic equations 0 = I - YV - line_currents = ((Vr_cnv + Vi_cnv * 1im) - (Vr_pcc + Vi_pcc * 1im)) / - (Rtrans + Xtrans * 1im) - dx[i__ii_source] = ii_source - imag(line_currents) - dx[i__ir_source] = ir_source - real(line_currents) - return -end - -u0 = [0.0, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 1.0, - 1.0, - 0.0, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.01, - 0.0, - 1.0, - 0.0 -] -init_f! = (dx, x) -> vsm(dx, x, p_inv, 0) -res = nlsolve(init_f!, u0) - -M = diagm(ones(21)) -#Last 2 equations are algebraic -M[20, 20] = M[21, 21] = 0.0 - -f = ODEFunction(vsm, mass_matrix = M) - -condition(u, t, integrator) = t == 1.0 -affect!(integrator) = integrator.p[28] += 0.2 -cb = DiscreteCallback(condition, affect!) - -prob = ODEProblem(f, deepcopy(res.zero), (0, 20.0), deepcopy(p_inv)) -refsol = solve(prob, Rodas4(), saveat = 0.1, callback = cb, tstops = [1.0], reltol = 1e-12, - abstol = 1e-17) - -for solver in (Rodas4, Rodas4P, Rodas5, Rodas5P, FBDF, QNDF, Rosenbrock23) - @show solver - prob = ODEProblem(f, deepcopy(res.zero), (0, 20.0), deepcopy(p_inv)) - sol = solve( - prob, solver(), saveat = 0.1, callback = cb, tstops = [1.0], reltol = 1e-14, - abstol = 1e-14) - @test sol.retcode == ReturnCode.Success - @test sol.t[end] == 20.0 - @test maximum(sol - refsol) < 1e-11 -end - -function hardstop!(du, u, p, t) - pm, pg = p - y, f_wall, dy = u - du[1] = dy - du[2] = ifelse(y <= 0, y, f_wall) - du[3] = (-ifelse(t < 2, -pg * pm, pg * pm) - f_wall) / (-pm) -end - -hardstop!(u, p, t) = (du = similar(u); hardstop!(du, u, p, t); du) - -fun = ODEFunction(hardstop!, mass_matrix = Diagonal([1, 0, 1])) -prob1 = ODEProblem(fun, [5, 0, 0.0], (0, 4.0), [100, 10.0]) -prob2 = ODEProblem(fun, [5, 0, 0.0], (0, 4.0), [100, 10.0]) -for prob in [prob1, prob2] - @test solve(prob, ImplicitEuler(), dt = 1 / 2^10, adaptive = false).retcode == - ReturnCode.ConvergenceFailure -end - -condition2 = (u, t, integrator) -> t == 2 -affect2! = integrator -> integrator.u[1] = 1e-6 -cb = DiscreteCallback(condition2, affect2!) - -@isdefined(N_FAILS) || const N_FAILS = Ref(0) -function choice_function(integrator) - integrator.do_error_check = false - if integrator.force_stepfail - N_FAILS[] += 1 - else - N_FAILS[] = 0 - end - - (N_FAILS[] > 3) + 1 -end -simple_implicit_euler = ImplicitEuler(nlsolve = NLNewton(check_div = false, - always_new = true)) -alg_switch = CompositeAlgorithm((ImplicitEuler(), simple_implicit_euler), choice_function) - -for prob in [prob1, prob2], alg in [simple_implicit_euler, alg_switch] - sol = solve(prob, alg, callback = cb, dt = 1 / 2^10, adaptive = false) - @test sol.retcode == ReturnCode.Success - @test sol(0, idxs = 1) == 5 - @test sol(2, idxs = 1) == 0 - @test sol(4, idxs = 1) > 10 -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDAE/test/runtest.jl b/lib/OrdinaryDiffEqDAE/test/runtest.jl deleted file mode 100644 index a639da4027..0000000000 --- a/lib/OrdinaryDiffEqDAE/test/runtest.jl +++ /dev/null @@ -1,2 +0,0 @@ -using SafeTestsets - diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 7e6c5b3072..ffc428cda0 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -292,12 +292,7 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, <<<<<<< HEAD ======= -include("../lib/OrdinaryDiffEqDAE/src/OrdinaryDiffEqDAE.jl") -using ..OrdinaryDiffEqDAE -export DImplicitEuler, DABDF2, DFBDF - - -using ..OrdinaryDiffEqDAE: post_newton_controller! +using ..OrdinaryDiffEqBDF: post_newton_controller! include("integrators/integrator_utils.jl") include("nlsolve/newton.jl") diff --git a/test/runtests.jl b/test/runtests.jl index dff44a6753..6fb2cbe7ed 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -147,6 +147,7 @@ end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceV" || GROUP == "Interface") @time @safetestset "Interpolation Derivative Error Tests" include("interface/interpolation_derivative_error_tests.jl") @time @safetestset "AD Tests" include("interface/ad_tests.jl") +<<<<<<< HEAD <<<<<<< HEAD @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl") @time @safetestset "Newton Tests" include("interface/newton_tests.jl") @@ -156,6 +157,11 @@ end @time @safetestset "Newton Tests" include("interface/newton_tests.jl") @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl") >>>>>>> 09f9af8c (@unpack) +======= + @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl") + @time @safetestset "Newton Tests" include("interface/newton_tests.jl") + @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl") +>>>>>>> 24d3c61a (DAE added to BDF) end if !is_APPVEYOR && @@ -179,6 +185,7 @@ end @time @safetestset "Reverse Directioned Event Tests" include("integrators/rev_events_tests.jl") @time @safetestset "Differentiation Direction Tests" include("integrators/diffdir_tests.jl") @time @safetestset "Resize Tests" include("integrators/resize_tests.jl") +<<<<<<< HEAD <<<<<<< HEAD @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl") @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_event.jl") @@ -186,6 +193,10 @@ end @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl") @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_event.jl") >>>>>>> 09f9af8c (@unpack) +======= + @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl") + @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_event.jl") +>>>>>>> 24d3c61a (DAE added to BDF) @time @safetestset "Cache Tests" include("integrators/ode_cache_tests.jl") @time @safetestset "Add Steps Tests" include("integrators/ode_add_steps_tests.jl") @time @safetestset "IMEX Split Function Tests" include("integrators/split_ode_tests.jl") @@ -196,11 +207,15 @@ end @time @safetestset "Special Interp Tests" include("regression/special_interps.jl") @time @safetestset "Inplace Tests" include("regression/ode_inplace_tests.jl") @time @safetestset "Adaptive Tests" include("regression/ode_adaptive_tests.jl") +<<<<<<< HEAD <<<<<<< HEAD @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqBDF/test/hard_dae.jl") ======= @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqDAE/test/hard_dae.jl") >>>>>>> 09f9af8c (@unpack) +======= + @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqBDF/test/hard_dae.jl") +>>>>>>> 24d3c61a (DAE added to BDF) end if !is_APPVEYOR && (GROUP == "All" || GROUP == "Regression_II" || GROUP == "Regression") @@ -214,11 +229,15 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_I" @time @safetestset "Partitioned Methods Tests" include("algconvergence/partitioned_methods_tests.jl") @time @safetestset "Convergence Tests" include("algconvergence/ode_convergence_tests.jl") +<<<<<<< HEAD <<<<<<< HEAD @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl") ======= @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl") >>>>>>> 09f9af8c (@unpack) +======= + @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl") +>>>>>>> 24d3c61a (DAE added to BDF) @time @safetestset "Non-autonomous Convergence Tests" include("algconvergence/non-autonomous_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("algconvergence/adams_tests.jl") @time @safetestset "Nordsieck Tests" include("algconvergence/nordsieck_tests.jl") From 124a5f026ec00ae706e66e8fa6c93098b0a8555e Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Fri, 26 Jul 2024 22:31:11 +0530 Subject: [PATCH 41/45] added tests --- src/OrdinaryDiffEq.jl | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index ffc428cda0..5f91695273 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -289,15 +289,6 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_finite_difference_weights, estimate_terk, calc_Lagrange_interp, bdf_step_reject_controller! -<<<<<<< HEAD -======= - -using ..OrdinaryDiffEqBDF: post_newton_controller! -include("integrators/integrator_utils.jl") -include("nlsolve/newton.jl") - -import PrecompileTools ->>>>>>> b150b887 (Added DAE solvers) using ..OrdinaryDiffEqBDF: post_newton_controller! include("integrators/integrator_utils.jl") From cd75f16f29dd2d69c845ee19486c5f41df76a848 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Fri, 26 Jul 2024 23:33:54 -0400 Subject: [PATCH 42/45] Update lib/OrdinaryDiffEqBDF/src/algorithms.jl --- lib/OrdinaryDiffEqBDF/src/algorithms.jl | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index 0ed740a489..71900e4925 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -426,19 +426,6 @@ function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = V nlsolve, precs, extrapolant, controller) end -#= -struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -DBDF(;chunk_size=Val{0}(),autodiff=Val{true}(), standardtag = Val{true}(), concrete_jac = nothing,diff_type=Val{:forward}, - linsolve=nothing,precs = DEFAULT_PRECS,nlsolve=NLNewton(),extrapolant=:linear) = - DBDF{_unwrap_val(chunk_size),_unwrap_val(autodiff),typeof(linsolve),typeof(nlsolve),typeof(precs),diff_type,_unwrap_val(standardtag),_unwrap_val(concrete_jac)}( - linsolve,nlsolve,precs,extrapolant) -=# struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FDT, ST, CJ} max_order::Val{MO} From 7b87efce88e59c2012613ca3508486d3287be150 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 27 Jul 2024 10:16:05 +0530 Subject: [PATCH 43/45] merge conflicts --- test/runtests.jl | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 6fb2cbe7ed..1edccc79e5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -147,21 +147,9 @@ end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceV" || GROUP == "Interface") @time @safetestset "Interpolation Derivative Error Tests" include("interface/interpolation_derivative_error_tests.jl") @time @safetestset "AD Tests" include("interface/ad_tests.jl") -<<<<<<< HEAD -<<<<<<< HEAD @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl") @time @safetestset "Newton Tests" include("interface/newton_tests.jl") @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl") -======= - @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_ad_tests.jl") - @time @safetestset "Newton Tests" include("interface/newton_tests.jl") - @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqDAE/test/dae_initialize_integration.jl") ->>>>>>> 09f9af8c (@unpack) -======= - @time @safetestset "DAE AD Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_ad_tests.jl") - @time @safetestset "Newton Tests" include("interface/newton_tests.jl") - @time @safetestset "DAE Initialize Integration" include("../lib/OrdinaryDiffEqBDF/test/dae_initialize_integration.jl") ->>>>>>> 24d3c61a (DAE added to BDF) end if !is_APPVEYOR && @@ -185,18 +173,8 @@ end @time @safetestset "Reverse Directioned Event Tests" include("integrators/rev_events_tests.jl") @time @safetestset "Differentiation Direction Tests" include("integrators/diffdir_tests.jl") @time @safetestset "Resize Tests" include("integrators/resize_tests.jl") -<<<<<<< HEAD -<<<<<<< HEAD @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl") @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_event.jl") -======= - @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_initialization_tests.jl") - @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_event.jl") ->>>>>>> 09f9af8c (@unpack) -======= - @time @safetestset "DAE Initialization Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl") - @time @safetestset "DAE Event Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_event.jl") ->>>>>>> 24d3c61a (DAE added to BDF) @time @safetestset "Cache Tests" include("integrators/ode_cache_tests.jl") @time @safetestset "Add Steps Tests" include("integrators/ode_add_steps_tests.jl") @time @safetestset "IMEX Split Function Tests" include("integrators/split_ode_tests.jl") @@ -207,15 +185,7 @@ end @time @safetestset "Special Interp Tests" include("regression/special_interps.jl") @time @safetestset "Inplace Tests" include("regression/ode_inplace_tests.jl") @time @safetestset "Adaptive Tests" include("regression/ode_adaptive_tests.jl") -<<<<<<< HEAD -<<<<<<< HEAD @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqBDF/test/hard_dae.jl") -======= - @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqDAE/test/hard_dae.jl") ->>>>>>> 09f9af8c (@unpack) -======= - @time @safetestset "Hard DAE Tests" include("../lib/OrdinaryDiffEqBDF/test/hard_dae.jl") ->>>>>>> 24d3c61a (DAE added to BDF) end if !is_APPVEYOR && (GROUP == "All" || GROUP == "Regression_II" || GROUP == "Regression") @@ -229,15 +199,7 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_I" @time @safetestset "Partitioned Methods Tests" include("algconvergence/partitioned_methods_tests.jl") @time @safetestset "Convergence Tests" include("algconvergence/ode_convergence_tests.jl") -<<<<<<< HEAD -<<<<<<< HEAD - @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl") -======= - @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqDAE/test/dae_convergence_tests.jl") ->>>>>>> 09f9af8c (@unpack) -======= @time @safetestset "DAE Convergence Tests" include("../lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl") ->>>>>>> 24d3c61a (DAE added to BDF) @time @safetestset "Non-autonomous Convergence Tests" include("algconvergence/non-autonomous_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("algconvergence/adams_tests.jl") @time @safetestset "Nordsieck Tests" include("algconvergence/nordsieck_tests.jl") From 3553e19cc84e829b5d96b8b42eb1fce61db90bf4 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 27 Jul 2024 10:22:15 +0530 Subject: [PATCH 44/45] precompile tools --- src/OrdinaryDiffEq.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 5f91695273..57c9ee3aa1 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -20,6 +20,8 @@ using LinearAlgebra import StaticArrayInterface +using PrecompileTools + import InteractiveUtils using LinearSolve, SimpleNonlinearSolve @@ -292,6 +294,7 @@ using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, using ..OrdinaryDiffEqBDF: post_newton_controller! include("integrators/integrator_utils.jl") + PrecompileTools.@compile_workload begin function lorenz(du, u, p, t) du[1] = 10.0(u[2] - u[1]) From 5a3b4e4e409c077959e83e46aa8b28fa591b2203 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 27 Jul 2024 10:48:13 +0530 Subject: [PATCH 45/45] compute_step! --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 740ced5261..33078d809b 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -16,6 +16,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, DIRK, set_new_W!, du_alias_or_new, trivial_limiter!, ImplicitEulerConstantCache, + compute_step!, ImplicitEulerCache, COEFFICIENT_MULTISTEP, markfirststage!, UJacobianWrapper, mul!, issplit, qsteady_min_default, qsteady_max_default,