<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 11, 2016 at 10:39 AM, Barry Smith <span dir="ltr"><<a href="mailto:bsmith@mcs.anl.gov" target="_blank">bsmith@mcs.anl.gov</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-"><br>
> On Oct 11, 2016, at 9:33 AM, Kong, Fande <<a href="mailto:fande.kong@inl.gov">fande.kong@inl.gov</a>> wrote:<br>
><br>
> Barry, Thanks so much for your explanation. It helps me a lot.<br>
><br>
> On Mon, Oct 10, 2016 at 4:00 PM, Barry Smith <<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>> wrote:<br>
><br>
> > On Oct 10, 2016, at 4:01 PM, Kong, Fande <<a href="mailto:fande.kong@inl.gov">fande.kong@inl.gov</a>> wrote:<br>
> ><br>
> > Hi All,<br>
> ><br>
> > I know how to remove the null spaces from a singular system using creating a MatNullSpace and attaching it to Mat.<br>
> ><br>
> > I was really wondering what is the philosophy behind this? The exact algorithms we are using in PETSc right now? Where we are dealing with this, preconditioner, linear solver, or nonlinear solver?<br>
><br>
> It is in the Krylov solver.<br>
><br>
> The idea is very simple. Say you have a singular A with null space N (that all values Ny are in the null space of A. So N is tall and skinny) and you want to solve A x = b where b is in the range of A. This problem has an infinite number of solutions Ny + x* since A (Ny + x*) = ANy + Ax* = Ax* = b where x* is the "minimum norm solution; that is Ax* = b and x* has the smallest norm of all solutions.<br>
><br>
> With left preconditioning B A x = B b GMRES, for example, normally computes the solution in the as alpha_1 Bb + alpha_2 BABb + alpha_3 BABABAb + .... but the B operator will likely introduce some component into the direction of the null space so as GMRES continues the "solution" computed will grow larger and larger with a large component in the null space of A. Hence we simply modify GMRES a tiny bit by building the solution from alpha_1 (I-N)Bb + alpha_2 (I-N)BABb + alpha_3<br>
><br>
> Does "I" mean an identity matrix? Could you possibly send me a link for this GMRES implementation, that is, how PETSc does this in the actual code?<br>
<br>
</span> Yes.<br>
<br>
It is in the helper routine KSP_PCApplyBAorAB()<br>
#undef __FUNCT__<br>
#define __FUNCT__ "KSP_PCApplyBAorAB"<br>
PETSC_STATIC_INLINE PetscErrorCode KSP_PCApplyBAorAB(KSP ksp,Vec x,Vec y,Vec w)<br>
{<br>
PetscErrorCode ierr;<br>
PetscFunctionBegin;<br>
if (!ksp->transpose_solve) {<br>
ierr = PCApplyBAorAB(ksp->pc,ksp->pc_<wbr>side,x,y,w);CHKERRQ(ierr);<br>
ierr = KSP_RemoveNullSpace(ksp,y);<wbr>CHKERRQ(ierr);<br>
} else {<br>
ierr = PCApplyBAorABTranspose(ksp-><wbr>pc,ksp->pc_side,x,y,w);<wbr>CHKERRQ(ierr);<br>
}<br>
PetscFunctionReturn(0);<br>
}<br></blockquote><div><br><br>PETSC_STATIC_INLINE PetscErrorCode KSP_RemoveNullSpace(KSP ksp,Vec y)<br>{<br> PetscErrorCode ierr;<br> PetscFunctionBegin;<br> if (ksp->pc_side == PC_LEFT) {<br> Mat A;<br> MatNullSpace nullsp;<br> ierr = PCGetOperators(ksp->pc,&A,NULL);CHKERRQ(ierr);<br> ierr = MatGetNullSpace(A,&nullsp);CHKERRQ(ierr);<br> if (nullsp) {<br> ierr = MatNullSpaceRemove(nullsp,y);CHKERRQ(ierr);<br> }<br> }<br> PetscFunctionReturn(0);<br>}<br><br>"ksp->pc_side == PC_LEFT" deals with the left preconditioning Krylov methods only? How about the right preconditioning ones? Are they just magically right for the right preconditioning Krylov methods? <br><br></div><div>Fande Kong,<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
There is no code directly in the GMRES or other methods.<br>
<span class="gmail-"><br>
><br>
> (I-N)BABABAb + .... that is we remove from each new direction anything in the direction of the null space. Hence the null space doesn't directly appear in the preconditioner, just in the KSP method. If you attach a null space to the matrix, the KSP just automatically uses it to do the removal above.<br>
><br>
> With right preconditioning the solution is built from alpha_1 b + alpha_2 ABb + alpha_3 ABABb + .... and again we apply (I-N) to each term to remove any part that is in the null space of A.<br>
><br>
> Now consider the case A y = b where b is NOT in the range of A. So the problem has no "true" solution, but one can find a least squares solution by rewriting b = b_par + b_perp where b_par is in the range of A and b_perp is orthogonal to the range of A and solve instead A x = b_perp. If you provide a MatSetTransposeNullSpace() then KSP automatically uses it to remove b_perp from the right hand side before starting the KSP iterations.<br>
><br>
> The manual pages for MatNullSpaceAttach() and MatTranposeNullSpaceAttach() discuss this an explain how it relates to the fundamental theorem of linear algebra.<br>
><br>
> Note that for symmetric matrices the two null spaces are the same.<br>
><br>
> Barry<br>
><br>
><br>
> A different note: This "trick" is not a "cure all" for a totally inappropriate preconditioner. For example if one uses for a preconditioner a direct (sparse or dense) solver or an ILU(k) one can end up with a very bad solver because the direct solver will likely produce a very small pivot at some point thus the triangular solver applied in the precondition can produce HUGE changes in the solution (that are not physical) and so the preconditioner basically produces garbage. On the other hand sometimes it works out ok.<br>
><br>
> What preconditioners are appropriate? asm, bjacobi, amg? I have an example which shows lu and ilu indeed work, but asm and bjacobi do not at all. That is why I am asking questions about algorithms. I am trying to figure out a default preconditioner for several singular systems.<br>
<br>
</span> Hmm, normally asm and bjacobi would be fine with this unless one or more of the subblocks are themselves singular (which normally won't happen). AMG can also work find sometimes.<br>
<br>
Can you send a sample code?<br>
<span class="gmail-HOEnZb"><font color="#888888"><br>
Barry<br>
</font></span><div class="gmail-HOEnZb"><div class="gmail-h5"><br>
><br>
> Thanks again.<br>
><br>
><br>
> Fande Kong,<br>
><br>
><br>
><br>
> ><br>
> ><br>
> > Fande Kong,<br>
<br>
</div></div></blockquote></div><br></div></div>