Skip to content

Commit

Permalink
Add a separate BVPsolution type
Browse files Browse the repository at this point in the history
  • Loading branch information
avik-pal committed Dec 25, 2023
1 parent 62c4cb8 commit 344f505
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 31 deletions.
5 changes: 3 additions & 2 deletions src/SciMLBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -767,10 +767,11 @@ export isinplace

export solve, solve!, init, discretize, symbolic_discretize

export LinearProblem, NonlinearProblem, IntervalNonlinearProblem,
export LinearProblem, IntervalNonlinearProblem,
IntegralProblem, SampledIntegralProblem, OptimizationProblem,
NonlinearLeastSquaresProblem

export NonlinearProblem, NonlinearSolution
export DiscreteProblem, ImplicitDiscreteProblem
export SteadyStateProblem, SteadyStateSolution
export NoiseProblem
Expand All @@ -789,7 +790,7 @@ export SDDEProblem
export PDEProblem
export IncrementingODEProblem

export BVProblem, TwoPointBVProblem
export BVProblem, TwoPointBVProblem, BVPSolution

export remake

Expand Down
171 changes: 142 additions & 29 deletions src/solutions/ode_solutions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,65 @@ https://docs.sciml.ai/DiffEqDocs/stable/basics/solution/
[the return code documentation](https://docs.sciml.ai/SciMLBase/stable/interfaces/Solutions/#retcodes).
"""
struct ODESolution{T, N, uType, uType2, DType, tType, rateType, P, A, IType, S,
AC <: Union{Nothing, Vector{Int}}, R, O} <:
AC <: Union{Nothing, Vector{Int}}} <:
AbstractODESolution{T, N, uType}
u::uType
u_analytic::uType2
errors::DType
t::tType
k::rateType
prob::P
alg::A
interp::IType
dense::Bool
tslocation::Int
stats::S
alg_choice::AC
retcode::ReturnCode.T
end

function ODESolution{T, N}(u, u_analytic, errors, t, k, prob, alg, interp, dense,
tslocation, stats, alg_choice, retcode) where {T, N}
return ODESolution{T, N, typeof(u), typeof(u_analytic), typeof(errors), typeof(t),
typeof(k), typeof(prob), typeof(alg), typeof(interp),
typeof(stats), typeof(alg_choice)}(u, u_analytic, errors, t, k, prob, alg, interp,
dense, tslocation, stats, alg_choice, retcode)
end


"""
$(TYPEDEF)
Representation of the solution to an boundary value differential equation defined by an BVPProblem.
## DESolution Interface
For more information on interacting with `DESolution` types, check out the Solution Handling
page of the DifferentialEquations.jl documentation.
https://docs.sciml.ai/DiffEqDocs/stable/basics/solution/
## Fields
- `u`: the representation of the BVP solution. Given as an array of solutions, where `u[i]`
corresponds to the solution at time `t[i]`. It is recommended in most cases one does not
access `sol.u` directly and instead use the array interface described in the Solution
Handling page of the DifferentialEquations.jl documentation.
- `t`: the time points corresponding to the saved values of the ODE solution.
- `prob`: the original BVProblem that was solved.
- `alg`: the algorithm type used by the solver.
- `stats`: statistics of the solver, such as the number of function evaluations required,
number of Jacobians computed, and more.
- `retcode`: the return code from the solver. Used to determine whether the solver solved
successfully, whether it terminated early due to a user-defined callback, or whether it
exited due to an error. For more details, see
[the return code documentation](https://docs.sciml.ai/SciMLBase/stable/interfaces/Solutions/#retcodes).
- `resid`: Residual of the final internal nonlinear solve problem
- `original_ivp`: Original Solution of the internal Initial Value Problem
- `original_nlsolve`: Original Solution of the internal Nonlinear Solve Problem
"""
struct BVPSolution{T, N, uType, uType2, DType, tType, rateType, P, A, IType, S,
AC <: Union{Nothing, Vector{Int}}, R, OI, ON} <:
AbstractODESolution{T, N, uType}
u::uType
u_analytic::uType2
Expand All @@ -116,7 +174,29 @@ struct ODESolution{T, N, uType, uType2, DType, tType, rateType, P, A, IType, S,
alg_choice::AC
retcode::ReturnCode.T
resid::R
original::O
original_ivp::OI
original_nlsolve::ON
end

function BVPSolution{T, N}(u, u_analytic, errors, t, k, prob, alg, interp, dense,
tslocation, stats, alg_choice, retcode, resid, original_ivp,
original_nlsolve) where {T, N}
return BVPSolution{T, N, typeof(u), typeof(u_analytic), typeof(errors), typeof(t),
typeof(k), typeof(prob), typeof(alg), typeof(interp),
typeof(stats), typeof(alg_choice), typeof(resid), typeof(original_ivp),
typeof(original_nlsolve)}(u, u_analytic, errors, t, k, prob, alg, interp,
dense, tslocation, stats, alg_choice, retcode, resid, original_ivp,
original_nlsolve)
end

function BVPSolution(sol::ODESolution{T, N}; resid = nothing, retcode = sol.retcode,
original::Union{Nothing, AbstractNonlinearSolution} = nothing) where {T, N}
if original !== nothing && resid === nothing && hasfield(typeof(original), :resid)
resid = original.resid
end
return BVPSolution{T, N}(sol.u, sol.u_analytic, sol.errors, sol.t, sol.k, sol.prob,
sol.alg, sol.interp, sol.dense, sol.tslocation, sol.stats, sol.alg_choice,
retcode, resid, sol, original)
end

Base.@propagate_inbounds function Base.getproperty(x::AbstractODESolution, s::Symbol)
Expand All @@ -127,17 +207,6 @@ Base.@propagate_inbounds function Base.getproperty(x::AbstractODESolution, s::Sy
return getfield(x, s)
end

# FIXME: Remove the defaults for resid and original on a breaking release
function ODESolution{T, N}(u, u_analytic, errors, t, k, prob, alg, interp, dense,
tslocation, stats, alg_choice, retcode, resid = nothing,
original = nothing) where {T, N}
return ODESolution{T, N, typeof(u), typeof(u_analytic), typeof(errors), typeof(t),
typeof(k), typeof(prob), typeof(alg), typeof(interp),
typeof(stats), typeof(alg_choice), typeof(resid),
typeof(original)}(u, u_analytic, errors, t, k, prob, alg, interp,
dense, tslocation, stats, alg_choice, retcode, resid, original)
end

function (sol::AbstractODESolution)(t, ::Type{deriv} = Val{0}; idxs = nothing,
continuity = :left) where {deriv}
sol(t, deriv, idxs, continuity)
Expand Down Expand Up @@ -217,7 +286,6 @@ function build_solution(prob::Union{AbstractODEProblem, AbstractDDEProblem},
alg_choice = nothing,
interp = LinearInterpolation(t, u),
retcode = ReturnCode.Default, destats = missing, stats = nothing,
resid = nothing, original = nothing,
kwargs...)
T = eltype(eltype(u))

Expand Down Expand Up @@ -257,9 +325,7 @@ function build_solution(prob::Union{AbstractODEProblem, AbstractDDEProblem},
0,
stats,
alg_choice,
retcode,
resid,
original)
retcode)
if calculate_error
calculate_solution_errors!(sol; timeseries_errors = timeseries_errors,
dense_errors = dense_errors)
Expand All @@ -277,9 +343,7 @@ function build_solution(prob::Union{AbstractODEProblem, AbstractDDEProblem},
0,
stats,
alg_choice,
retcode,
resid,
original)
retcode)
end
end

Expand Down Expand Up @@ -335,13 +399,27 @@ function build_solution(sol::ODESolution{T, N}, u_analytic, errors) where {T, N}
sol.tslocation,
sol.stats,
sol.alg_choice,
sol.retcode,
sol.resid,
sol.original)
sol.retcode)
end

function solution_new_retcode(sol::ODESolution{T, N}, retcode) where {T, N}
ODESolution{T, N}(sol.u,
sol.u_analytic,
sol.errors,
sol.t,
sol.k,
sol.prob,
sol.alg,
sol.interp,
sol.dense,
sol.tslocation,
sol.stats,
sol.alg_choice,
retcode)
end

function solution_new_retcode(sol::BVPSolution{T, N}, retcode) where {T, N}
BVPSolution{T, N}(sol.u,
sol.u_analytic,
sol.errors,
sol.t,
Expand All @@ -355,7 +433,8 @@ function solution_new_retcode(sol::ODESolution{T, N}, retcode) where {T, N}
sol.alg_choice,
retcode,
sol.resid,
sol.original)
sol.original_ivp,
sol.original_nlsolve)
end

function solution_new_tslocation(sol::ODESolution{T, N}, tslocation) where {T, N}
Expand All @@ -371,13 +450,27 @@ function solution_new_tslocation(sol::ODESolution{T, N}, tslocation) where {T, N
tslocation,
sol.stats,
sol.alg_choice,
sol.retcode,
sol.resid,
sol.original)
sol.retcode)
end

function solution_slice(sol::ODESolution{T, N}, I) where {T, N}
ODESolution{T, N}(sol.u[I],
sol.u_analytic === nothing ? nothing : sol.u_analytic[I],
sol.errors,
sol.t[I],
sol.dense ? sol.k[I] : sol.k,
sol.prob,
sol.alg,
sol.interp,
false,
sol.tslocation,
sol.stats,
sol.alg_choice,
sol.retcode)
end

function solution_slice(sol::BVPSolution{T, N}, I) where {T, N}
BVPSolution{T, N}(sol.u[I],
sol.u_analytic === nothing ? nothing : sol.u_analytic[I],
sol.errors,
sol.t[I],
Expand All @@ -391,7 +484,8 @@ function solution_slice(sol::ODESolution{T, N}, I) where {T, N}
sol.alg_choice,
sol.retcode,
sol.resid,
sol.original)
sol.original_ivp,
sol.original_nlsolve)
end

function sensitivity_solution(sol::ODESolution, u, t)
Expand All @@ -409,5 +503,24 @@ function sensitivity_solution(sol::ODESolution, u, t)
nothing, sol.prob,
sol.alg, interp,
sol.dense, sol.tslocation,
sol.stats, sol.alg_choice, sol.retcode, sol.resid, sol.original)
sol.stats, sol.alg_choice, sol.retcode)
end

function sensitivity_solution(sol::BVPSolution, u, t)
T = eltype(eltype(u))
N = length((size(sol.prob.u0)..., length(u)))
interp = if sol.interp isa LinearInterpolation
LinearInterpolation(t, u)
elseif sol.interp isa ConstantInterpolation
ConstantInterpolation(t, u)
else
SensitivityInterpolation(t, u)
end

BVPSolution{T, N}(u, sol.u_analytic, sol.errors, t,
nothing, sol.prob,
sol.alg, interp,
sol.dense, sol.tslocation,
sol.stats, sol.alg_choice, sol.retcode,
sol.resid, sol.original_ivp, sol.original_nlsolve)
end

0 comments on commit 344f505

Please sign in to comment.