-
-
Notifications
You must be signed in to change notification settings - Fork 51
Description
- https://link.springer.com/book/10.1007/0-387-30260-3 Chapter 7
- https://escholarship.org/content/qt80t380tv/qt80t380tv_noSplash_18a25fa49e487cb213e64ecee5b003fb.pdf?t=li54ql
- https://apps.dtic.mil/sti/tr/pdf/ADA317005.pdf
The idea is that instead of solving one giant Newton method, you can instead split it up into successive Newton solves that are then recursed based on the strongly connected components.
The algorithms of ModelingToolkit are already able to put the system in BLT form and do the tearing process to reduce the systems. I think as a general nonlinear solver, it would be good to, instead of baking this into MTK in some form, have a way to be able to express such structural systems with NonlinearSolve.jl and have MTK generate code to that interface.
I could see this happening in a few forms:
- We could do this on split vectors.
- We could do this by passing extra structural information for scheduling.
SCCNonlinearFunction((f1,f2,f3), jac = (J1,J2,J3))
would be needed for both. But the question is do you make u0 = [a1,a2,a3]
where each a[i]
is an array for the SCC[i], or do you make this segmented?
Effectively the question is as follows. If you do this in the segmented way, then f1(resid, a1, p)
, f2(resid, a1, a2, p)
, f3(resid, a1, a2, a3, p)
is the target, i.e. each has more arguments as you go along. I could see this having some compilation difficulties, so you could just do this as fi(resid,u,p)
where u
is an array-of-arrays.
Or, at that point, you could just give the whole u
array but with a known structure used by the solver that is not enforced in the definition of fi
. For this interface, you would still have to give split scheduled functions SCCNonlinearFunction((f1,f2,f3), jac = (J1,J2,J3))
, but with sizes of resid
being chosen to match the size of the current nonlinear system. You could just create one resid
with the maximum size of the strongly connected components, and then just use views of that in each such component. Thus SCCNonlinearProblem(f,u0, lengths, p)
would just need to know the length of each SCC, and then schedule the algorithm into the cascading functions from there. This would probably need to impose an AbstractVector
structure on u0
, whereas the split form would be easier for handling more array types.
The split form could be nicely handled by keeping the cache of arrays of arrays but having a mapping method to_arrarr!(a,u0)
that takes a flattened version of the vector into the SCC split structure. So I don't think it would necessarily have more allocations beyond the setup phase.
So of the ways to represent this, I think I'd rank:
- Array of arrays
fi(resid,u,p)
- Flattened
fi(resid,u,p)
with sizes f1(resid, a1, p)
,f2(resid, a1, a2, p)
,f3(resid, a1, a2, a3, p)
With the last one effectively eliminated for compile time concerns. I like that the first enforces that the BLT form is respected, to an extent. Someone could still modify u
, but that's always a concern 😅.