Skip to content

Commit 3c35141

Browse files
committed
Add preconditioner functions for Sundials and Julia solver
1 parent 2bc600b commit 3c35141

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

src/Reactor.jl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ using DiffEqBase
33
using ForwardDiff
44
using Sundials
55
using ModelingToolkit
6+
using IncompleteLU
7+
using LinearAlgebra
8+
using SparseArrays
69
abstract type AbstractReactor end
710
export AbstractReactor
811

@@ -163,6 +166,73 @@ function Reactor(domains::T,y0s::W,tspan::W2,interfaces::Z=Tuple(),ps::X=DiffEqB
163166
end
164167
export Reactor
165168

169+
#preconditioner related functions
170+
@inline function _psetupsundials(p::T1, t::T2, u::T3, du::T4, jok::Bool, jcurPtr::T5, gamma::T6, jac!::T7, W::T8, preccache::T9, tau::T10) where {T1,T2,T3,T4,T5,T6,T7,T8,T9,T10}
171+
"""
172+
Update preconditioner when Jacobian needs to be updated for Sundials solvers. Credit to tutorial of DifferentialEquations.jl.
173+
p: the parameters
174+
t: the current independent variable
175+
u: the current state
176+
du: the current f(u,p,t)
177+
jok: a bool indicating whether the Jacobian needs to be updated
178+
jcurPtr: a reference to an Int for whether the Jacobian was updated. jcurPtr[]=true should be set if the Jacobian was updated, and jcurPtr[]=false should be set if the Jacobian was not updated.
179+
gamma: the gamma of W = M - gamma*J
180+
"""
181+
if jok
182+
@. W = 0.0
183+
jac!(W,u,p,t)
184+
jcurPtr[] = true
185+
186+
# W = I - gamma*J
187+
@. W.nzval = -gamma*W.nzval
188+
idxs = diagind(W)
189+
@inbounds @views @. W[idxs] = W[idxs] + 1
190+
191+
# Build preconditioner on W
192+
preccache[] = ilu(W, τ = tau)
193+
end
194+
nothing
195+
end
196+
@inline function _precsundials(z::T1, r::T2, p::T3, t::T4, y::T5, fy::T6, gamma::T7, delta::T8, lr::T9, preccache::T10) where {T1,T2,T3,T4,T5,T6,T7,T8,T9,T10}
197+
"""
198+
Compute preccache \\ r in-place and store the result in z for Sundials solver. Credit to tutorial of DifferentialEquations.jl.
199+
z: the computed output vector
200+
r: the right-hand side vector of the linear system
201+
p: the parameters
202+
t: the current independent variable
203+
du: the current value of f(u,p,t)
204+
gamma: the gamma of W = M - gamma*J
205+
delta: the iterative method tolerance
206+
lr: a flag for whether lr=1 (left) or lr=2 (right) preconditioning
207+
preccache: preconditioner cache
208+
"""
209+
ldiv!(z,preccache[],r)
210+
end
211+
@inline function _precsjulia(W::T1,du::T2,u::T3,p::T4,t::T5,newW::T6,Plprev::T7,Prprev::T8,solverdata::T9,tau::T10) where {T1,T2,T3,T4,T5,T6,T7,T8,T9,T10}
212+
"""
213+
Update preconditioner when Jacobian needs to be updated for Julia solvers. Credit to tutorial of DifferentialEquations.jl.
214+
W: I - gamma*J or I/gamma - J depending on the algorithm.
215+
Commonly be a WOperator type defined by OrdinaryDiffEq.jl. It is a lazy representation of the operator
216+
Users can construct the W-matrix on demand by calling convert(AbstractMatrix,W) to receive an AbstractMatrix matching the jac_prototype.
217+
du: the current ODE derivative
218+
u: the current ODE state
219+
p: the ODE parameters
220+
t: the current ODE time
221+
newW: a Bool which specifies whether the W matrix has been updated since the last call to precs.
222+
It is recommended that this is checked to only update the preconditioner when newW == true.
223+
Plprev: the previous Pl.
224+
Prprev: the previous Pr.
225+
solverdata: Optional extra data the solvers can give to the precs function. Solver-dependent and subject to change.
226+
"""
227+
if newW === nothing || newW
228+
Pl = ilu(convert(AbstractMatrix,W), τ = tau)
229+
else
230+
Pl = Plprev
231+
end
232+
Pl,nothing
233+
end
234+
235+
166236
@inline function getrate(rxn::T,cs::Array{W,1},kfs::Array{Q,1},krevs::Array{Q,1}) where {T<:AbstractReaction,Q,W<:Real}
167237
Nreact = length(rxn.reactantinds)
168238
Nprod = length(rxn.productinds)

0 commit comments

Comments
 (0)