@@ -65,6 +65,11 @@ struct ODESystem <: AbstractSystem
65
65
""" Parameter variables."""
66
66
ps:: Vector{Variable}
67
67
"""
68
+ Time-derivative matrix. Note: this field will not be defined until
69
+ [`calculate_tgrad`](@ref) is called on the system.
70
+ """
71
+ tgrad:: RefValue{Vector{Expression}}
72
+ """
68
73
Jacobian matrix. Note: this field will not be defined until
69
74
[`calculate_jacobian`](@ref) is called on the system.
70
75
"""
@@ -99,10 +104,11 @@ function ODESystem(eqs)
99
104
end
100
105
101
106
function ODESystem (deqs:: AbstractVector{DiffEq} , iv, dvs, ps)
107
+ tgrad = RefValue (Vector {Expression} (undef, 0 ))
102
108
jac = RefValue (Matrix {Expression} (undef, 0 , 0 ))
103
109
Wfact = RefValue (Matrix {Expression} (undef, 0 , 0 ))
104
110
Wfact_t = RefValue (Matrix {Expression} (undef, 0 , 0 ))
105
- ODESystem (deqs, iv, dvs, ps, jac, Wfact, Wfact_t)
111
+ ODESystem (deqs, iv, dvs, ps, tgrad, jac, Wfact, Wfact_t)
106
112
end
107
113
108
114
function ODESystem (deqs:: AbstractVector{<:Equation} , iv, dvs, ps)
@@ -133,6 +139,17 @@ independent_variables(sys::ODESystem) = Set{Variable}([sys.iv])
133
139
dependent_variables (sys:: ODESystem ) = Set {Variable} (sys. dvs)
134
140
parameters (sys:: ODESystem ) = Set {Variable} (sys. ps)
135
141
142
+ function calculate_tgrad (sys:: ODESystem )
143
+ isempty (sys. tgrad[]) || return sys. tgrad[] # use cached tgrad, if possible
144
+ rhs = [detime_dvs (eq. rhs) for eq ∈ sys. eqs]
145
+ iv = sys. iv ()
146
+ notime_tgrad = [expand_derivatives (ModelingToolkit. Differential (iv)(r)) for r in rhs]
147
+ @show notime_tgrad
148
+ tgrad = retime_dvs .(notime_tgrad,(sys. dvs,),iv)
149
+ @show tgrad
150
+ sys. tgrad[] = tgrad
151
+ return tgrad
152
+ end
136
153
137
154
function calculate_jacobian (sys:: ODESystem )
138
155
isempty (sys. jac[]) || return sys. jac[] # use cached Jacobian, if possible
@@ -160,6 +177,11 @@ function (f::ODEToExpr)(O::Operation)
160
177
end
161
178
(f:: ODEToExpr )(x) = convert (Expr, x)
162
179
180
+ function generate_tgrad (sys:: ODESystem , dvs = sys. dvs, ps = sys. ps, expression = Val{true }; kwargs... )
181
+ tgrad = calculate_tgrad (sys)
182
+ return build_function (tgrad, dvs, ps, (sys. iv. name,), ODEToExpr (sys), expression; kwargs... )
183
+ end
184
+
163
185
function generate_jacobian (sys:: ODESystem , dvs = sys. dvs, ps = sys. ps, expression = Val{true }; kwargs... )
164
186
jac = calculate_jacobian (sys)
165
187
return build_function (jac, dvs, ps, (sys. iv. name,), ODEToExpr (sys), expression; kwargs... )
@@ -218,13 +240,21 @@ are used to set the order of the dependent variable and parameter vectors,
218
240
respectively.
219
241
"""
220
242
function DiffEqBase. ODEFunction {iip} (sys:: ODESystem , dvs = sys. dvs, ps = sys. ps;
221
- version = nothing ,
243
+ version = nothing , tgrad = false ,
222
244
jac = false , Wfact = false ) where {iip}
223
245
f_oop,f_iip = generate_function (sys, dvs, ps, Val{false })
224
246
225
247
f (u,p,t) = f_oop (u,p,t)
226
248
f (du,u,p,t) = f_iip (du,u,p,t)
227
249
250
+ if tgrad
251
+ tgrad_oop,tgrad_iip = generate_tgrad (sys, dvs, ps, Val{false })
252
+ _tgrad (u,p,t) = tgrad_oop (u,p,t)
253
+ _tgrad (J,u,p,t) = tgrad_iip (J,u,p,t)
254
+ else
255
+ _tgrad = nothing
256
+ end
257
+
228
258
if jac
229
259
jac_oop,jac_iip = generate_jacobian (sys, dvs, ps, Val{false })
230
260
_jac (u,p,t) = jac_oop (u,p,t)
@@ -246,6 +276,7 @@ function DiffEqBase.ODEFunction{iip}(sys::ODESystem, dvs = sys.dvs, ps = sys.ps;
246
276
end
247
277
248
278
ODEFunction {iip} (f,jac= _jac,
279
+ tgrad = tgrad,
249
280
Wfact = _Wfact,
250
281
Wfact_t = _Wfact_t,
251
282
syms = string .(sys. dvs))
0 commit comments