Wow, a lot of discussion.
My interest in saving eigenvectors primarily stems from the siloing of the results from the EVP solver; I simply don't know how else one could reasonably re-use those results after calling the EVP solver from within a function. I am certain some part of this stems from my own python ignorance.
For my purposes, the most convenient method for saving the eigenfunctions is to use numpy's built-in `savez` and `load` methods. I have a function which takes as input a domain and fields, sets up and solves the eigenproblem using linearization, and then iterates through the N indices of the eigenvalues, calling set_state() appropriately, and copying the coefficients to a pre-allocated numpy matrix, which is returned along with a copy of the similarly ordered eigenvalues.
I call this function twice -- once for the right eigenfunctions, and once for the left eigenfunctions. The latter use the explicitly defined Jacobian, rather than the parsers linearization.
For computing the inner products, it's most convenient to build a new np.complex128 domain, define a set of fields for the left eigenfunctions of the system (W#) and the right eigenfunctions of the system (V#), and then again iterate through the N modes, copying the amplitudes to the newly defined fields, and then calling (for a two-variable system)
WV[m,n] = de.operators.integrate(W1*V1 + W2*V2, 'x').evaluate()['g'][0]
for each of the N^2 pairings. It's amazingly slow, but perfectly functional, and it avoids some frustrations I ran into with re-using domains.
There are some lingering issues I'm struggling to solve regarding the EVP output, but that's a discussion for another time.