The standard workfllow to access the solution of a nonlinear_eq = NonlinearProblem is something like
sol = SciMLBase.solve(nonlinear_eq, NewtonRaphson(autodiff = AutoFiniteDiff()));
Is it possible to suppress the build-up of the sol object and have the solution written directly to the initial guess which is supplied in construction of the NonlinearProblem?
alias_u0 = true, though we’re rolling out a whole aliasing system to simplify this, so that will be deprecated very soon for just a more comprehensive verbose
How big is your system? If it’s small, use static arrays and they all stack allocate with SimpleNonlinearSolve. If it’s big then these ones don’t matter: the Jacobian is O(n^2) vs these O(n). The general way to do the big ones would be to use the cache = init(prob) interface, though I’m cleaning that up a bit in order to get it documented so that might need to wait till over the weekend to have a fully non-allocating form.
So eventually I would like to go to millions of unknowns, as I am trying to build a special IMEX-multirate integration scheme for Trixi.jl
Thanks, good to know! I was wondering how to go about this, since NonlinearProblem itself is immutable - which leads to me currently re-initializing it all the time despite only parameter and initial guess changes.
I also played a bit with this, and managed to store the NonlinearProblem somewhere persistent, but I currently cannot avoid repeated init calls when the parameters p and/or the initial guess u changes. Is this expected?
sol = SciMLBase.solve!(integrator.nonlin_cache)
copyto!(integrator.k_nonlin, sol.u)
instead of just having it directly written in integrator.k_nonlin.
I initialize Problem and Cache as
nonlin_prob = NonlinearProblem{true}(stage_residual_midpoint!,
k_nonlin, p)
nonlin_cache = SciMLBase.init(nonlin_prob,
NewtonRaphson(autodiff = AutoFiniteDiff());
# This works if I specify it directly in a `solve` call
alias = SciMLBase.NonlinearAliasSpecifier(alias_u0 = true))
SciMLBase.reinit!(integrator.nonlin_cache, integrator.k_nonlin;
# Added `alias` again here
alias = SciMLBase.NonlinearAliasSpecifier(alias_u0 = true))
#println("inplace: ", SciMLBase.isinplace(integrator.nonlin_cache)) # true
# These seems unfortunately also not to work, and gives different results than `reinit!`
#SciMLBase.set_u!(integrator.nonlin_cache, integrator.k_nonlin)
#sol = SciMLBase.solve!(integrator.nonlin_cache)
#copyto!(integrator.k_nonlin, sol.u)
# Does not write the results back to `integrator.k_nonlin`
SciMLBase.solve!(integrator.nonlin_cache)
does still not what I want - although I would like to remark that the approach with writing out sol seems to allocate the same memory as the approach without writing into sol - so maybe I am fine with the current way.