I am interacting with TSAdjoint from firedrake. TSAdjoint takes the jacobian of your PDE and calls KSPSolveTranspose to get the adjoint function. The jacobian is already assembled with the boundary conditions. I believe this is messing up with the preconditioners. For instance, in the following mwe, I calculate the adjoint function using solve and using KSPSolveTranspose. With a direct solver, they both return the same solution. With the iterative solver, KSPSolveTranspose does not converge in 100 iterations.
It seems that the main difference is that in the first case, the adjoint/transpose operation precedes the application of the boundary conditions (I believe), whereas the opposite happens in the second case.
Is there any way to hand KSPSolveTranspose() a jacobian or solver parameters to make it converge reasonably? Bear in mind that KSPSolveTranspose() is deep in the TSAdjoint implementation. I do not know how easy it will be to replace with something that looks like the first adjoint solve.
I am interacting with TSAdjoint from firedrake. TSAdjoint takes the jacobian of your PDE and calls
KSPSolveTranspose
to get the adjoint function. The jacobian is already assembled with the boundary conditions. I believe this is messing up with the preconditioners. For instance, in the following mwe, I calculate the adjoint function usingsolve
and usingKSPSolveTranspose
. With a direct solver, they both return the same solution. With the iterative solver,KSPSolveTranspose
does not converge in 100 iterations.It seems that the main difference is that in the first case, the adjoint/transpose operation precedes the application of the boundary conditions (I believe), whereas the opposite happens in the second case.
Is there any way to hand
KSPSolveTranspose()
a jacobian or solver parameters to make it converge reasonably? Bear in mind thatKSPSolveTranspose()
is deep in the TSAdjoint implementation. I do not know how easy it will be to replace with something that looks like the first adjoint solve.