Skip to content

Commit ad5a5a8

Browse files
feat: support symbolic save_idxs in DAESolution
1 parent a626b86 commit ad5a5a8

File tree

1 file changed

+46
-69
lines changed

1 file changed

+46
-69
lines changed

src/solutions/dae_solutions.jl

Lines changed: 46 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ https://docs.sciml.ai/DiffEqDocs/stable/basics/solution/
2727
exited due to an error. For more details, see
2828
[the return code documentation](https://docs.sciml.ai/SciMLBase/stable/interfaces/Solutions/#retcodes).
2929
"""
30-
struct DAESolution{T, N, uType, duType, uType2, DType, tType, P, A, ID, S, rateType} <:
30+
struct DAESolution{T, N, uType, duType, uType2, DType, tType, P, A, ID, S, rateType, V} <:
3131
AbstractDAESolution{T, N, uType}
3232
u::uType
3333
du::duType
@@ -42,6 +42,31 @@ struct DAESolution{T, N, uType, duType, uType2, DType, tType, P, A, ID, S, rateT
4242
tslocation::Int
4343
stats::S
4444
retcode::ReturnCode.T
45+
saved_subsystem::V
46+
end
47+
48+
function DAESolution{T, N}(u, du, u_analytic, errors, t, k, prob, alg, interp, dense,
49+
tslocation, stats, retcode, saved_subsystem) where {T, N}
50+
return DAESolution{T, N, typeof(u), typeof(du), typeof(u_analytic), typeof(errors),
51+
typeof(t), typeof(prob), typeof(alg), typeof(interp), typeof(stats), typeof(k),
52+
typeof(saved_subsystem)}(
53+
u, du, u_analytic, errors, t, k, prob, alg, interp, dense, tslocation, stats,
54+
retcode, saved_subsystem
55+
)
56+
end
57+
58+
function ConstructionBase.constructorof(::Type{O}) where {T, N, O <: DAESolution{T, N}}
59+
DAESolution{T, N}
60+
end
61+
62+
function ConstructionBase.setproperties(sol::DAESolution, patch::NamedTuple)
63+
u = get(patch, :u, sol.u)
64+
N = u === nothing ? 2 : ndims(eltype(u)) + 1
65+
T = eltype(eltype(u))
66+
patch = merge(getproperties(sol), patch)
67+
return DAESolution{T, N}(patch.u, patch.du, patch.u_analytic, patch.errors, patch.t,
68+
patch.k, patch.prob, patch.alg, patch.interp, patch.dense, patch.tslocation,
69+
patch.stats, patch.retcode, patch.saved_subsystem)
4570
end
4671

4772
Base.@propagate_inbounds function Base.getproperty(x::AbstractDAESolution, s::Symbol)
@@ -65,13 +90,14 @@ function build_solution(prob::AbstractDAEProblem, alg, t, u, du = nothing;
6590
retcode = ReturnCode.Default,
6691
destats = missing,
6792
stats = nothing,
93+
saved_subsystem = nothing,
6894
kwargs...)
6995
T = eltype(eltype(u))
7096

7197
if prob.u0 === nothing
7298
N = 2
7399
else
74-
N = length((size(prob.u0)..., length(u)))
100+
N = ndims(eltype(u)) + 1
75101
end
76102

77103
if !ismissing(destats)
@@ -88,7 +114,8 @@ function build_solution(prob::AbstractDAEProblem, alg, t, u, du = nothing;
88114
errors = Dict{Symbol, real(eltype(prob.u0))}()
89115

90116
sol = DAESolution{T, N, typeof(u), typeof(du), typeof(u_analytic), typeof(errors),
91-
typeof(t), typeof(prob), typeof(alg), typeof(interp), typeof(stats), typeof(k)}(
117+
typeof(t), typeof(prob), typeof(alg), typeof(interp), typeof(stats), typeof(k),
118+
typeof(saved_subsystem)}(
92119
u,
93120
du,
94121
u_analytic,
@@ -101,7 +128,8 @@ function build_solution(prob::AbstractDAEProblem, alg, t, u, du = nothing;
101128
dense,
102129
0,
103130
stats,
104-
retcode)
131+
retcode,
132+
saved_subsystem)
105133

106134
if calculate_error
107135
calculate_solution_errors!(sol; timeseries_errors = timeseries_errors,
@@ -110,15 +138,17 @@ function build_solution(prob::AbstractDAEProblem, alg, t, u, du = nothing;
110138
sol
111139
else
112140
DAESolution{T, N, typeof(u), typeof(du), Nothing, Nothing, typeof(t),
113-
typeof(prob), typeof(alg), typeof(interp), typeof(stats), typeof(k)}(
141+
typeof(prob), typeof(alg), typeof(interp), typeof(stats), typeof(k),
142+
typeof(saved_subsystem)}(
114143
u, du,
115144
nothing,
116145
nothing, t, k,
117146
prob, alg,
118147
interp,
119148
dense, 0,
120149
stats,
121-
retcode)
150+
retcode,
151+
saved_subsystem)
122152
end
123153
end
124154

@@ -161,76 +191,23 @@ function calculate_solution_errors!(sol::AbstractDAESolution;
161191
end
162192

163193
function build_solution(sol::AbstractDAESolution{T, N}, u_analytic, errors) where {T, N}
164-
DAESolution{T, N, typeof(sol.u), typeof(sol.du), typeof(u_analytic), typeof(errors),
165-
typeof(sol.t), typeof(sol.prob), typeof(sol.alg), typeof(sol.interp),
166-
typeof(sol.stats), typeof(sol.k)}(sol.u,
167-
sol.du,
168-
u_analytic,
169-
errors,
170-
sol.t,
171-
sol.k,
172-
sol.prob,
173-
sol.alg,
174-
sol.interp,
175-
sol.dense,
176-
sol.tslocation,
177-
sol.stats,
178-
sol.retcode)
194+
@reset sol.u_analytic = u_analytic
195+
return @set sol.errors = errors
179196
end
180197

181198
function solution_new_retcode(sol::AbstractDAESolution{T, N}, retcode) where {T, N}
182-
DAESolution{T, N, typeof(sol.u), typeof(sol.du), typeof(sol.u_analytic),
183-
typeof(sol.errors), typeof(sol.t), typeof(sol.prob), typeof(sol.alg),
184-
typeof(sol.interp), typeof(sol.stats), typeof(sol.k)}(sol.u,
185-
sol.du,
186-
sol.u_analytic,
187-
sol.errors,
188-
sol.t,
189-
sol.k,
190-
sol.prob,
191-
sol.alg,
192-
sol.interp,
193-
sol.dense,
194-
sol.tslocation,
195-
sol.stats,
196-
retcode)
199+
return @set sol.retcode = retcode
197200
end
198201

199202
function solution_new_tslocation(sol::AbstractDAESolution{T, N}, tslocation) where {T, N}
200-
DAESolution{T, N, typeof(sol.u), typeof(sol.du), typeof(sol.u_analytic),
201-
typeof(sol.errors), typeof(sol.t), typeof(sol.prob), typeof(sol.alg),
202-
typeof(sol.interp), typeof(sol.stats), typeof(k)}(sol.u,
203-
sol.du,
204-
sol.u_analytic,
205-
sol.errors,
206-
sol.t,
207-
sol.k,
208-
sol.prob,
209-
sol.alg,
210-
sol.interp,
211-
sol.dense,
212-
tslocation,
213-
sol.stats,
214-
sol.retcode)
203+
return @set sol.tslocation = tslocation
215204
end
216205

217206
function solution_slice(sol::AbstractDAESolution{T, N}, I) where {T, N}
218-
DAESolution{T, N, typeof(sol.u), typeof(sol.du), typeof(sol.u_analytic),
219-
typeof(sol.errors), typeof(sol.t), typeof(sol.prob), typeof(sol.alg),
220-
typeof(sol.interp), typeof(sol.stats), typeof(sol.k)}(sol.u[I],
221-
sol.du[I],
222-
sol.u_analytic ===
223-
nothing ?
224-
nothing :
225-
sol.u_analytic[I],
226-
sol.errors,
227-
sol.t[I],
228-
sol.k[I],
229-
sol.prob,
230-
sol.alg,
231-
sol.interp,
232-
false,
233-
sol.tslocation,
234-
sol.stats,
235-
sol.retcode)
207+
@reset sol.u = sol.u[I]
208+
@reset sol.du = sol.du[I]
209+
@reset sol.u_analytic = sol.u_analytic === nothing ? nothing : sol.u_analytic[I]
210+
@reset sol.t = sol.t[I]
211+
@reset sol.k = sol.dense ? sol.k[I] : sol.k
212+
return @set sol.dense = false
236213
end

0 commit comments

Comments
 (0)