-
Notifications
You must be signed in to change notification settings - Fork 17
Implicit solvers
Some docs here: https://diffeq.sciml.ai/dev/features/linear_nonlinear/
-
Val{true}implies it operates in-place
-
Calls
build_nlsolver, dispatching onAbstractNLSolverAlgorithmtype: these are defined in DiffEqBase. e.g.NLNewton, which would callbuild_nlsolver.a.
nf = nlsolve_f(f, alg), which extracts the implicit part if using aSplitFunctionb.
SciMLBase.islinear(f): this appears to only betrueiff(orf.f1) is anAbstractDiffEqOperatorthatisconstant?-
If so, then it sets
ufandjac_configtonothing, and callslinsolve(Val{:init},nf,u). Otherwise... -
uf = build_uf(alg,nf,t,p,Val(true)): returns aSciMLBase.UJacobianWrapper, which captures the function, parameter and time, and can be called with just(dest, src)args (to make it easier to use the AD tools I assume?). -
jac_config = build_jac_config(alg,nf,uf,du1,uprev,u,ztmp,dz): I think it allocates the cache for forming the Jacobian matrix?
c.
build_J_W:-
islinearfunction(f, alg): "return the tuple(is_linear_wrt_odealg, islinearodefunction).": 2nd is true ifislinear(f), 1st if 2nd oralg isa SplitAlgorithmsandislinear(f.f1.f)? -
One of:
-
if
f.jac_prototype isa DiffEqBase.AbstractDiffEqLinearOperator:W = WOperator{IIP}(f, u, dt),J = W.J -
if
f.jac_prototype !== nothing:J = similar(f.jac_prototype);W = similar(J) -
if
islin: unwrapfif split; wrap inDiffEqArrayOperatorto getJ;W = WOperator{IIP}(f.mass_matrix, dt, J, u) -
otherwise
J = ArrayInterface.zeromatrix(u);W = similar(J).
-
-
Returns
J, W
d.
nlcache = NLNewtonConstantCacheobjecte. returns
NLSolverobject. -
a. update_W!
- [`calc_W!`](https://github.com/SciML/OrdinaryDiffEq.jl/blob/v5.59.1/src/derivative_utils.jl#L422) with `transform=true`
- if `DiffEqBase.has_Wfact_t(f)`
- `set_W_γdt!(nlsolver, dtgamma)`
- otherwise:
- `do_newJW`
- if `W isa WOperator`:
- `DiffEqBase.update_coefficients!(W,uprev,p,t)`
- otherwise
- `calc_J!(J, integrator, lcache)` if `J` changed in `do_newJW`
- `update_coefficients!(mass_matrix,uprev,p,t)`
- `jacobian2W!(W, mass_matrix, dtgamma, J, W_transform)` if `W` changed in `do_newJW`
- `set_new_W!(nlsolver, new_W)`
- `set_W_γdt!(nlsolver, dtgamma)` if `W` changed in `do_newJW`