Hi Chris,
No problem, it’s great to see more interest in the NLBVP! I think you’re understanding of how Dedalus is doing things is essentially correct, and the issues you’re seeing are due to using numpy functions on scipy sparse arrays.
To make sure we’re on the same page, the docstring on the NLBVP problem class
here describes the problem setup. We essentially start with N(X) = 0, but split the linear and nonlinear terms like N(X) = L.X - F(X) = 0 ==> L.X = F(X), so the solver only has to recompute the Jacobian of F, and not rebuild the L matrices, every iteration. This problem is written as a BVP for a perturbation/update around some initial state as (L - F’(X0)).X1 = F(X0) - L.X0, which is equivalent to N’(X0).X1 = -N(X0), or simply A.X1 = b for the update.
The Newton step routine can be found
here. It uses the current values of solver.state to compute N(X0) and N’(X0) (lines 236 and 238). Then it builds the A matrix and b vectors using this data (lines 243-244), and solves for the update X1 in line 245. The routine then adds these perturbations back to the state vector.
The matrix A is a scipy sparse matrix, and b is a dense numpy vector. Scipy sparse matrices are not natively supported in must regular numpy functions — in particular, np.dot(A,b) with these types produces a numpy object array, which causes the first error, and np.linalg.pinv(A) directly throws the second error.
Depending on your problem (and particularly the NCC cutoff), matrix A may still be fairly sparse, in which case it might be better to use the scipy sparse linear algebra tools and sparse matrix methods, like A.dot(_). Otherwise, you can use the A.todense() method to convert to a dense numpy array, and then use any numpy linear algebra functions.
Everything else should still work, with A and b from lines 243-244 representing the Jacobian and residual on each iteration, no matter how you choose to determine the update x in line 245.
Hope that helps, and definitely give an update if you run into more issues or get something working with one of the scipy optimization routines!
Best,
-Keaton