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