<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Mar 24, 2021, at 5:08 AM, feng wang <<a href="mailto:snailsoar@hotmail.com" class="">snailsoar@hotmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;" class="">Hi Barry,</div><div style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;" class=""><br class=""></div><div style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;" class="">Thanks for your comments. It's very helpful. For your comments, I have a bit more questions</div><div style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;" class=""><br class=""></div><div style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;" class=""><ol class=""><li class=""><span class="">for your 1st comment " Yes, in some sense. So long as each process ....".<span class="Apple-converted-space"> </span><br class=""></span></li><ol style="list-style-type: lower-alpha;" class=""><li class=""><span class="">If I understand it correctly (hopefully) a parallel vector in petsc can hold discontinuous rows of data in a global array. If this is true, If I call "VecGetArray", it would create a copy in a continuous space if the data is not continuous, do some operations and petsc will figure out how to put updated values back to the right place in the global array? <span class="Apple-converted-space"> </span><br class=""></span></li><li class=""><span class="">This would generate an overhead. If I do the renumbering to make each process hold continuous rows, this overhead can be avoided when I call "VecGetArray"?</span></li></ol></ol></div></div></blockquote><div><br class=""></div> GetArray does nothing except return the pointer to the data in the vector. It does not copy anything or reorder anything. Whatever order the numbers are in vector they are in the same order as in the array you obtain with VecGetArray.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;" class=""><ol class="" start="2"><li class=""><span class="">for your 2nd comment " The matrix and vectors the algebraic solvers see DO NOT have......." For the callback function of my shell matrix "mymult(Mat m ,Vec x, Vec y)", I need to get "x" for the halo elements to compute the non-linear function. My code will take care of other halo exchanges, but I am not sure how to use petsc to get the halo elements "x" in the shell matrix, could you please elaborate on this? some related examples or simple pesudo code would be great.<br class=""></span></li></ol></div></div></blockquote><div> Basically all the parallel code in PETSc does this. How you need to set up the halo communication depends on how you are managing the assignment of degrees of freedom on each process and between processes. VecScatterCreate() is the tool you will use to tell PETSc how to get the correct values from one process to their halo-ed location on the process. It like everything in PETSc uses a number in the vectors of 0 ... n_0-1 on the first process, n_0, n_0+1, ... n_1-1 on the second etc. Since you are managing the partitioning and distribution of parallel data you must renumber the vector entry numbering in your data structures to match that shown above. Just do the numbering once after you have setup your distributed data and use it for the rest of the run. You might use the object from AOCreate to do the renumbering for you. </div><div><br class=""></div><div> Barry</div><div><br class=""></div><div><br class=""></div> <br class=""><blockquote type="cite" class=""><div class=""><div style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;" class=""><div class="">Thanks,</div><div class="">Feng<br class=""></div></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div id="appendonsend" class=""></div><div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;" class=""><br class=""></div><hr tabindex="-1" style="display: inline-block; width: 1200.5px;" class=""><div id="divRplyFwdMsg" dir="ltr" class=""><font face="Calibri, sans-serif" style="font-size: 11pt;" class=""><b class="">From:</b><span class="Apple-converted-space"> </span>Barry Smith <<a href="mailto:bsmith@petsc.dev" class="">bsmith@petsc.dev</a>><br class=""><b class="">Sent:</b><span class="Apple-converted-space"> </span>22 March 2021 1:28<br class=""><b class="">To:</b><span class="Apple-converted-space"> </span>feng wang <<a href="mailto:snailsoar@hotmail.com" class="">snailsoar@hotmail.com</a>><br class=""><b class="">Cc:</b><span class="Apple-converted-space"> </span><a href="mailto:petsc-users@mcs.anl.gov" class="">petsc-users@mcs.anl.gov</a><span class="Apple-converted-space"> </span><<a href="mailto:petsc-users@mcs.anl.gov" class="">petsc-users@mcs.anl.gov</a>><br class=""><b class="">Subject:</b><span class="Apple-converted-space"> </span>Re: [petsc-users] Questions on matrix-free GMRES implementation</font><div class=""> </div></div><div class="" style="word-wrap: break-word; line-break: after-white-space;"><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Mar 21, 2021, at 6:22 PM, feng wang <<a href="mailto:snailsoar@hotmail.com" class="">snailsoar@hotmail.com</a>> wrote:</div><br class="x_Apple-interchange-newline"><div class=""><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Hi Barry,</div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none;">Thanks for your help, I really appreciate it.<span class="x_Apple-converted-space"> </span><br class=""></div><div class="" style="font-family: Helvetica; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none;">In the end I used a shell matrix to compute the matrix-vector product, it is clearer to me and there are more things under my control. I am now trying to do a parallel implementation, I have some questions on setting up parallel matrices and vectors for a user-defined partition, could you please provide some advice? Suppose I have already got a partition for 2 CPUs. Each cpu is assigned a list of elements and also their halo elements.<br class=""></div><div class="" style="font-family: Helvetica; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none;"><ol class=""><li class="">The global element index for each partition is not necessarily continuous, do I have to I re-order them to make them continuous?<br class=""></li></ol></div></div></blockquote><div class=""><br class=""></div> Yes, in some sense. So long as each process can march over ITS elements computing the function and Jacobian matrix-vector product it doesn't matter how you have named/numbered entries. But conceptually the first process has the first set of vector entries and the second the second set. <br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none;"><ol class=""><li class=""><span class=""></span><br class=""></li><li class=""><span class="">When I set up the size of the matrix and vectors for each cpu, should I take into account the halo elements? <span class="x_Apple-converted-space"> </span><br class=""></span></li></ol></div></div></blockquote><div class=""><br class=""></div> The matrix and vectors the algebraic solvers see DO NOT have halo elements in their sizes. You will likely need a halo-ed work vector to do the matrix-free multiply from. The standard model is use VecScatterBegin/End to get the values from the non-halo-ed algebraic vector input to MatMult into a halo-ed one to do the local product.</div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none;"><ol class="" start="3"><li class=""><span class="">In my serial version, when I initialize my RHS vector, I am not using VecSetValues, Instead I use VecGetArray/VecRestoreArray to assign the values. VecAssemblyBegin()/VecAssemblyEnd() is never used. would this still work for a parallel version?</span></li></ol></div></div></blockquote><div class=""><br class=""></div> Yes, you can use Get/Restore but the input vector x will need to be, as noted above, scattered into a haloed version to get all the entries you will need to do the local part of the product.</div><div class=""><br class=""></div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none;"><div class="">Thanks,</div><div class="">Feng<br class=""></div></div><div class="" style="font-family: Helvetica; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none;"><br class=""><hr tabindex="-1" class="" style="display: inline-block; width: 1200.5px;"><div id="x_divRplyFwdMsg" dir="ltr" class=""><font class="" face="Calibri, sans-serif" style="font-size: 11pt;"><b class="">From:</b><span class="x_Apple-converted-space"> </span>Barry Smith <<a href="mailto:bsmith@petsc.dev" class="">bsmith@petsc.dev</a>><br class=""><b class="">Sent:</b><span class="x_Apple-converted-space"> </span>12 March 2021 23:40<br class=""><b class="">To:</b><span class="x_Apple-converted-space"> </span>feng wang <<a href="mailto:snailsoar@hotmail.com" class="">snailsoar@hotmail.com</a>><br class=""><b class="">Cc:</b><span class="x_Apple-converted-space"> </span><a href="mailto:petsc-users@mcs.anl.gov" class="">petsc-users@mcs.anl.gov</a><span class="x_Apple-converted-space"> </span><<a href="mailto:petsc-users@mcs.anl.gov" class="">petsc-users@mcs.anl.gov</a>><br class=""><b class="">Subject:</b><span class="x_Apple-converted-space"> </span>Re: [petsc-users] Questions on matrix-free GMRES implementation</font><div class=""> </div></div><div class="" style="word-wrap: break-word; line-break: after-white-space;"><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Mar 12, 2021, at 9:37 AM, feng wang <<a href="mailto:snailsoar@hotmail.com" class="">snailsoar@hotmail.com</a>> wrote:</div><br class="x_x_Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Hi Matt,</div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Thanks for your prompt response.<span class="x_Apple-converted-space"> </span><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Below are my two versions. one is buggy and the 2nd one is working. For the first one, I add the diagonal contribution to the true RHS (variable: rhs) and then set the base point, the callback function is somehow called twice afterwards to compute Jacobian. <span class="x_Apple-converted-space"> </span></div></div></div></blockquote><div class=""><br class=""></div> Do you mean "to compute the Jacobian matrix-vector product?"</div><div class=""><br class=""></div><div class=""> Is it only in the first computation of the product (for the given base vector) that it calls it twice or every matrix-vector product?</div><div class=""><br class=""></div><div class=""> It is possible there is a bug in our logic; run in the debugger with a break point in <font class="" face="Calibri, Helvetica, sans-serif">FormFunction_mf and each time the function is hit in the debugger type where or bt to get the stack frames from the calls. Send this. From this we can all see if it is being called excessively and why.</font></div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">For the 2nd one, I just call the callback function manually to recompute everything, the callback function is then called once as expected to compute the Jacobian. For me, both versions should do the same things. but I don't know why in the first one the callback function is called twice after I set the base point. what could possibly go wrong?<br class=""></div></div></div></blockquote><div class=""><br class=""></div> The logic of how it is suppose to work is shown below.<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Thanks,</div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Feng<br class=""></div><div class=""><div id="x_x_appendonsend" class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><b class="">//This does not work</b><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"> fld->cnsv( iqs,iqe, q, aux, csv );<div class=""> //add contribution of time-stepping</div><div class=""> for(iv=0; iv<nv; iv++)</div><div class=""> {</div><div class=""> for(iq=0; iq<nq; iq++)</div><div class=""> {</div><div class=""> //use conservative variables here</div><div class=""> rhs[iv][iq] = -rhs[iv][iq] + csv[iv][iq]*lhsa[nlhs-1][iq]/cfl;</div><div class=""> }</div><div class=""> }</div><div class=""> ierr = petsc_setcsv(petsc_csv); CHKERRQ(ierr);</div><div class=""> ierr = petsc_setrhs(petsc_baserhs); CHKERRQ(ierr);</div><div class=""> ierr = MatMFFDSetBase(petsc_A_mf, petsc_csv, petsc_baserhs); CHKERRQ(ierr);</div></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><b class="">//This works</b><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"> fld->cnsv( iqs,iqe, q, aux, csv );<div class=""> ierr = petsc_setcsv(petsc_csv); CHKERRQ(ierr);</div><div class=""> ierr = FormFunction_mf(this, petsc_csv, petsc_baserhs); //this is my callback function, now call it manually<br class=""></div><div class=""> ierr = MatMFFDSetBase(petsc_A_mf, petsc_csv, petsc_baserhs); CHKERRQ(ierr);</div><div class=""><br class=""></div><br class=""></div></div></div></div></blockquote><div class=""> Since you provide <span class="" style="font-family: Calibri, Helvetica, sans-serif;">petsc_baserhs MatMFFD assumes (naturally) that you will keep the correct values in it. Hence for each new base value YOU need to compute the new values in </span><span class="" style="font-family: Calibri, Helvetica, sans-serif;">petsc_baserhs. This approach gives you a bit more control over reusing the information in </span><span class="" style="font-family: Calibri, Helvetica, sans-serif;">petsc_baserhs. </span></div><div class=""><span class="" style="font-family: Calibri, Helvetica, sans-serif;"><br class=""></span></div><div class=""><span class="" style="font-family: Calibri, Helvetica, sans-serif;"> If you would prefer that </span><span class="" style="font-family: Calibri, Helvetica, sans-serif;">MatMFFD recomputes the base values, as needed, then you call </span><span class="" style="font-family: Calibri, Helvetica, sans-serif;">FormFunction_mf(this, petsc_csv, NULL); and PETSc will allocate a vector and fill it up as needed by calling your </span><span class="" style="font-family: Calibri, Helvetica, sans-serif;">FormFunction_mf() But you need to call MatAssemblyBegin/End each time you the base input vector </span><span class="" style="font-family: Calibri, Helvetica, sans-serif;">this, petsc_csv values change. For </span><font class="" face="Calibri, Helvetica, sans-serif">example</font></div><div class=""><font class="" face="Calibri, Helvetica, sans-serif"><br class=""></font></div><div class=""><font class="" face="Calibri, Helvetica, sans-serif"> MatAssemblyBegin(</font><span class="" style="font-family: Calibri, Helvetica, sans-serif;">petsc_A_mf,...)</span></div><div class=""><span class="" style="font-family: Calibri, Helvetica, sans-serif;"> </span><font class="" face="Calibri, Helvetica, sans-serif">MatAssemblyEnd(</font><span class="" style="font-family: Calibri, Helvetica, sans-serif;">petsc_A_mf,...)</span></div><div class=""><span class="" style="font-family: Calibri, Helvetica, sans-serif;"> KSPSolve()</span></div><div class=""><span class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></span></div><div class=""><span class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></span></div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><hr tabindex="-1" class="" style="display: inline-block; width: 1190.6875px;"><div id="x_x_divRplyFwdMsg" dir="ltr" class=""><font class="" face="Calibri, sans-serif" style="font-size: 11pt;"><b class="">From:</b><span class="x_Apple-converted-space"> </span>Matthew Knepley <<a href="mailto:knepley@gmail.com" class="">knepley@gmail.com</a>><br class=""><b class="">Sent:</b><span class="x_Apple-converted-space"> </span>12 March 2021 15:08<br class=""><b class="">To:</b><span class="x_Apple-converted-space"> </span>feng wang <<a href="mailto:snailsoar@hotmail.com" class="">snailsoar@hotmail.com</a>><br class=""><b class="">Cc:</b><span class="x_Apple-converted-space"> </span>Barry Smith <<a href="mailto:bsmith@petsc.dev" class="">bsmith@petsc.dev</a>>;<span class="x_Apple-converted-space"> </span><a href="mailto:petsc-users@mcs.anl.gov" class="">petsc-users@mcs.anl.gov</a><span class="x_Apple-converted-space"> </span><<a href="mailto:petsc-users@mcs.anl.gov" class="">petsc-users@mcs.anl.gov</a>><br class=""><b class="">Subject:</b><span class="x_Apple-converted-space"> </span>Re: [petsc-users] Questions on matrix-free GMRES implementation</font><div class=""> </div></div><div class=""><div dir="ltr" class=""><div dir="ltr" class="">On Fri, Mar 12, 2021 at 9:55 AM feng wang <<a href="mailto:snailsoar@hotmail.com" class="">snailsoar@hotmail.com</a>> wrote:<br class=""></div><div class="x_x_x_gmail_quote"><blockquote class="x_x_x_gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Hi Mat,</div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Thanks for your reply. I will try the parallel implementation.</div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">I've got a serial matrix-free GMRES working, but I would like to know why my initial version of matrix-free implementation does not work and there is still something I don't understand. I did some debugging and find that the callback function to compute the RHS for the matrix-free matrix is called twice by Petsc when it computes the finite difference Jacobian, but it should only be called once. I don't know why, could you please give some advice?</div></div></blockquote><div class=""><br class=""></div><div class="">F is called once to calculate the base point and once to get the perturbation. The base point is not recalculated, so if you do many iterates, it is amortized.</div><div class=""><br class=""></div><div class=""> Thanks,</div><div class=""><br class=""></div><div class=""> Matt</div><div class=""> </div><blockquote class="x_x_x_gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Thanks,</div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Feng<br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class=""><div id="x_x_x_gmail-m_-6641396561494424030appendonsend" class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><hr class="" style="display: inline-block; width: 1173.125px;"><div id="x_x_x_gmail-m_-6641396561494424030divRplyFwdMsg" dir="ltr" class=""><font class="" face="Calibri, sans-serif" style="font-size: 11pt;"><b class="">From:</b><span class="x_Apple-converted-space"> </span>Matthew Knepley <<a href="mailto:knepley@gmail.com" target="_blank" class="">knepley@gmail.com</a>><br class=""><b class="">Sent:</b><span class="x_Apple-converted-space"> </span>12 March 2021 12:05<br class=""><b class="">To:</b><span class="x_Apple-converted-space"> </span>feng wang <<a href="mailto:snailsoar@hotmail.com" target="_blank" class="">snailsoar@hotmail.com</a>><br class=""><b class="">Cc:</b><span class="x_Apple-converted-space"> </span>Barry Smith <<a href="mailto:bsmith@petsc.dev" target="_blank" class="">bsmith@petsc.dev</a>>;<span class="x_Apple-converted-space"> </span><a href="mailto:petsc-users@mcs.anl.gov" target="_blank" class="">petsc-users@mcs.anl.gov</a><span class="x_Apple-converted-space"> </span><<a href="mailto:petsc-users@mcs.anl.gov" target="_blank" class="">petsc-users@mcs.anl.gov</a>><br class=""><b class="">Subject:</b><span class="x_Apple-converted-space"> </span>Re: [petsc-users] Questions on matrix-free GMRES implementation</font><div class=""> </div></div><div class=""><div dir="ltr" class=""><div dir="ltr" class="">On Fri, Mar 12, 2021 at 6:02 AM feng wang <<a href="mailto:snailsoar@hotmail.com" target="_blank" class="">snailsoar@hotmail.com</a>> wrote:<br class=""></div><div class=""><blockquote class="" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Hi Barry,</div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Thanks for your advice.</div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">You are right on this. somehow there is some inconsistency when I compute the right hand side (true RHS + time-stepping contribution to the diagonal matrix) to compute the finite difference Jacobian. If I just use the call back function to recompute my RHS before I call<span class="x_Apple-converted-space"> </span><b class="">MatMFFDSetBase</b>, then it works like a charm. But now I end up with computing my RHS three times. 1st time is to compute the true RHS, the rest two is for computing finite difference Jacobian.<span class="x_Apple-converted-space"> </span><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">In my previous buggy version, I only compute RHS twice. If possible, could you elaborate on your comments "<font class="" face="Calibri, Helvetica, sans-serif">Also be careful about </font><span class="" style="font-family: Calibri, Helvetica, sans-serif;"> </span><span class="" style="font-family: Calibri, Helvetica, sans-serif;">petsc_baserhs</span>", so I may possibly understand what was going on with my buggy version.</div></div></blockquote><div class=""><br class=""></div><div class="">Our FD implementation is simple. It approximates the action of the Jacobian as</div><div class=""><br class=""></div><div class=""> J(b) v = (F(b + h v) - F(b)) / h ||v||</div><div class=""><br class=""></div><div class="">where h is some small parameter and b is the base vector, namely the one that you are linearizing around. In a Newton step, b is the previous solution</div><div class="">and v is the proposed solution update.</div><div class=""> </div><blockquote class="" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Besides, for a parallel implementation, my code already has its own partition method, is it possible to allow petsc read in a user-defined partition? if not what is a better way to do this?</div></div></blockquote><div class=""><br class=""></div><div class="">Sure</div><div class=""><br class=""></div><div class=""> <a href="https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecSetSizes.html" target="_blank" class="">https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecSetSizes.html</a></div><div class=""><br class=""></div><div class=""> Thanks,</div><div class=""><br class=""></div><div class=""> Matt</div><div class=""> </div><blockquote class="" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Many thanks,</div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Feng<br class=""></div><div class=""><div id="x_x_x_gmail-m_-6641396561494424030x_gmail-m_-4210113834389506889appendonsend" class=""></div><div class="" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><hr class="" style="display: inline-block; width: 1155.5625px;"><div id="x_x_x_gmail-m_-6641396561494424030x_gmail-m_-4210113834389506889divRplyFwdMsg" dir="ltr" class=""><font class="" face="Calibri, sans-serif" style="font-size: 11pt;"><b class="">From:</b><span class="x_Apple-converted-space"> </span>Barry Smith <<a href="mailto:bsmith@petsc.dev" target="_blank" class="">bsmith@petsc.dev</a>><br class=""><b class="">Sent:</b><span class="x_Apple-converted-space"> </span>11 March 2021 22:15<br class=""><b class="">To:</b><span class="x_Apple-converted-space"> </span>feng wang <<a href="mailto:snailsoar@hotmail.com" target="_blank" class="">snailsoar@hotmail.com</a>><br class=""><b class="">Cc:</b><span class="x_Apple-converted-space"> </span><a href="mailto:petsc-users@mcs.anl.gov" target="_blank" class="">petsc-users@mcs.anl.gov</a><span class="x_Apple-converted-space"> </span><<a href="mailto:petsc-users@mcs.anl.gov" target="_blank" class="">petsc-users@mcs.anl.gov</a>><br class=""><b class="">Subject:</b><span class="x_Apple-converted-space"> </span>Re: [petsc-users] Questions on matrix-free GMRES implementation</font><div class=""> </div></div><div class=""><div class=""><br class=""></div> Feng,<div class=""><br class=""></div><div class=""> The first thing to check is that for each linear solve that involves a new operator (values in the base vector) the MFFD matrix knows it is using a new operator. </div><div class=""><br class=""></div><div class="">The easiest way is to call <font class="" face="Calibri, Helvetica, sans-serif">MatMFFDSetBase() before each solve that involves a new operator (new values in the base vector). Also be careful about </font><span class="" style="font-family: Calibri, Helvetica, sans-serif;"> </span><span class="" style="font-family: Calibri, Helvetica, sans-serif;">petsc_baserhs, when you change the base vector's values you also need to change the </span><span class="" style="font-family: Calibri, Helvetica, sans-serif;">petsc_baserhs values to the function evaluation at that point.</span></div><div class=""><span class="" style="font-family: Calibri, Helvetica, sans-serif;"><br class=""></span></div><div class=""><span class="" style="font-family: Calibri, Helvetica, sans-serif;">If that is correct I would check with a trivial function evaluator to make sure the infrastructure is all set up correctly. For examples use for the matrix free a 1 4 1 operator applied matrix free. </span></div><div class=""><br class=""></div><div class="">Barry</div><div class=""><br class=""></div><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Mar 11, 2021, at 7:35 AM, feng wang <<a href="mailto:snailsoar@hotmail.com" target="_blank" class="">snailsoar@hotmail.com</a>> wrote:</div><br class=""><div class=""><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Dear All,</div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">I am new to petsc and trying to implement a matrix-free GMRES. I have assembled an approximate Jacobian matrix just for preconditioning. After reading some previous questions on this topic, my approach is:</div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">the matrix-free matrix is created as:</div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"> ierr = MatCreateMFFD(*A_COMM_WORLD, iqe*blocksize, iqe*blocksize, PETSC_DETERMINE, PETSC_DETERMINE, &petsc_A_mf); CHKERRQ(ierr);<div class=""> ierr = MatMFFDSetFunction(petsc_A_mf, FormFunction_mf, this); CHKERRQ(ierr);</div><div class=""></div><div class=""><br class=""></div><div class="">KSP linear operator is set up as:</div><div class=""><br class=""></div><div class=""> ierr = KSPSetOperators(petsc_ksp, petsc_A_mf, petsc_A_pre); CHKERRQ(ierr); //petsc_A_pre is my assembled pre-conditioning matrix<br class=""></div><div class=""><br class=""></div><div class="">Before calling KSPSolve, I do:</div><div class=""><br class=""></div> ierr = MatMFFDSetBase(petsc_A_mf, petsc_csv, petsc_baserhs); CHKERRQ(ierr); //petsc_csv is the flow states, petsc_baserhs is the pre-computed right hand side</div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">The call back function is defined as:</div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"> PetscErrorCode cFdDomain::FormFunction_mf(void *ctx, Vec in_vec, Vec out_vec)<div class=""> {</div><div class=""> PetscErrorCode ierr;</div><div class=""> cFdDomain *user_ctx;</div><div class=""><br class=""></div><div class=""> cout << "FormFunction_mf called\n";</div><div class=""><br class=""></div><div class=""> //in_vec: flow states</div><div class=""> //out_vec: right hand side + diagonal contributions from CFL number</div><div class=""><br class=""></div><div class=""> user_ctx = (cFdDomain*)ctx;</div><div class=""><br class=""></div><div class=""> //get perturbed conservative variables from petsc</div><div class=""> user_ctx->petsc_getcsv(in_vec);</div><div class=""><br class=""></div><div class=""> //get new right side</div><div class=""> user_ctx->petsc_fd_rhs();</div><div class=""><br class=""></div><div class=""> //set new right hand side to the output vector</div><div class=""> user_ctx->petsc_setrhs(out_vec);</div><div class=""><br class=""></div><div class=""> ierr = 0;</div><div class=""> return ierr;</div><div class=""> }</div></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">The linear system I am solving is (J+D)x=RHS. J is the Jacobian matrix. D is a diagonal matrix and it is used to stabilise the solution at the start but reduced gradually when the solution moves on to recover Newton's method. I add D*x to the true right side when non-linear function is computed to work out finite difference Jacobian, so when finite difference is used, it actually computes (J+D)*dx.<span class=""> </span><br class=""></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">The code runs but diverges in the end. If I don't do matrix-free and use my approximate Jacobian matrix, GMRES works. So something is wrong with my matrix-free implementation. Have I missed something in my implementation? Besides, is there a way to check if the finite difference Jacobian matrix is computed correctly in a matrix-free implementation?</div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;"><br class=""></div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Thanks for your help in advance.</div><div class="" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; text-decoration: none; font-family: Calibri, Helvetica, sans-serif; font-size: 12pt;">Feng <span class=""> </span></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class="" clear="all"><div class=""><br class=""></div>--<span class="x_Apple-converted-space"> </span><br class=""><div dir="ltr" class=""><div dir="ltr" class=""><div class=""><div dir="ltr" class=""><div class=""><div dir="ltr" class=""><div class="">What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead.<br class="">-- Norbert Wiener</div><div class=""><br class=""></div><div class=""><a href="http://www.cse.buffalo.edu/~knepley/" target="_blank" class="">https://www.cse.buffalo.edu/~knepley/</a><br class=""></div></div></div></div></div></div></div></div></div></div></div></blockquote></div><br class="" clear="all"><div class=""><br class=""></div>--<span class="x_Apple-converted-space"> </span><br class=""><div dir="ltr" class="x_x_x_gmail_signature"><div dir="ltr" class=""><div class=""><div dir="ltr" class=""><div class=""><div dir="ltr" class=""><div class="">What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead.<br class="">-- Norbert Wiener</div><div class=""><br class=""></div><div class=""><a href="http://www.cse.buffalo.edu/~knepley/" target="_blank" class="">https://www.cse.buffalo.edu/~knepley/</a></div></div></div></div></div></div></div></div></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div><br class=""></body></html>