xref: /petsc/src/ksp/ksp/interface/itcreate.c (revision aab5bcd8e18f0808071e10849b7b64c13bdb175c)
1 
2 /*
3      The basic KSP routines, Create, View etc. are here.
4 */
5 #include <petsc/private/kspimpl.h>      /*I "petscksp.h" I*/
6 
7 /* Logging support */
8 PetscClassId  KSP_CLASSID;
9 PetscClassId  DMKSP_CLASSID;
10 PetscClassId  KSPGUESS_CLASSID;
11 PetscLogEvent KSP_GMRESOrthogonalization, KSP_SetUp, KSP_Solve;
12 
13 /*
14    Contains the list of registered KSP routines
15 */
16 PetscFunctionList KSPList              = 0;
17 PetscBool         KSPRegisterAllCalled = PETSC_FALSE;
18 
19 /*@C
20   KSPLoad - Loads a KSP that has been stored in binary  with KSPView().
21 
22   Collective on PetscViewer
23 
24   Input Parameters:
25 + newdm - the newly loaded KSP, this needs to have been created with KSPCreate() or
26            some related function before a call to KSPLoad().
27 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
28 
29    Level: intermediate
30 
31   Notes:
32    The type is determined by the data in the file, any type set into the KSP before this call is ignored.
33 
34   Notes for advanced users:
35   Most users should not need to know the details of the binary storage
36   format, since KSPLoad() and KSPView() completely hide these details.
37   But for anyone who's interested, the standard binary matrix storage
38   format is
39 .vb
40      has not yet been determined
41 .ve
42 
43 .seealso: PetscViewerBinaryOpen(), KSPView(), MatLoad(), VecLoad()
44 @*/
45 PetscErrorCode  KSPLoad(KSP newdm, PetscViewer viewer)
46 {
47   PetscErrorCode ierr;
48   PetscBool      isbinary;
49   PetscInt       classid;
50   char           type[256];
51   PC             pc;
52 
53   PetscFunctionBegin;
54   PetscValidHeaderSpecific(newdm,KSP_CLASSID,1);
55   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
56   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
57   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
58 
59   ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
60   if (classid != KSP_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not KSP next in file");
61   ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
62   ierr = KSPSetType(newdm, type);CHKERRQ(ierr);
63   if (newdm->ops->load) {
64     ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
65   }
66   ierr = KSPGetPC(newdm,&pc);CHKERRQ(ierr);
67   ierr = PCLoad(pc,viewer);CHKERRQ(ierr);
68   PetscFunctionReturn(0);
69 }
70 
71 #include <petscdraw.h>
72 #if defined(PETSC_HAVE_SAWS)
73 #include <petscviewersaws.h>
74 #endif
75 /*@C
76    KSPView - Prints the KSP data structure.
77 
78    Collective on KSP
79 
80    Input Parameters:
81 +  ksp - the Krylov space context
82 -  viewer - visualization context
83 
84    Options Database Keys:
85 .  -ksp_view - print the ksp data structure at the end of a KSPSolve call
86 
87    Note:
88    The available visualization contexts include
89 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
90 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
91          output where only the first processor opens
92          the file.  All other processors send their
93          data to the first processor to print.
94 
95    The user can open an alternative visualization context with
96    PetscViewerASCIIOpen() - output to a specified file.
97 
98    Level: beginner
99 
100 .keywords: KSP, view
101 
102 .seealso: PCView(), PetscViewerASCIIOpen()
103 @*/
104 PetscErrorCode  KSPView(KSP ksp,PetscViewer viewer)
105 {
106   PetscErrorCode ierr;
107   PetscBool      iascii,isbinary,isdraw;
108 #if defined(PETSC_HAVE_SAWS)
109   PetscBool      issaws;
110 #endif
111 
112   PetscFunctionBegin;
113   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
114   if (!viewer) {
115     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);CHKERRQ(ierr);
116   }
117   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
118   PetscCheckSameComm(ksp,1,viewer,2);
119 
120   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
121   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
122   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
123 #if defined(PETSC_HAVE_SAWS)
124   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
125 #endif
126   if (iascii) {
127     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ksp,viewer);CHKERRQ(ierr);
128     if (ksp->ops->view) {
129       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
130       ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
131       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
132     }
133     if (ksp->guess_zero) {
134       ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, initial guess is zero\n",ksp->max_it);CHKERRQ(ierr);
135     } else {
136       ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, nonzero initial guess\n", ksp->max_it);CHKERRQ(ierr);
137     }
138     if (ksp->guess_knoll) {ierr = PetscViewerASCIIPrintf(viewer,"  using preconditioner applied to right hand side for initial guess\n");CHKERRQ(ierr);}
139     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances:  relative=%g, absolute=%g, divergence=%g\n",(double)ksp->rtol,(double)ksp->abstol,(double)ksp->divtol);CHKERRQ(ierr);
140     if (ksp->pc_side == PC_RIGHT) {
141       ierr = PetscViewerASCIIPrintf(viewer,"  right preconditioning\n");CHKERRQ(ierr);
142     } else if (ksp->pc_side == PC_SYMMETRIC) {
143       ierr = PetscViewerASCIIPrintf(viewer,"  symmetric preconditioning\n");CHKERRQ(ierr);
144     } else {
145       ierr = PetscViewerASCIIPrintf(viewer,"  left preconditioning\n");CHKERRQ(ierr);
146     }
147     if (ksp->guess) {
148       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
149       ierr = KSPGuessView(ksp->guess,viewer);CHKERRQ(ierr);
150       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
151     }
152     if (ksp->dscale) {ierr = PetscViewerASCIIPrintf(viewer,"  diagonally scaled system\n");CHKERRQ(ierr);}
153     ierr = PetscViewerASCIIPrintf(viewer,"  using %s norm type for convergence test\n",KSPNormTypes[ksp->normtype]);CHKERRQ(ierr);
154   } else if (isbinary) {
155     PetscInt    classid = KSP_FILE_CLASSID;
156     MPI_Comm    comm;
157     PetscMPIInt rank;
158     char        type[256];
159 
160     ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr);
161     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
162     if (!rank) {
163       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
164       ierr = PetscStrncpy(type,((PetscObject)ksp)->type_name,256);CHKERRQ(ierr);
165       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
166     }
167     if (ksp->ops->view) {
168       ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
169     }
170   } else if (isdraw) {
171     PetscDraw draw;
172     char      str[36];
173     PetscReal x,y,bottom,h;
174     PetscBool flg;
175 
176     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
177     ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
178     ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);CHKERRQ(ierr);
179     if (!flg) {
180       ierr   = PetscStrcpy(str,"KSP: ");CHKERRQ(ierr);
181       ierr   = PetscStrcat(str,((PetscObject)ksp)->type_name);CHKERRQ(ierr);
182       ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_RED,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
183       bottom = y - h;
184     } else {
185       bottom = y;
186     }
187     ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
188 #if defined(PETSC_HAVE_SAWS)
189   } else if (issaws) {
190     PetscMPIInt rank;
191     const char  *name;
192 
193     ierr = PetscObjectGetName((PetscObject)ksp,&name);CHKERRQ(ierr);
194     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
195     if (!((PetscObject)ksp)->amsmem && !rank) {
196       char       dir[1024];
197 
198       ierr = PetscObjectViewSAWs((PetscObject)ksp,viewer);CHKERRQ(ierr);
199       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr);
200       PetscStackCallSAWs(SAWs_Register,(dir,&ksp->its,1,SAWs_READ,SAWs_INT));
201       if (!ksp->res_hist) {
202         ierr = KSPSetResidualHistory(ksp,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr);
203       }
204       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/res_hist",name);CHKERRQ(ierr);
205       PetscStackCallSAWs(SAWs_Register,(dir,ksp->res_hist,10,SAWs_READ,SAWs_DOUBLE));
206     }
207 #endif
208   } else if (ksp->ops->view) {
209     ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
210   }
211   if (!ksp->skippcsetfromoptions) {
212     if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
213     ierr = PCView(ksp->pc,viewer);CHKERRQ(ierr);
214   }
215   if (isdraw) {
216     PetscDraw draw;
217     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
218     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
219   }
220   PetscFunctionReturn(0);
221 }
222 
223 
224 /*@
225    KSPSetNormType - Sets the norm that is used for convergence testing.
226 
227    Logically Collective on KSP
228 
229    Input Parameter:
230 +  ksp - Krylov solver context
231 -  normtype - one of
232 $   KSP_NORM_NONE - skips computing the norm, this should only be used if you are using
233 $                 the Krylov method as a smoother with a fixed small number of iterations.
234 $                 Implicitly sets KSPConvergedSkip as KSP convergence test.
235 $   KSP_NORM_PRECONDITIONED - the default for left preconditioned solves, uses the l2 norm
236 $                 of the preconditioned residual P^{-1}(b - A x)
237 $   KSP_NORM_UNPRECONDITIONED - uses the l2 norm of the true b - Ax residual.
238 $   KSP_NORM_NATURAL - supported  by KSPCG, KSPCR, KSPCGNE, KSPCGS
239 
240 
241    Options Database Key:
242 .   -ksp_norm_type <none,preconditioned,unpreconditioned,natural>
243 
244    Notes:
245    Not all combinations of preconditioner side (see KSPSetPCSide()) and norm type are supported by all Krylov methods.
246    If only one is set, PETSc tries to automatically change the other to find a compatible pair.  If no such combination
247    is supported, PETSc will generate an error.
248 
249    Developer Notes:
250    Supported combinations of norm and preconditioner side are set using KSPSetSupportedNorm().
251 
252    Level: advanced
253 
254 .keywords: KSP, create, context, norms
255 
256 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPConvergedSkip(), KSPSetCheckNormIteration(), KSPSetPCSide(), KSPGetPCSide(), KSPNormType
257 @*/
258 PetscErrorCode  KSPSetNormType(KSP ksp,KSPNormType normtype)
259 {
260   PetscFunctionBegin;
261   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
262   PetscValidLogicalCollectiveEnum(ksp,normtype,2);
263   ksp->normtype = ksp->normtype_set = normtype;
264   PetscFunctionReturn(0);
265 }
266 
267 /*@
268    KSPSetCheckNormIteration - Sets the first iteration at which the norm of the residual will be
269      computed and used in the convergence test.
270 
271    Logically Collective on KSP
272 
273    Input Parameter:
274 +  ksp - Krylov solver context
275 -  it  - use -1 to check at all iterations
276 
277    Notes:
278    Currently only works with KSPCG, KSPBCGS and KSPIBCGS
279 
280    Use KSPSetNormType(ksp,KSP_NORM_NONE) to never check the norm
281 
282    On steps where the norm is not computed, the previous norm is still in the variable, so if you run with, for example,
283     -ksp_monitor the residual norm will appear to be unchanged for several iterations (though it is not really unchanged).
284    Level: advanced
285 
286 .keywords: KSP, create, context, norms
287 
288 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPConvergedSkip(), KSPSetNormType()
289 @*/
290 PetscErrorCode  KSPSetCheckNormIteration(KSP ksp,PetscInt it)
291 {
292   PetscFunctionBegin;
293   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
294   PetscValidLogicalCollectiveInt(ksp,it,2);
295   ksp->chknorm = it;
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    KSPSetLagNorm - Lags the residual norm calculation so that it is computed as part of the MPI_Allreduce() for
301    computing the inner products for the next iteration.  This can reduce communication costs at the expense of doing
302    one additional iteration.
303 
304 
305    Logically Collective on KSP
306 
307    Input Parameter:
308 +  ksp - Krylov solver context
309 -  flg - PETSC_TRUE or PETSC_FALSE
310 
311    Options Database Keys:
312 .  -ksp_lag_norm - lag the calculated residual norm
313 
314    Notes:
315    Currently only works with KSPIBCGS.
316 
317    Use KSPSetNormType(ksp,KSP_NORM_NONE) to never check the norm
318 
319    If you lag the norm and run with, for example, -ksp_monitor, the residual norm reported will be the lagged one.
320    Level: advanced
321 
322 .keywords: KSP, create, context, norms
323 
324 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPConvergedSkip(), KSPSetNormType(), KSPSetCheckNormIteration()
325 @*/
326 PetscErrorCode  KSPSetLagNorm(KSP ksp,PetscBool flg)
327 {
328   PetscFunctionBegin;
329   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
330   PetscValidLogicalCollectiveBool(ksp,flg,2);
331   ksp->lagnorm = flg;
332   PetscFunctionReturn(0);
333 }
334 
335 /*@
336    KSPSetSupportedNorm - Sets a norm and preconditioner side supported by a KSP
337 
338    Logically Collective
339 
340    Input Arguments:
341 +  ksp - Krylov method
342 .  normtype - supported norm type
343 .  pcside - preconditioner side that can be used with this norm
344 -  preference - integer preference for this combination, larger values have higher priority
345 
346    Level: developer
347 
348    Notes:
349    This function should be called from the implementation files KSPCreate_XXX() to declare
350    which norms and preconditioner sides are supported. Users should not need to call this
351    function.
352 
353    KSP_NORM_NONE is supported by default with all KSP methods and any PC side at priority 1.  If a KSP explicitly does
354    not support KSP_NORM_NONE, it should set this by setting priority=0.  Since defaulting to KSP_NORM_NONE is usually
355    undesirable, more desirable norms should usually have priority 2 or higher.
356 
357 .seealso: KSPSetNormType(), KSPSetPCSide()
358 @*/
359 PetscErrorCode KSPSetSupportedNorm(KSP ksp,KSPNormType normtype,PCSide pcside,PetscInt priority)
360 {
361 
362   PetscFunctionBegin;
363   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
364   ksp->normsupporttable[normtype][pcside] = priority;
365   PetscFunctionReturn(0);
366 }
367 
368 PetscErrorCode KSPNormSupportTableReset_Private(KSP ksp)
369 {
370   PetscErrorCode ierr;
371 
372   PetscFunctionBegin;
373   ierr = PetscMemzero(ksp->normsupporttable,sizeof(ksp->normsupporttable));CHKERRQ(ierr);
374   ksp->pc_side  = ksp->pc_side_set;
375   ksp->normtype = ksp->normtype_set;
376   PetscFunctionReturn(0);
377 }
378 
379 PetscErrorCode KSPSetUpNorms_Private(KSP ksp,PetscBool errorifnotsupported,KSPNormType *normtype,PCSide *pcside)
380 {
381   PetscInt i,j,best,ibest = 0,jbest = 0;
382 
383   PetscFunctionBegin;
384   best = 0;
385   for (i=0; i<KSP_NORM_MAX; i++) {
386     for (j=0; j<PC_SIDE_MAX; j++) {
387       if ((ksp->normtype == KSP_NORM_DEFAULT || ksp->normtype == i) && (ksp->pc_side == PC_SIDE_DEFAULT || ksp->pc_side == j) && (ksp->normsupporttable[i][j] > best)) {
388         best  = ksp->normsupporttable[i][j];
389         ibest = i;
390         jbest = j;
391       }
392     }
393   }
394   if (best < 1 && errorifnotsupported) {
395     if (ksp->normtype == KSP_NORM_DEFAULT && ksp->pc_side == PC_SIDE_DEFAULT) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_PLIB,"The %s KSP implementation did not call KSPSetSupportedNorm()",((PetscObject)ksp)->type_name);
396     if (ksp->normtype == KSP_NORM_DEFAULT) SETERRQ2(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"KSP %s does not support %s",((PetscObject)ksp)->type_name,PCSides[ksp->pc_side]);
397     if (ksp->pc_side == PC_SIDE_DEFAULT) SETERRQ2(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"KSP %s does not support %s",((PetscObject)ksp)->type_name,KSPNormTypes[ksp->normtype]);
398     SETERRQ3(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"KSP %s does not support %s with %s",((PetscObject)ksp)->type_name,KSPNormTypes[ksp->normtype],PCSides[ksp->pc_side]);
399   }
400   if (normtype) *normtype = (KSPNormType)ibest;
401   if (pcside)   *pcside   = (PCSide)jbest;
402   PetscFunctionReturn(0);
403 }
404 
405 /*@
406    KSPGetNormType - Gets the norm that is used for convergence testing.
407 
408    Not Collective
409 
410    Input Parameter:
411 .  ksp - Krylov solver context
412 
413    Output Parameter:
414 .  normtype - norm that is used for convergence testing
415 
416    Level: advanced
417 
418 .keywords: KSP, create, context, norms
419 
420 .seealso: KSPNormType, KSPSetNormType(), KSPConvergedSkip()
421 @*/
422 PetscErrorCode  KSPGetNormType(KSP ksp, KSPNormType *normtype)
423 {
424   PetscErrorCode ierr;
425 
426   PetscFunctionBegin;
427   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
428   PetscValidPointer(normtype,2);
429   ierr      = KSPSetUpNorms_Private(ksp,PETSC_TRUE,&ksp->normtype,&ksp->pc_side);CHKERRQ(ierr);
430   *normtype = ksp->normtype;
431   PetscFunctionReturn(0);
432 }
433 
434 #if defined(PETSC_HAVE_SAWS)
435 #include <petscviewersaws.h>
436 #endif
437 
438 /*@
439    KSPSetOperators - Sets the matrix associated with the linear system
440    and a (possibly) different one associated with the preconditioner.
441 
442    Collective on KSP and Mat
443 
444    Input Parameters:
445 +  ksp - the KSP context
446 .  Amat - the matrix that defines the linear system
447 -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
448 
449    Notes:
450 
451     If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
452     space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
453 
454     All future calls to KSPSetOperators() must use the same size matrices!
455 
456     Passing a NULL for Amat or Pmat removes the matrix that is currently used.
457 
458     If you wish to replace either Amat or Pmat but leave the other one untouched then
459     first call KSPGetOperators() to get the one you wish to keep, call PetscObjectReference()
460     on it and then pass it back in in your call to KSPSetOperators().
461 
462     Level: beginner
463 
464    Alternative usage: If the operators have NOT been set with KSP/PCSetOperators() then the operators
465       are created in PC and returned to the user. In this case, if both operators
466       mat and pmat are requested, two DIFFERENT operators will be returned. If
467       only one is requested both operators in the PC will be the same (i.e. as
468       if one had called KSP/PCSetOperators() with the same argument for both Mats).
469       The user must set the sizes of the returned matrices and their type etc just
470       as if the user created them with MatCreate(). For example,
471 
472 $         KSP/PCGetOperators(ksp/pc,&mat,NULL); is equivalent to
473 $           set size, type, etc of mat
474 
475 $         MatCreate(comm,&mat);
476 $         KSP/PCSetOperators(ksp/pc,mat,mat);
477 $         PetscObjectDereference((PetscObject)mat);
478 $           set size, type, etc of mat
479 
480      and
481 
482 $         KSP/PCGetOperators(ksp/pc,&mat,&pmat); is equivalent to
483 $           set size, type, etc of mat and pmat
484 
485 $         MatCreate(comm,&mat);
486 $         MatCreate(comm,&pmat);
487 $         KSP/PCSetOperators(ksp/pc,mat,pmat);
488 $         PetscObjectDereference((PetscObject)mat);
489 $         PetscObjectDereference((PetscObject)pmat);
490 $           set size, type, etc of mat and pmat
491 
492     The rational for this support is so that when creating a TS, SNES, or KSP the hierarchy
493     of underlying objects (i.e. SNES, KSP, PC, Mat) and their livespans can be completely
494     managed by the top most level object (i.e. the TS, SNES, or KSP). Another way to look
495     at this is when you create a SNES you do not NEED to create a KSP and attach it to
496     the SNES object (the SNES object manages it for you). Similarly when you create a KSP
497     you do not need to attach a PC to it (the KSP object manages the PC object for you).
498     Thus, why should YOU have to create the Mat and attach it to the SNES/KSP/PC, when
499     it can be created for you?
500 
501 .keywords: KSP, set, operators, matrix, preconditioner, linear system
502 
503 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPGetOperators(), KSPSetComputeOperators(), KSPSetComputeInitialGuess(), KSPSetComputeRHS()
504 @*/
505 PetscErrorCode  KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat)
506 {
507   PetscErrorCode ierr;
508 
509   PetscFunctionBegin;
510   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
511   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
512   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
513   if (Amat) PetscCheckSameComm(ksp,1,Amat,2);
514   if (Pmat) PetscCheckSameComm(ksp,1,Pmat,3);
515   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
516   ierr = PCSetOperators(ksp->pc,Amat,Pmat);CHKERRQ(ierr);
517   if (ksp->setupstage == KSP_SETUP_NEWRHS) ksp->setupstage = KSP_SETUP_NEWMATRIX;  /* so that next solve call will call PCSetUp() on new matrix */
518   PetscFunctionReturn(0);
519 }
520 
521 /*@
522    KSPGetOperators - Gets the matrix associated with the linear system
523    and a (possibly) different one associated with the preconditioner.
524 
525    Collective on KSP and Mat
526 
527    Input Parameter:
528 .  ksp - the KSP context
529 
530    Output Parameters:
531 +  Amat - the matrix that defines the linear system
532 -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
533 
534     Level: intermediate
535 
536    Notes: DOES NOT increase the reference counts of the matrix, so you should NOT destroy them.
537 
538 .keywords: KSP, set, get, operators, matrix, preconditioner, linear system
539 
540 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPSetOperators(), KSPGetOperatorsSet()
541 @*/
542 PetscErrorCode  KSPGetOperators(KSP ksp,Mat *Amat,Mat *Pmat)
543 {
544   PetscErrorCode ierr;
545 
546   PetscFunctionBegin;
547   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
548   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
549   ierr = PCGetOperators(ksp->pc,Amat,Pmat);CHKERRQ(ierr);
550   PetscFunctionReturn(0);
551 }
552 
553 /*@C
554    KSPGetOperatorsSet - Determines if the matrix associated with the linear system and
555    possibly a different one associated with the preconditioner have been set in the KSP.
556 
557    Not collective, though the results on all processes should be the same
558 
559    Input Parameter:
560 .  pc - the KSP context
561 
562    Output Parameters:
563 +  mat - the matrix associated with the linear system was set
564 -  pmat - matrix associated with the preconditioner was set, usually the same
565 
566    Level: intermediate
567 
568 .keywords: KSP, get, operators, matrix, linear system
569 
570 .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperators(), PCGetOperatorsSet()
571 @*/
572 PetscErrorCode  KSPGetOperatorsSet(KSP ksp,PetscBool  *mat,PetscBool  *pmat)
573 {
574   PetscErrorCode ierr;
575 
576   PetscFunctionBegin;
577   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
578   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
579   ierr = PCGetOperatorsSet(ksp->pc,mat,pmat);CHKERRQ(ierr);
580   PetscFunctionReturn(0);
581 }
582 
583 /*@C
584    KSPSetPreSolve - Sets a function that is called before every KSPSolve() is started
585 
586    Logically Collective on KSP
587 
588    Input Parameters:
589 +   ksp - the solver object
590 .   presolve - the function to call before the solve
591 -   prectx - any context needed by the function
592 
593    Level: developer
594 
595 .keywords: KSP, create, context
596 
597 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP, KSPSetPostSolve()
598 @*/
599 PetscErrorCode  KSPSetPreSolve(KSP ksp,PetscErrorCode (*presolve)(KSP,Vec,Vec,void*),void *prectx)
600 {
601   PetscFunctionBegin;
602   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
603   ksp->presolve = presolve;
604   ksp->prectx   = prectx;
605   PetscFunctionReturn(0);
606 }
607 
608 /*@C
609    KSPSetPostSolve - Sets a function that is called after every KSPSolve() completes (whether it converges or not)
610 
611    Logically Collective on KSP
612 
613    Input Parameters:
614 +   ksp - the solver object
615 .   postsolve - the function to call after the solve
616 -   postctx - any context needed by the function
617 
618    Level: developer
619 
620 .keywords: KSP, create, context
621 
622 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP, KSPSetPreSolve()
623 @*/
624 PetscErrorCode  KSPSetPostSolve(KSP ksp,PetscErrorCode (*postsolve)(KSP,Vec,Vec,void*),void *postctx)
625 {
626   PetscFunctionBegin;
627   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
628   ksp->postsolve = postsolve;
629   ksp->postctx   = postctx;
630   PetscFunctionReturn(0);
631 }
632 
633 /*@
634    KSPCreate - Creates the default KSP context.
635 
636    Collective on MPI_Comm
637 
638    Input Parameter:
639 .  comm - MPI communicator
640 
641    Output Parameter:
642 .  ksp - location to put the KSP context
643 
644    Notes:
645    The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt
646    orthogonalization.
647 
648    Level: beginner
649 
650 .keywords: KSP, create, context
651 
652 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP
653 @*/
654 PetscErrorCode  KSPCreate(MPI_Comm comm,KSP *inksp)
655 {
656   KSP            ksp;
657   PetscErrorCode ierr;
658   void           *ctx;
659 
660   PetscFunctionBegin;
661   PetscValidPointer(inksp,2);
662   *inksp = 0;
663   ierr = KSPInitializePackage();CHKERRQ(ierr);
664 
665   ierr = PetscHeaderCreate(ksp,KSP_CLASSID,"KSP","Krylov Method","KSP",comm,KSPDestroy,KSPView);CHKERRQ(ierr);
666 
667   ksp->max_it  = 10000;
668   ksp->pc_side = ksp->pc_side_set = PC_SIDE_DEFAULT;
669   ksp->rtol    = 1.e-5;
670 #if defined(PETSC_USE_REAL_SINGLE)
671   ksp->abstol  = 1.e-25;
672 #else
673   ksp->abstol  = 1.e-50;
674 #endif
675   ksp->divtol  = 1.e4;
676 
677   ksp->chknorm        = -1;
678   ksp->normtype       = ksp->normtype_set = KSP_NORM_DEFAULT;
679   ksp->rnorm          = 0.0;
680   ksp->its            = 0;
681   ksp->guess_zero     = PETSC_TRUE;
682   ksp->calc_sings     = PETSC_FALSE;
683   ksp->res_hist       = NULL;
684   ksp->res_hist_alloc = NULL;
685   ksp->res_hist_len   = 0;
686   ksp->res_hist_max   = 0;
687   ksp->res_hist_reset = PETSC_TRUE;
688   ksp->numbermonitors = 0;
689 
690   ierr                    = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr);
691   ierr                    = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr);
692   ksp->ops->buildsolution = KSPBuildSolutionDefault;
693   ksp->ops->buildresidual = KSPBuildResidualDefault;
694 
695   ksp->vec_sol    = 0;
696   ksp->vec_rhs    = 0;
697   ksp->pc         = 0;
698   ksp->data       = 0;
699   ksp->nwork      = 0;
700   ksp->work       = 0;
701   ksp->reason     = KSP_CONVERGED_ITERATING;
702   ksp->setupstage = KSP_SETUP_NEW;
703 
704   ierr = KSPNormSupportTableReset_Private(ksp);CHKERRQ(ierr);
705 
706   *inksp = ksp;
707   PetscFunctionReturn(0);
708 }
709 
710 /*@C
711    KSPSetType - Builds KSP for a particular solver.
712 
713    Logically Collective on KSP
714 
715    Input Parameters:
716 +  ksp      - the Krylov space context
717 -  type - a known method
718 
719    Options Database Key:
720 .  -ksp_type  <method> - Sets the method; use -help for a list
721     of available methods (for instance, cg or gmres)
722 
723    Notes:
724    See "petsc/include/petscksp.h" for available methods (for instance,
725    KSPCG or KSPGMRES).
726 
727   Normally, it is best to use the KSPSetFromOptions() command and
728   then set the KSP type from the options database rather than by using
729   this routine.  Using the options database provides the user with
730   maximum flexibility in evaluating the many different Krylov methods.
731   The KSPSetType() routine is provided for those situations where it
732   is necessary to set the iterative solver independently of the command
733   line or options database.  This might be the case, for example, when
734   the choice of iterative solver changes during the execution of the
735   program, and the user's application is taking responsibility for
736   choosing the appropriate method.  In other words, this routine is
737   not for beginners.
738 
739   Level: intermediate
740 
741   Developer Note: KSPRegister() is used to add Krylov types to KSPList from which they
742   are accessed by KSPSetType().
743 
744 .keywords: KSP, set, method
745 
746 .seealso: PCSetType(), KSPType, KSPRegister(), KSPCreate()
747 
748 @*/
749 PetscErrorCode  KSPSetType(KSP ksp, KSPType type)
750 {
751   PetscErrorCode ierr,(*r)(KSP);
752   PetscBool      match;
753 
754   PetscFunctionBegin;
755   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
756   PetscValidCharPointer(type,2);
757 
758   ierr = PetscObjectTypeCompare((PetscObject)ksp,type,&match);CHKERRQ(ierr);
759   if (match) PetscFunctionReturn(0);
760 
761   ierr =  PetscFunctionListFind(KSPList,type,&r);CHKERRQ(ierr);
762   if (!r) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested KSP type %s",type);
763   /* Destroy the previous private KSP context */
764   if (ksp->ops->destroy) {
765     ierr              = (*ksp->ops->destroy)(ksp);CHKERRQ(ierr);
766     ksp->ops->destroy = NULL;
767   }
768   /* Reinitialize function pointers in KSPOps structure */
769   ierr                    = PetscMemzero(ksp->ops,sizeof(struct _KSPOps));CHKERRQ(ierr);
770   ksp->ops->buildsolution = KSPBuildSolutionDefault;
771   ksp->ops->buildresidual = KSPBuildResidualDefault;
772   ierr                    = KSPNormSupportTableReset_Private(ksp);CHKERRQ(ierr);
773   /* Call the KSPCreate_XXX routine for this particular Krylov solver */
774   ksp->setupstage = KSP_SETUP_NEW;
775   ierr            = PetscObjectChangeTypeName((PetscObject)ksp,type);CHKERRQ(ierr);
776   ierr            = (*r)(ksp);CHKERRQ(ierr);
777   PetscFunctionReturn(0);
778 }
779 
780 /*@C
781    KSPGetType - Gets the KSP type as a string from the KSP object.
782 
783    Not Collective
784 
785    Input Parameter:
786 .  ksp - Krylov context
787 
788    Output Parameter:
789 .  name - name of KSP method
790 
791    Level: intermediate
792 
793 .keywords: KSP, get, method, name
794 
795 .seealso: KSPSetType()
796 @*/
797 PetscErrorCode  KSPGetType(KSP ksp,KSPType *type)
798 {
799   PetscFunctionBegin;
800   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
801   PetscValidPointer(type,2);
802   *type = ((PetscObject)ksp)->type_name;
803   PetscFunctionReturn(0);
804 }
805 
806 /*@C
807   KSPRegister -  Adds a method to the Krylov subspace solver package.
808 
809    Not Collective
810 
811    Input Parameters:
812 +  name_solver - name of a new user-defined solver
813 -  routine_create - routine to create method context
814 
815    Notes:
816    KSPRegister() may be called multiple times to add several user-defined solvers.
817 
818    Sample usage:
819 .vb
820    KSPRegister("my_solver",MySolverCreate);
821 .ve
822 
823    Then, your solver can be chosen with the procedural interface via
824 $     KSPSetType(ksp,"my_solver")
825    or at runtime via the option
826 $     -ksp_type my_solver
827 
828    Level: advanced
829 
830 .keywords: KSP, register
831 
832 .seealso: KSPRegisterAll(), KSPRegisterDestroy()
833 
834 @*/
835 PetscErrorCode  KSPRegister(const char sname[],PetscErrorCode (*function)(KSP))
836 {
837   PetscErrorCode ierr;
838 
839   PetscFunctionBegin;
840   ierr = PetscFunctionListAdd(&KSPList,sname,function);CHKERRQ(ierr);
841   PetscFunctionReturn(0);
842 }
843