xref: /petsc/src/ksp/ksp/interface/itcreate.c (revision 55e7fe800d976e85ed2b5cd8bfdef564daa37bd9)
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   = PetscStrncpy(str,"KSP: ",sizeof(str));CHKERRQ(ierr);
181       ierr   = PetscStrlcat(str,((PetscObject)ksp)->type_name,sizeof(str));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 generally 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 $                 Note that certain algorithms such as KSPGMRES ALWAYS require the norm calculation,
236 $                 for these methods the norms are still computed, they are just not used in
237 $                 the convergence test.
238 $   KSP_NORM_PRECONDITIONED - the default for left preconditioned solves, uses the l2 norm
239 $                 of the preconditioned residual P^{-1}(b - A x)
240 $   KSP_NORM_UNPRECONDITIONED - uses the l2 norm of the true b - Ax residual.
241 $   KSP_NORM_NATURAL - supported  by KSPCG, KSPCR, KSPCGNE, KSPCGS
242 
243 
244    Options Database Key:
245 .   -ksp_norm_type <none,preconditioned,unpreconditioned,natural>
246 
247    Notes:
248    Not all combinations of preconditioner side (see KSPSetPCSide()) and norm type are supported by all Krylov methods.
249    If only one is set, PETSc tries to automatically change the other to find a compatible pair.  If no such combination
250    is supported, PETSc will generate an error.
251 
252    Developer Notes:
253    Supported combinations of norm and preconditioner side are set using KSPSetSupportedNorm().
254 
255    Level: advanced
256 
257 .keywords: KSP, create, context, norms
258 
259 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPConvergedSkip(), KSPSetCheckNormIteration(), KSPSetPCSide(), KSPGetPCSide(), KSPNormType
260 @*/
261 PetscErrorCode  KSPSetNormType(KSP ksp,KSPNormType normtype)
262 {
263   PetscFunctionBegin;
264   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
265   PetscValidLogicalCollectiveEnum(ksp,normtype,2);
266   ksp->normtype = ksp->normtype_set = normtype;
267   PetscFunctionReturn(0);
268 }
269 
270 /*@
271    KSPSetCheckNormIteration - Sets the first iteration at which the norm of the residual will be
272      computed and used in the convergence test.
273 
274    Logically Collective on KSP
275 
276    Input Parameter:
277 +  ksp - Krylov solver context
278 -  it  - use -1 to check at all iterations
279 
280    Notes:
281    Currently only works with KSPCG, KSPBCGS and KSPIBCGS
282 
283    Use KSPSetNormType(ksp,KSP_NORM_NONE) to never check the norm
284 
285    On steps where the norm is not computed, the previous norm is still in the variable, so if you run with, for example,
286     -ksp_monitor the residual norm will appear to be unchanged for several iterations (though it is not really unchanged).
287    Level: advanced
288 
289 .keywords: KSP, create, context, norms
290 
291 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPConvergedSkip(), KSPSetNormType()
292 @*/
293 PetscErrorCode  KSPSetCheckNormIteration(KSP ksp,PetscInt it)
294 {
295   PetscFunctionBegin;
296   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
297   PetscValidLogicalCollectiveInt(ksp,it,2);
298   ksp->chknorm = it;
299   PetscFunctionReturn(0);
300 }
301 
302 /*@
303    KSPSetLagNorm - Lags the residual norm calculation so that it is computed as part of the MPI_Allreduce() for
304    computing the inner products for the next iteration.  This can reduce communication costs at the expense of doing
305    one additional iteration.
306 
307 
308    Logically Collective on KSP
309 
310    Input Parameter:
311 +  ksp - Krylov solver context
312 -  flg - PETSC_TRUE or PETSC_FALSE
313 
314    Options Database Keys:
315 .  -ksp_lag_norm - lag the calculated residual norm
316 
317    Notes:
318    Currently only works with KSPIBCGS.
319 
320    Use KSPSetNormType(ksp,KSP_NORM_NONE) to never check the norm
321 
322    If you lag the norm and run with, for example, -ksp_monitor, the residual norm reported will be the lagged one.
323    Level: advanced
324 
325 .keywords: KSP, create, context, norms
326 
327 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPConvergedSkip(), KSPSetNormType(), KSPSetCheckNormIteration()
328 @*/
329 PetscErrorCode  KSPSetLagNorm(KSP ksp,PetscBool flg)
330 {
331   PetscFunctionBegin;
332   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
333   PetscValidLogicalCollectiveBool(ksp,flg,2);
334   ksp->lagnorm = flg;
335   PetscFunctionReturn(0);
336 }
337 
338 /*@
339    KSPSetSupportedNorm - Sets a norm and preconditioner side supported by a KSP
340 
341    Logically Collective
342 
343    Input Arguments:
344 +  ksp - Krylov method
345 .  normtype - supported norm type
346 .  pcside - preconditioner side that can be used with this norm
347 -  priority - positive integer preference for this combination; larger values have higher priority
348 
349    Level: developer
350 
351    Notes:
352    This function should be called from the implementation files KSPCreate_XXX() to declare
353    which norms and preconditioner sides are supported. Users should not need to call this
354    function.
355 
356 .seealso: KSPSetNormType(), KSPSetPCSide()
357 @*/
358 PetscErrorCode KSPSetSupportedNorm(KSP ksp,KSPNormType normtype,PCSide pcside,PetscInt priority)
359 {
360 
361   PetscFunctionBegin;
362   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
363   ksp->normsupporttable[normtype][pcside] = priority;
364   PetscFunctionReturn(0);
365 }
366 
367 PetscErrorCode KSPNormSupportTableReset_Private(KSP ksp)
368 {
369   PetscErrorCode ierr;
370 
371   PetscFunctionBegin;
372   ierr = PetscMemzero(ksp->normsupporttable,sizeof(ksp->normsupporttable));CHKERRQ(ierr);
373   ksp->pc_side  = ksp->pc_side_set;
374   ksp->normtype = ksp->normtype_set;
375   PetscFunctionReturn(0);
376 }
377 
378 PetscErrorCode KSPSetUpNorms_Private(KSP ksp,PetscBool errorifnotsupported,KSPNormType *normtype,PCSide *pcside)
379 {
380   PetscInt i,j,best,ibest = 0,jbest = 0;
381 
382   PetscFunctionBegin;
383   best = 0;
384   for (i=0; i<KSP_NORM_MAX; i++) {
385     for (j=0; j<PC_SIDE_MAX; j++) {
386       if ((ksp->normtype == KSP_NORM_DEFAULT || ksp->normtype == i) && (ksp->pc_side == PC_SIDE_DEFAULT || ksp->pc_side == j) && (ksp->normsupporttable[i][j] > best)) {
387         best  = ksp->normsupporttable[i][j];
388         ibest = i;
389         jbest = j;
390       }
391     }
392   }
393   if (best < 1 && errorifnotsupported) {
394     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);
395     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]);
396     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]);
397     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]);
398   }
399   if (normtype) *normtype = (KSPNormType)ibest;
400   if (pcside)   *pcside   = (PCSide)jbest;
401   PetscFunctionReturn(0);
402 }
403 
404 /*@
405    KSPGetNormType - Gets the norm that is used for convergence testing.
406 
407    Not Collective
408 
409    Input Parameter:
410 .  ksp - Krylov solver context
411 
412    Output Parameter:
413 .  normtype - norm that is used for convergence testing
414 
415    Level: advanced
416 
417 .keywords: KSP, create, context, norms
418 
419 .seealso: KSPNormType, KSPSetNormType(), KSPConvergedSkip()
420 @*/
421 PetscErrorCode  KSPGetNormType(KSP ksp, KSPNormType *normtype)
422 {
423   PetscErrorCode ierr;
424 
425   PetscFunctionBegin;
426   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
427   PetscValidPointer(normtype,2);
428   ierr      = KSPSetUpNorms_Private(ksp,PETSC_TRUE,&ksp->normtype,&ksp->pc_side);CHKERRQ(ierr);
429   *normtype = ksp->normtype;
430   PetscFunctionReturn(0);
431 }
432 
433 #if defined(PETSC_HAVE_SAWS)
434 #include <petscviewersaws.h>
435 #endif
436 
437 /*@
438    KSPSetOperators - Sets the matrix associated with the linear system
439    and a (possibly) different one associated with the preconditioner.
440 
441    Collective on KSP and Mat
442 
443    Input Parameters:
444 +  ksp - the KSP context
445 .  Amat - the matrix that defines the linear system
446 -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
447 
448    Notes:
449 
450     If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
451     space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
452 
453     All future calls to KSPSetOperators() must use the same size matrices!
454 
455     Passing a NULL for Amat or Pmat removes the matrix that is currently used.
456 
457     If you wish to replace either Amat or Pmat but leave the other one untouched then
458     first call KSPGetOperators() to get the one you wish to keep, call PetscObjectReference()
459     on it and then pass it back in in your call to KSPSetOperators().
460 
461     Level: beginner
462 
463    Alternative usage: If the operators have NOT been set with KSP/PCSetOperators() then the operators
464       are created in PC and returned to the user. In this case, if both operators
465       mat and pmat are requested, two DIFFERENT operators will be returned. If
466       only one is requested both operators in the PC will be the same (i.e. as
467       if one had called KSP/PCSetOperators() with the same argument for both Mats).
468       The user must set the sizes of the returned matrices and their type etc just
469       as if the user created them with MatCreate(). For example,
470 
471 $         KSP/PCGetOperators(ksp/pc,&mat,NULL); is equivalent to
472 $           set size, type, etc of mat
473 
474 $         MatCreate(comm,&mat);
475 $         KSP/PCSetOperators(ksp/pc,mat,mat);
476 $         PetscObjectDereference((PetscObject)mat);
477 $           set size, type, etc of mat
478 
479      and
480 
481 $         KSP/PCGetOperators(ksp/pc,&mat,&pmat); is equivalent to
482 $           set size, type, etc of mat and pmat
483 
484 $         MatCreate(comm,&mat);
485 $         MatCreate(comm,&pmat);
486 $         KSP/PCSetOperators(ksp/pc,mat,pmat);
487 $         PetscObjectDereference((PetscObject)mat);
488 $         PetscObjectDereference((PetscObject)pmat);
489 $           set size, type, etc of mat and pmat
490 
491     The rational for this support is so that when creating a TS, SNES, or KSP the hierarchy
492     of underlying objects (i.e. SNES, KSP, PC, Mat) and their livespans can be completely
493     managed by the top most level object (i.e. the TS, SNES, or KSP). Another way to look
494     at this is when you create a SNES you do not NEED to create a KSP and attach it to
495     the SNES object (the SNES object manages it for you). Similarly when you create a KSP
496     you do not need to attach a PC to it (the KSP object manages the PC object for you).
497     Thus, why should YOU have to create the Mat and attach it to the SNES/KSP/PC, when
498     it can be created for you?
499 
500 .keywords: KSP, set, operators, matrix, preconditioner, linear system
501 
502 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPGetOperators(), KSPSetComputeOperators(), KSPSetComputeInitialGuess(), KSPSetComputeRHS()
503 @*/
504 PetscErrorCode  KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat)
505 {
506   PetscErrorCode ierr;
507 
508   PetscFunctionBegin;
509   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
510   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
511   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
512   if (Amat) PetscCheckSameComm(ksp,1,Amat,2);
513   if (Pmat) PetscCheckSameComm(ksp,1,Pmat,3);
514   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
515   ierr = PCSetOperators(ksp->pc,Amat,Pmat);CHKERRQ(ierr);
516   if (ksp->setupstage == KSP_SETUP_NEWRHS) ksp->setupstage = KSP_SETUP_NEWMATRIX;  /* so that next solve call will call PCSetUp() on new matrix */
517   PetscFunctionReturn(0);
518 }
519 
520 /*@
521    KSPGetOperators - Gets the matrix associated with the linear system
522    and a (possibly) different one associated with the preconditioner.
523 
524    Collective on KSP and Mat
525 
526    Input Parameter:
527 .  ksp - the KSP context
528 
529    Output Parameters:
530 +  Amat - the matrix that defines the linear system
531 -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
532 
533     Level: intermediate
534 
535    Notes:
536     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   ksp->setfromoptionscalled = 0;
690 
691   ierr                    = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr);
692   ierr                    = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr);
693   ksp->ops->buildsolution = KSPBuildSolutionDefault;
694   ksp->ops->buildresidual = KSPBuildResidualDefault;
695 
696   ksp->vec_sol    = 0;
697   ksp->vec_rhs    = 0;
698   ksp->pc         = 0;
699   ksp->data       = 0;
700   ksp->nwork      = 0;
701   ksp->work       = 0;
702   ksp->reason     = KSP_CONVERGED_ITERATING;
703   ksp->setupstage = KSP_SETUP_NEW;
704 
705   ierr = KSPNormSupportTableReset_Private(ksp);CHKERRQ(ierr);
706 
707   *inksp = ksp;
708   PetscFunctionReturn(0);
709 }
710 
711 /*@C
712    KSPSetType - Builds KSP for a particular solver.
713 
714    Logically Collective on KSP
715 
716    Input Parameters:
717 +  ksp      - the Krylov space context
718 -  type - a known method
719 
720    Options Database Key:
721 .  -ksp_type  <method> - Sets the method; use -help for a list
722     of available methods (for instance, cg or gmres)
723 
724    Notes:
725    See "petsc/include/petscksp.h" for available methods (for instance,
726    KSPCG or KSPGMRES).
727 
728   Normally, it is best to use the KSPSetFromOptions() command and
729   then set the KSP type from the options database rather than by using
730   this routine.  Using the options database provides the user with
731   maximum flexibility in evaluating the many different Krylov methods.
732   The KSPSetType() routine is provided for those situations where it
733   is necessary to set the iterative solver independently of the command
734   line or options database.  This might be the case, for example, when
735   the choice of iterative solver changes during the execution of the
736   program, and the user's application is taking responsibility for
737   choosing the appropriate method.  In other words, this routine is
738   not for beginners.
739 
740   Level: intermediate
741 
742   Developer Note: KSPRegister() is used to add Krylov types to KSPList from which they
743   are accessed by KSPSetType().
744 
745 .keywords: KSP, set, method
746 
747 .seealso: PCSetType(), KSPType, KSPRegister(), KSPCreate()
748 
749 @*/
750 PetscErrorCode  KSPSetType(KSP ksp, KSPType type)
751 {
752   PetscErrorCode ierr,(*r)(KSP);
753   PetscBool      match;
754   void           *ctx;
755 
756   PetscFunctionBegin;
757   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
758   PetscValidCharPointer(type,2);
759 
760   ierr = PetscObjectTypeCompare((PetscObject)ksp,type,&match);CHKERRQ(ierr);
761   if (match) PetscFunctionReturn(0);
762 
763   ierr =  PetscFunctionListFind(KSPList,type,&r);CHKERRQ(ierr);
764   if (!r) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested KSP type %s",type);
765   /* Destroy the previous private KSP context */
766   if (ksp->ops->destroy) {
767     ierr              = (*ksp->ops->destroy)(ksp);CHKERRQ(ierr);
768     ksp->ops->destroy = NULL;
769   }
770   /* Reinitialize function pointers in KSPOps structure */
771   ierr                    = PetscMemzero(ksp->ops,sizeof(struct _KSPOps));CHKERRQ(ierr);
772   ierr                    = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr);
773   ierr                    = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr);
774   ksp->ops->buildsolution = KSPBuildSolutionDefault;
775   ksp->ops->buildresidual = KSPBuildResidualDefault;
776   ierr                    = KSPNormSupportTableReset_Private(ksp);CHKERRQ(ierr);
777   /* Call the KSPCreate_XXX routine for this particular Krylov solver */
778   ksp->setupstage = KSP_SETUP_NEW;
779   ierr            = PetscObjectChangeTypeName((PetscObject)ksp,type);CHKERRQ(ierr);
780   ierr            = (*r)(ksp);CHKERRQ(ierr);
781   PetscFunctionReturn(0);
782 }
783 
784 /*@C
785    KSPGetType - Gets the KSP type as a string from the KSP object.
786 
787    Not Collective
788 
789    Input Parameter:
790 .  ksp - Krylov context
791 
792    Output Parameter:
793 .  name - name of KSP method
794 
795    Level: intermediate
796 
797 .keywords: KSP, get, method, name
798 
799 .seealso: KSPSetType()
800 @*/
801 PetscErrorCode  KSPGetType(KSP ksp,KSPType *type)
802 {
803   PetscFunctionBegin;
804   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
805   PetscValidPointer(type,2);
806   *type = ((PetscObject)ksp)->type_name;
807   PetscFunctionReturn(0);
808 }
809 
810 /*@C
811   KSPRegister -  Adds a method to the Krylov subspace solver package.
812 
813    Not Collective
814 
815    Input Parameters:
816 +  name_solver - name of a new user-defined solver
817 -  routine_create - routine to create method context
818 
819    Notes:
820    KSPRegister() may be called multiple times to add several user-defined solvers.
821 
822    Sample usage:
823 .vb
824    KSPRegister("my_solver",MySolverCreate);
825 .ve
826 
827    Then, your solver can be chosen with the procedural interface via
828 $     KSPSetType(ksp,"my_solver")
829    or at runtime via the option
830 $     -ksp_type my_solver
831 
832    Level: advanced
833 
834 .keywords: KSP, register
835 
836 .seealso: KSPRegisterAll(), KSPRegisterDestroy()
837 
838 @*/
839 PetscErrorCode  KSPRegister(const char sname[],PetscErrorCode (*function)(KSP))
840 {
841   PetscErrorCode ierr;
842 
843   PetscFunctionBegin;
844   ierr = KSPInitializePackage();CHKERRQ(ierr);
845   ierr = PetscFunctionListAdd(&KSPList,sname,function);CHKERRQ(ierr);
846   PetscFunctionReturn(0);
847 }
848