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