Florian,
CR is indeed possible in a multilevel solver. In fact, we have an
example in Examples/CompatibleRelaxation of creating a splitting.
The idea is that
splitting = CR(A)
is called and fed to a classical AMG solver. As you point out, there
may be some limitations with interpolation in classical AMG. We have
direct interpolation implemented in pyamg/classical/interpolate.py,
but it would be straightforward to extend this to more general
settings. (In the solver below, direction interpolation works fine in
a two level method).
Also, two cautions with the state of CR in PyAMG right now. The first
is that only 'habituated' CR is implemented. There is a placeholder
for a 'concurrent' version. The second is that we haven't profiled
this code heavily so there may be performance issues. For example, I
suspect that the biorthogonalization would benefit from some C++
optimization.
I've added to two tickets for these issues. We're targeting a new
release soon and I'll try to put these in.
Let me know if you run into problems, but the framework is all there
to analyze a multilevel CR. I'm pasting an example called demo2.py.
To run it you need to make one change to classical.py so that CR can
be called. Add this:
elif CF in ['CR']:
import cr
splitting = cr.CR(A,method='habituated',maxiter=20)
after the first if CF statement here:
http://code.google.com/p/pyamg/source/browse/trunk/pyamg/classical/classical.py#109
One issue with the example is that it hangs for more than two levels.
I'm not sure why this is happening, but the two level method works
fine.
Luke
%%%%
import numpy
import scipy
from pyamg.gallery import poisson
from pyamg.classical import CR
from pyamg.vis import vis_splitting
from pyamg import ruge_stuben_solver
print '----setting up problem'
n = 25
A=poisson((n,n)).tocsr()
xx = numpy.arange(0,n,dtype=float)
x,y = numpy.meshgrid(xx,xx)
Verts = numpy.concatenate([[x.ravel()],[y.ravel()]],axis=0).T
print '----setting up RS solver'
mls = ruge_stuben_solver(A, max_levels=2, max_coarse=5, CF='CR')
print mls
print '----running RS solver'
resvec = []
b = numpy.zeros((A.shape[0],))
z = x = scipy.rand(A.shape[0])
z = mls.solve(b, x0=z, maxiter=200, tol=1e-8, residuals=resvec)
avgconvergencefactor = (resvec[-1]/resvec[0])**(1.0/len(resvec))
allconvergencefactor = numpy.array(resvec[1::])/
numpy.array(resvec[0:-1:])
print avgconvergencefactor
print allconvergencefactor
print '----setting up print'
from pylab import figure, axis, scatter, show
splitting = mls.levels[0].splitting
C_nodes = splitting == 1
F_nodes = splitting == 0
figure(figsize=(6,6))
axis('equal')
scatter(Verts[:,0][C_nodes], Verts[:,1][C_nodes], c='r', s=100.0)
#plot C-nodes in red
scatter(Verts[:,0][F_nodes], Verts[:,1][F_nodes], c='b', s=100.0)
#plot F-nodes in blue
show()
%%%%