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