@@ -37,42 +37,6 @@ function AIBECSFunction(T::Function, Gs::Tuple, nb::Int)
37
37
AIBECSFunction ((T,), Gs, nb, nt, Tidx)
38
38
end
39
39
function AIBECSFunction (Ts:: Tuple , Gs:: Tuple , nb:: Int , nt:: Int = length (Ts), Tidx:: AbstractVector = 1 : nt)
40
- if all (isinplace (G, nt + 2 ) for G in Gs) # +2 to account for dx and p
41
- iipAIBECSFunction (Ts, Gs, nb, nt, Tidx)
42
- else
43
- oopAIBECSFunction (Ts, Gs, nb, nt, Tidx)
44
- end
45
- end
46
-
47
- function iipAIBECSFunction (Ts, Gs, nb, nt= length (Ts), Tidx= 1 : nt)
48
- tracers (u) = state_to_tracers (u, nb, nt)
49
- tracer (u, i) = state_to_tracer (u, nb, nt, i)
50
- function G (du, u, p)
51
- for j in 1 : nt
52
- Gs[j](tracer (du, j), tracers (u)... , p)
53
- end
54
- du
55
- end
56
- function f (du, u, p, t= 0 )
57
- G (du, u, p)
58
- for jT in eachindex (Ts)
59
- op = Ts[jT](p)
60
- for j in findall (Tidx .== jT)
61
- mul! (tracer (du, j), op, tracer (u, j), - 1 , 1 )
62
- end
63
- end
64
- du
65
- end
66
- # Jacobian
67
- ∇ₓG (u, p) = inplace_local_jacobian (Gs, u, p, nt, nb)
68
- function T (p)
69
- uniqueTs = [Tⱼ (p) for Tⱼ in Ts]
70
- blockdiag ([uniqueTs[Tidx[j]] for j in 1 : nt]. .. )
71
- end
72
- jac (u, p, t= 0 ) = ∇ₓG (u, p) - T (p)
73
- return ODEFunction {true} (f, jac= jac)
74
- end
75
- function oopAIBECSFunction (Ts, Gs, nb, nt= length (Ts), Tidx= 1 : nt)
76
40
tracers (u) = state_to_tracers (u, nb, nt)
77
41
tracer (u, i) = state_to_tracer (u, nb, nt, i)
78
42
G (u, p) = reduce (vcat, Gⱼ (tracers (u)... , p) for Gⱼ in Gs)
99
63
function AIBECSFunction (Ts, Gs, nb:: Int , :: Type{P} ) where {P <: APar }
100
64
AIBECSFunction (AIBECSFunction (Ts, Gs, nb), P)
101
65
end
102
- function AIBECSFunction (fun:: ODEFunction{false} , :: Type{P} ) where {P <: APar }
66
+ function AIBECSFunction (fun:: ODEFunction , :: Type{P} ) where {P <: APar }
103
67
jac (u, p:: P , t= 0 ) = fun. jac (u, p, t)
104
68
jac (u, λ:: Vector , t= 0 ) = fun. jac (u, λ2p (P, λ), t)
105
69
f (u, p:: P , t= 0 ) = fun. f (u, p, t)
106
70
f (u, λ:: Vector , t= 0 ) = fun. f (u, λ2p (P, λ), t)
107
71
return ODEFunction {false} (f, jac= jac)
108
72
end
109
- function AIBECSFunction (fun:: ODEFunction{true} , :: Type{P} ) where {P <: APar }
110
- jac (u, p:: P , t= 0 ) = fun. jac (u, p, t)
111
- jac (u, λ:: Vector , t= 0 ) = fun. jac (u, λ2p (P, λ), t)
112
- f (du, u, p:: P , t= 0 ) = fun. f (du, u, p, t)
113
- f (du, u, λ:: Vector , t= 0 ) = fun. f (du, u, λ2p (P, λ), t)
114
- return ODEFunction {true} (f, jac= jac)
115
- end
116
73
117
74
export AIBECSFunction
118
75
119
- """
120
- F, ∇ₓF = F_and_∇ₓF(Ts, Gs, nb)
121
-
122
- Returns the state function `F` and its Jacobian, `∇ₓF`.
123
-
124
- F, ∇ₓF = F_and_∇ₓF(T, Gs, nb)
125
-
126
- Returns the state function `F` and its Jacobian, `∇ₓF` (with all tracers transported by single `T`).
127
-
128
- This function is deprecated. Use
129
-
130
- F = AIBECSFunction(Ts, Gs, nb)
131
-
132
- instead.
133
- You can then call `F(x,p)` for the tendencies, and `F(Val{:jac},x,p)` for the Jacobian.
134
- """
135
- function F_and_∇ₓF (fun:: ODEFunction )
136
- Base. depwarn (""" Deprecation:
137
- F, ∇ₓF = F_and_∇ₓF(args...)
138
- is deprecated. Use
139
- F = AIBECSFunction(args...)
140
- instead! (And then you can still call `F(x,p)`.)
141
- """ , :F_and_∇ₓF , force= true )
142
- fun. f, fun. jac
143
- end
144
- F_and_∇ₓF (args... ) = F_and_∇ₓF (AIBECSFunction (args... ))
145
- export F_and_∇ₓF
146
-
147
-
148
-
149
-
150
76
"""
151
77
localderivative(G, x, p)
152
78
localderivative(Gᵢ, xs, i, p)
166
92
function localderivative (Gᵢ, xs, j, p) # for multiple tracers
167
93
return ForwardDiff. derivative (λ -> Gᵢ (perturb_tracer (xs, j, λ)... , p), 0.0 )
168
94
end
169
- function localderivative (Gᵢ!, dx, xs, j, p) # if Gᵢ are in-place
170
- return ForwardDiff. derivative ((dx, λ) -> Gᵢ! (dx, perturb_tracer (xs, j, λ)... , p), dx, 0.0 )
171
- end
172
95
perturb_tracer (xs, j, λ) = (xs[1 : j - 1 ]. .. , xs[j] .+ λ, xs[j + 1 : end ]. .. )
173
96
174
97
@@ -202,19 +125,11 @@ export split_state_function_and_Jacobian
202
125
function local_jacobian (Gs, x, p, nt, nb)
203
126
return reduce (vcat, local_jacobian_row (Gⱼ, x, p, nt, nb) for Gⱼ in Gs)
204
127
end
205
- function inplace_local_jacobian (Gs, x, p, nt, nb)
206
- return reduce (vcat, inplace_local_jacobian_row (Gⱼ!, x, p, nt, nb) for Gⱼ! in Gs)
207
- end
208
128
209
129
function local_jacobian_row (Gᵢ, x, p, nt, nb)
210
130
tracers (x) = state_to_tracers (x, nb, nt)
211
131
return reduce (hcat, sparse (Diagonal (localderivative (Gᵢ, tracers (x), j, p))) for j in 1 : nt)
212
132
end
213
- function inplace_local_jacobian_row (Gᵢ!, x, p, nt, nb)
214
- tracers (x) = state_to_tracers (x, nb, nt)
215
- dx = Vector {Float64} (undef, nb)
216
- return reduce (hcat, sparse (Diagonal (localderivative (Gᵢ!, dx, tracers (x), j, p))) for j in 1 : nt)
217
- end
218
133
219
134
#= ============================================
220
135
Generate 𝑓 and derivatives from user input
0 commit comments