However, the argument (at source code) that PCGetOperators should return new Mat's if they were never set never, never convinced me. For me, Mat's are to KSP/PC like Function/Jacobian to SNES. Stuff that the user has to provide. Supose you call PCGetOperators(), and then that call returns a just created Mat, with no sizes and not type, almost empty. What those returned Mat's would be good for?? Just to save users from a MatCreate() call ?? However, creating 'on-demand' inner PC on KSP, or inner KSP on SNES is a completelly different matter, as we can provide meaningful defaults for SNESType/KSPType/PCType.
On Tue, Dec 2, 2008 at 6:53 PM, Barry Smith <bsmith at mcs.anl.gov> wrote: > > Ugg, I have added this check. > > Barry > > This bug came from another "design extension" that was slightly > half-assed. > Originally SNESCreate() always created a KSP and KSPCreate() always created > a PC and one could not change them. But I realized that PCCreate() did not > automatically have a Mat in it, you had to add one with PCSetOperators() > [which really should be called PCSetMats()!] One could also change > it later with another call to PCSetOperators(). By symmetry one should > also be able to replace the KSP in a SNES and the PC in a KSP, hence > SNESSetKSP(), KSPSetPC(). > > But still PC's PCGetOperator() was different > because it returned nothing if PCSetOperators() had not yet been set. So > I had PCGetOperators() automatically return a new Mat if one had never set > it. I then changed SNESGetKSP() and KSPGetPC() to automatically create > one if it did not already exist and SNESSetKSP() had never been called. > This meant I had to add a bunch of checks if (!snes->ksp) to make > sure SNES had a proper KSP when needed. > > An alternative approach was to have SNESCreate() and KSPCreate() > continue to create the KSP and PC and change the PCCreate() to automatically > have a Mat (then PCSetOperators() would just overwrite the one already > there). The reason I didn't take this route is that PC hast TWO slots for > mat and pmat, sometimes they are the same and sometimes they are > different. Should PCCreate() create one and put it in both slots or create > two, one for each slot. I could avoid that decision by having the creation > of those mats until PCGetOperators() when the user decides they want two or > one matrices by passing the same address in for mat and pmat or different > addresses. > > So a bunch of design decisions over time lead to the current undesirable > need for if (!snes->ksp) .... > > > On Dec 2, 2008, at 8:08 AM, Lisandro Dalcin wrote: > >> I've just noticed that now SNES does not create the inner KSP at the >> time SNESCreate() is called. Then I could easily manage to break >> things (basically, if SNESSetFromOptions() is never called) >> >> Does it make sense to add: >> >> if (!snes->ksp) { SNESGetKSP(snes, &snes->ksp);} >> >> near the begining of SNESSetUp() ?? >> >> >> -- >> Lisandro Dalc?n >> --------------- >> Centro Internacional de M?todos Computacionales en Ingenier?a (CIMEC) >> Instituto de Desarrollo Tecnol?gico para la Industria Qu?mica (INTEC) >> Consejo Nacional de Investigaciones Cient?ficas y T?cnicas (CONICET) >> PTLC - G?emes 3450, (3000) Santa Fe, Argentina >> Tel/Fax: +54-(0)342-451.1594 >> > > -- Lisandro Dalc?n --------------- Centro Internacional de M?todos Computacionales en Ingenier?a (CIMEC) Instituto de Desarrollo Tecnol?gico para la Industria Qu?mica (INTEC) Consejo Nacional de Investigaciones Cient?ficas y T?cnicas (CONICET) PTLC - G?emes 3450, (3000) Santa Fe, Argentina Tel/Fax: +54-(0)342-451.1594