I'm using a Krylov solver as in the stokes-iterative demo. However, it runs extremely slow. Is there a way to set the initial guess so as to speed the process up?
Thanks,
Amanda
Yes, just set
parameters['krylov_solver']['nonzero_initial_guess'] = True
The solver will then use whatever you have put in your solution Function as initial guess. The parameter above defaults to False.
Function
False
Mikael,
Thank you for your quick response. I have implemented the line of code above, but would you mind elaborating on the meaning of "the solver will then use whatever you have put in your solution Function as initial guess"? Specifically, if I were to put a time stepping loop on the stokes-iterative demo and use the code above, would the Krylov solver use the solution from the first time step as the initial guess for the second time step?
Furthermore, is there a way to determine what initial guess the Krylov solver is using?
Thanks for the help!
Hi,
If you put this at the start of the stokes-iterative demo:
parameters['krylov_solver']['nonzero_initial_guess'] = True parameters['krylov_solver']['monitor_convergence'] = True
then you'll see the progression of the solver. It should take 59 iterations to converge. Now after finishing the solution will be in your U Function object. So if you now were to restart your solver once more with
solver.solve(U.vector(), bb)
then the solver will start from the converged solution and use just one iteration. If you do
U.vector()[:] = 0. solver.solve(U.vector(), bb)
then you'll start from initial guess = 0 and you will again use 59 iterations. If
parameters['krylov_solver']['nonzero_initial_guess'] = False
then you'll always use 59 iterations.
So if you put the stokes-iterative demo in a time stepping loop you'll start from the previous solution. See the Navier-Stokes demo for a similar example with a time loop.
Hope this answers your question.
Hi Mikael,
I really appreciate your help! However, I have attempted to implement your suggestion above and it just doesn't seem to work. I am copying my altered stokes-iterative demo below. All I have done at this point is put in the two lines at the beginning...
and run the solver twice, hoping the second time it runs will only take one step as you suggest. Unfortunately, both times through, it takes 33 steps. Here is my code. Please let me know if I have misunderstood your suggestion.
Thanks again!
from dolfin import *
if not has_linear_algebra_backend("PETSc") and not has_linear_algebra_backend("Epetra"): info("DOLFIN has not been configured with Trilinos or PETSc. Exiting.") exit() if not has_krylov_solver_preconditioner("amg"): info("Sorry, this demo is only available when DOLFIN is compiled with AMG preconditioner, Hypre or ML."); exit()
mesh = UnitCubeMesh(16, 16, 16)
V = VectorFunctionSpace(mesh, "CG", 2) Q = FunctionSpace(mesh, "CG", 1) W=V* Q
def right(x, on_boundary): return x[0] > (1.0 - DOLFIN_EPS) def left(x, on_boundary): return x[0] < DOLFIN_EPS def top_bottom(x, on_boundary): return x[1] > 1.0 - DOLFIN_EPS or x[1] < DOLFIN_EPS
noslip = Constant((0.0, 0.0, 0.0)) bc0 = DirichletBC(W.sub(0), noslip, top_bottom)
inflow = Expression(("-sin(x[1]*pi)", "0.0", "0.0")) bc1 = DirichletBC(W.sub(0), inflow, right)
zero = Constant(0) bc2 = DirichletBC(W.sub(1), zero, left)
bcs = [bc0, bc1, bc2]
(u, p) = TrialFunctions(W) (v, q) = TestFunctions(W) f = Constant((0.0, 0.0, 0.0)) a = inner(grad(u), grad(v))dx + div(v)pdx + qdiv(u)dx L = inner(f, v)dx
b = inner(grad(u), grad(v))dx + pq*dx
A, bb = assemble_system(a, L, bcs)
P, btmp = assemble_system(b, L, bcs)
solver = KrylovSolver("tfqmr", "amg")
solver.set_operators(A, P)
U = Function(W) solver.solve(U.vector(), bb)
**# Test for KrylovSolver initial guess. solver = KrylovSolver("tfqmr", "amg")
U = Function(W) solver.solve(U.vector(), bb)**
u, p = U.split()
ufile_pvd = File("velocity.pvd") ufile_pvd << u pfile_pvd = File("pressure.pvd") pfile_pvd << p
plot(u) plot(p) interactive()
You might want to edit your question...
I'm not saying you should run the entire file twice. Run it once in a python shell, then when everything is finished, simply call the solver from the command-line:
If you're not already using IPython I strongly suggest you get started with it.
I think I got it. Thanks again for all your help!
Hi Mikael, I read this post and still don't figure out how to provide a nonzero initial guess for the solver. Could you please take a look at my question here. Thank you so much in advance.