xref: /petsc/src/ksp/ksp/interface/itcreate.c (revision ce94432eddcd14845bc7e8083b7f8ea723b9bf7d)
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,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,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 #undef __FUNCT__
73 #define __FUNCT__ "KSPView"
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 
108   PetscFunctionBegin;
109   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
110   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ksp));
111   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
112   PetscCheckSameComm(ksp,1,viewer,2);
113 
114   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
115   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
116   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
117   if (iascii) {
118     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ksp,viewer,"KSP Object");CHKERRQ(ierr);
119     if (ksp->ops->view) {
120       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
121       ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
122       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
123     }
124     if (ksp->guess_zero) {
125       ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, initial guess is zero\n",ksp->max_it);CHKERRQ(ierr);
126     } else {
127       ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", ksp->max_it);CHKERRQ(ierr);
128     }
129     if (ksp->guess_knoll) {ierr = PetscViewerASCIIPrintf(viewer,"  using preconditioner applied to right hand side for initial guess\n");CHKERRQ(ierr);}
130     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances:  relative=%G, absolute=%G, divergence=%G\n",ksp->rtol,ksp->abstol,ksp->divtol);CHKERRQ(ierr);
131     if (ksp->pc_side == PC_RIGHT) {
132       ierr = PetscViewerASCIIPrintf(viewer,"  right preconditioning\n");CHKERRQ(ierr);
133     } else if (ksp->pc_side == PC_SYMMETRIC) {
134       ierr = PetscViewerASCIIPrintf(viewer,"  symmetric preconditioning\n");CHKERRQ(ierr);
135     } else {
136       ierr = PetscViewerASCIIPrintf(viewer,"  left preconditioning\n");CHKERRQ(ierr);
137     }
138     if (ksp->guess) {ierr = PetscViewerASCIIPrintf(viewer,"  using Fischers initial guess method %D with size %D\n",ksp->guess->method,ksp->guess->maxl);CHKERRQ(ierr);}
139     if (ksp->dscale) {ierr = PetscViewerASCIIPrintf(viewer,"  diagonally scaled system\n");CHKERRQ(ierr);}
140     if (ksp->nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
141     if (!ksp->guess_zero) {ierr = PetscViewerASCIIPrintf(viewer,"  using nonzero initial guess\n");CHKERRQ(ierr);}
142     ierr = PetscViewerASCIIPrintf(viewer,"  using %s norm type for convergence test\n",KSPNormTypes[ksp->normtype]);CHKERRQ(ierr);
143   } else if (isbinary) {
144     PetscInt    classid = KSP_FILE_CLASSID;
145     MPI_Comm    comm;
146     PetscMPIInt rank;
147     char        type[256];
148 
149     ierr = PetscObjectGetComm((PetscObject)ksp,&comm);CHKERRQ(ierr);
150     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
151     if (!rank) {
152       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
153       ierr = PetscStrncpy(type,((PetscObject)ksp)->type_name,256);CHKERRQ(ierr);
154       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
155     }
156     if (ksp->ops->view) {
157       ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
158     }
159   } else if (isdraw) {
160     PetscDraw draw;
161     char      str[36];
162     PetscReal x,y,bottom,h;
163     PetscBool flg;
164 
165     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
166     ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
167     ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);CHKERRQ(ierr);
168     if (!flg) {
169       ierr   = PetscStrcpy(str,"KSP: ");CHKERRQ(ierr);
170       ierr   = PetscStrcat(str,((PetscObject)ksp)->type_name);CHKERRQ(ierr);
171       ierr   = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_RED,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
172       bottom = y - h;
173     } else {
174       bottom = y;
175     }
176     ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
177   } else if (ksp->ops->view) {
178       ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
179   }
180   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
181   ierr = PCView(ksp->pc,viewer);CHKERRQ(ierr);
182   if (isdraw) {
183     PetscDraw draw;
184     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
185     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
186   }
187   PetscFunctionReturn(0);
188 }
189 
190 
191 #undef __FUNCT__
192 #define __FUNCT__ "KSPSetNormType"
193 /*@
194    KSPSetNormType - Sets the norm that is used for convergence testing.
195 
196    Logically Collective on KSP
197 
198    Input Parameter:
199 +  ksp - Krylov solver context
200 -  normtype - one of
201 $   KSP_NORM_NONE - skips computing the norm, this should only be used if you are using
202 $                 the Krylov method as a smoother with a fixed small number of iterations.
203 $                 Implicitly sets KSPSkipConverged as KSP convergence test.
204 $                 Supported only by CG, Richardson, Bi-CG-stab, CR, and CGS methods.
205 $   KSP_NORM_PRECONDITIONED - the default for left preconditioned solves, uses the l2 norm
206 $                 of the preconditioned residual
207 $   KSP_NORM_UNPRECONDITIONED - uses the l2 norm of the true b - Ax residual, supported only by
208 $                 CG, CHEBYSHEV, and RICHARDSON, automatically true for right (see KSPSetPCSide())
209 $                 preconditioning..
210 $   KSP_NORM_NATURAL - supported  by KSPCG, KSPCR, KSPCGNE, KSPCGS
211 
212 
213    Options Database Key:
214 .   -ksp_norm_type <none,preconditioned,unpreconditioned,natural>
215 
216    Notes:
217    Currently only works with the CG, Richardson, Bi-CG-stab, CR, and CGS methods.
218 
219    Level: advanced
220 
221 .keywords: KSP, create, context, norms
222 
223 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged(), KSPSetCheckNormIteration()
224 @*/
225 PetscErrorCode  KSPSetNormType(KSP ksp,KSPNormType normtype)
226 {
227   PetscErrorCode ierr;
228 
229   PetscFunctionBegin;
230   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
231   PetscValidLogicalCollectiveEnum(ksp,normtype,2);
232   ksp->normtype = normtype;
233   if (normtype == KSP_NORM_NONE) {
234     ierr = KSPSetConvergenceTest(ksp,KSPSkipConverged,0,0);CHKERRQ(ierr);
235     ierr = PetscInfo(ksp,"Warning: setting KSPNormType to skip computing the norm\n\
236  KSP convergence test is implicitly set to KSPSkipConverged\n");CHKERRQ(ierr);
237   }
238   PetscFunctionReturn(0);
239 }
240 
241 #undef __FUNCT__
242 #define __FUNCT__ "KSPSetCheckNormIteration"
243 /*@
244    KSPSetCheckNormIteration - Sets the first iteration at which the norm of the residual will be
245      computed and used in the convergence test.
246 
247    Logically Collective on KSP
248 
249    Input Parameter:
250 +  ksp - Krylov solver context
251 -  it  - use -1 to check at all iterations
252 
253    Notes:
254    Currently only works with KSPCG, KSPBCGS and KSPIBCGS
255 
256    Use KSPSetNormType(ksp,KSP_NORM_NONE) to never check the norm
257 
258    On steps where the norm is not computed, the previous norm is still in the variable, so if you run with, for example,
259     -ksp_monitor the residual norm will appear to be unchanged for several iterations (though it is not really unchanged).
260    Level: advanced
261 
262 .keywords: KSP, create, context, norms
263 
264 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged(), KSPSetNormType()
265 @*/
266 PetscErrorCode  KSPSetCheckNormIteration(KSP ksp,PetscInt it)
267 {
268   PetscFunctionBegin;
269   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
270   PetscValidLogicalCollectiveInt(ksp,it,2);
271   ksp->chknorm = it;
272   PetscFunctionReturn(0);
273 }
274 
275 #undef __FUNCT__
276 #define __FUNCT__ "KSPSetLagNorm"
277 /*@
278    KSPSetLagNorm - Lags the residual norm calculation so that it is computed as part of the MPI_Allreduce() for
279    computing the inner products for the next iteration.  This can reduce communication costs at the expense of doing
280    one additional iteration.
281 
282 
283    Logically Collective on KSP
284 
285    Input Parameter:
286 +  ksp - Krylov solver context
287 -  flg - PETSC_TRUE or PETSC_FALSE
288 
289    Options Database Keys:
290 .  -ksp_lag_norm - lag the calculated residual norm
291 
292    Notes:
293    Currently only works with KSPIBCGS.
294 
295    Use KSPSetNormType(ksp,KSP_NORM_NONE) to never check the norm
296 
297    If you lag the norm and run with, for example, -ksp_monitor, the residual norm reported will be the lagged one.
298    Level: advanced
299 
300 .keywords: KSP, create, context, norms
301 
302 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged(), KSPSetNormType(), KSPSetCheckNormIteration()
303 @*/
304 PetscErrorCode  KSPSetLagNorm(KSP ksp,PetscBool flg)
305 {
306   PetscFunctionBegin;
307   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
308   PetscValidLogicalCollectiveBool(ksp,flg,2);
309   ksp->lagnorm = flg;
310   PetscFunctionReturn(0);
311 }
312 
313 #undef __FUNCT__
314 #define __FUNCT__ "KSPSetSupportedNorm"
315 /*@
316    KSPSetSupportedNorm - Sets a norm and preconditioner side supported by a KSP
317 
318    Logically Collective
319 
320    Input Arguments:
321 +  ksp - Krylov method
322 .  normtype - supported norm type
323 .  pcside - preconditioner side that can be used with this norm
324 -  preference - integer preference for this combination, larger values have higher priority
325 
326    Level: developer
327 
328    Notes:
329    This function should be called from the implementation files KSPCreate_XXX() to declare
330    which norms and preconditioner sides are supported. Users should not need to call this
331    function.
332 
333    KSP_NORM_NONE is supported by default with all KSP methods and any PC side. If a KSP explicitly does not support
334    KSP_NORM_NONE, it should set this by setting priority=0.
335 
336 .seealso: KSPSetNormType(), KSPSetPCSide()
337 @*/
338 PetscErrorCode KSPSetSupportedNorm(KSP ksp,KSPNormType normtype,PCSide pcside,PetscInt priority)
339 {
340 
341   PetscFunctionBegin;
342   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
343   ksp->normsupporttable[normtype][pcside] = priority;
344   PetscFunctionReturn(0);
345 }
346 
347 #undef __FUNCT__
348 #define __FUNCT__ "KSPNormSupportTableReset_Private"
349 PetscErrorCode KSPNormSupportTableReset_Private(KSP ksp)
350 {
351   PetscErrorCode ierr;
352 
353   PetscFunctionBegin;
354   ierr = PetscMemzero(ksp->normsupporttable,sizeof(ksp->normsupporttable));CHKERRQ(ierr);
355   ierr = KSPSetSupportedNorm(ksp,KSP_NORM_NONE,PC_LEFT,1);CHKERRQ(ierr);
356   ierr = KSPSetSupportedNorm(ksp,KSP_NORM_NONE,PC_RIGHT,1);CHKERRQ(ierr);
357   PetscFunctionReturn(0);
358 }
359 
360 #undef __FUNCT__
361 #define __FUNCT__ "KSPSetUpNorms_Private"
362 PetscErrorCode KSPSetUpNorms_Private(KSP ksp,KSPNormType *normtype,PCSide *pcside)
363 {
364   PetscInt i,j,best,ibest = 0,jbest = 0;
365 
366   PetscFunctionBegin;
367   best = 0;
368   for (i=0; i<KSP_NORM_MAX; i++) {
369     for (j=0; j<PC_SIDE_MAX; j++) {
370       if ((ksp->normtype == KSP_NORM_DEFAULT || ksp->normtype == i)
371           && (ksp->pc_side == PC_SIDE_DEFAULT || ksp->pc_side == j)
372           && (ksp->normsupporttable[i][j] > best)) {
373         if (ksp->normtype == KSP_NORM_DEFAULT && i == KSP_NORM_NONE && ksp->normsupporttable[i][j] <= 1) {
374           continue; /* Skip because we don't want to default to no norms unless set by the KSP (preonly). */
375         }
376         best  = ksp->normsupporttable[i][j];
377         ibest = i;
378         jbest = j;
379       }
380     }
381   }
382   if (best < 1) {
383     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);
384     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]);
385     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]);
386     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]);
387   }
388   *normtype = (KSPNormType)ibest;
389   *pcside   = (PCSide)jbest;
390   PetscFunctionReturn(0);
391 }
392 
393 #undef __FUNCT__
394 #define __FUNCT__ "KSPGetNormType"
395 /*@
396    KSPGetNormType - Gets the norm that is used for convergence testing.
397 
398    Not Collective
399 
400    Input Parameter:
401 .  ksp - Krylov solver context
402 
403    Output Parameter:
404 .  normtype - norm that is used for convergence testing
405 
406    Level: advanced
407 
408 .keywords: KSP, create, context, norms
409 
410 .seealso: KSPNormType, KSPSetNormType(), KSPSkipConverged()
411 @*/
412 PetscErrorCode  KSPGetNormType(KSP ksp, KSPNormType *normtype)
413 {
414   PetscErrorCode ierr;
415 
416   PetscFunctionBegin;
417   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
418   PetscValidPointer(normtype,2);
419   ierr      = KSPSetUpNorms_Private(ksp,&ksp->normtype,&ksp->pc_side);CHKERRQ(ierr);
420   *normtype = ksp->normtype;
421   PetscFunctionReturn(0);
422 }
423 
424 #if defined(PETSC_HAVE_AMS)
425 #undef __FUNCT__
426 #define __FUNCT__ "KSPPublish_Petsc"
427 static PetscErrorCode KSPPublish_Petsc(PetscObject obj)
428 {
429   KSP            ksp = (KSP) obj;
430   PetscErrorCode ierr;
431 
432   PetscFunctionBegin;
433   ierr = AMS_Memory_add_field(obj->amem,"its",&ksp->its,1,AMS_INT,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);CHKERRQ(ierr);
434   PetscFunctionReturn(0);
435 }
436 #endif
437 
438 #undef __FUNCT__
439 #define __FUNCT__ "KSPSetOperators"
440 /*@
441    KSPSetOperators - Sets the matrix associated with the linear system
442    and a (possibly) different one associated with the preconditioner.
443 
444    Collective on KSP and Mat
445 
446    Input Parameters:
447 +  ksp - the KSP context
448 .  Amat - the matrix associated with the linear system
449 .  Pmat - the matrix to be used in constructing the preconditioner, usually the
450           same as Amat.
451 -  flag - flag indicating information about the preconditioner matrix structure
452    during successive linear solves.  This flag is ignored the first time a
453    linear system is solved, and thus is irrelevant when solving just one linear
454    system.
455 
456    Notes:
457    The flag can be used to eliminate unnecessary work in the preconditioner
458    during the repeated solution of linear systems of the same size.  The
459    available options are
460 $    SAME_PRECONDITIONER -
461 $      Pmat is identical during successive linear solves.
462 $      This option is intended for folks who are using
463 $      different Amat and Pmat matrices and want to reuse the
464 $      same preconditioner matrix.  For example, this option
465 $      saves work by not recomputing incomplete factorization
466 $      for ILU/ICC preconditioners.
467 $    SAME_NONZERO_PATTERN -
468 $      Pmat has the same nonzero structure during
469 $      successive linear solves.
470 $    DIFFERENT_NONZERO_PATTERN -
471 $      Pmat does not have the same nonzero structure.
472 
473     All future calls to KSPSetOperators() must use the same size matrices!
474 
475     Passing a NULL for Amat or Pmat removes the matrix that is currently used.
476 
477     If you wish to replace either Amat or Pmat but leave the other one untouched then
478     first call KSPGetOperators() to get the one you wish to keep, call PetscObjectReference()
479     on it and then pass it back in in your call to KSPSetOperators().
480 
481     Caution:
482     If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
483     and does not check the structure of the matrix.  If you erroneously
484     claim that the structure is the same when it actually is not, the new
485     preconditioner will not function correctly.  Thus, use this optimization
486     feature carefully!
487 
488     If in doubt about whether your preconditioner matrix has changed
489     structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
490 
491     Level: beginner
492 
493    Alternative usage: If the operators have NOT been set with KSP/PCSetOperators() then the operators
494       are created in PC and returned to the user. In this case, if both operators
495       mat and pmat are requested, two DIFFERENT operators will be returned. If
496       only one is requested both operators in the PC will be the same (i.e. as
497       if one had called KSP/PCSetOperators() with the same argument for both Mats).
498       The user must set the sizes of the returned matrices and their type etc just
499       as if the user created them with MatCreate(). For example,
500 
501 $         KSP/PCGetOperators(ksp/pc,&mat,NULL,NULL); is equivalent to
502 $           set size, type, etc of mat
503 
504 $         MatCreate(comm,&mat);
505 $         KSP/PCSetOperators(ksp/pc,mat,mat,SAME_NONZERO_PATTERN);
506 $         PetscObjectDereference((PetscObject)mat);
507 $           set size, type, etc of mat
508 
509      and
510 
511 $         KSP/PCGetOperators(ksp/pc,&mat,&pmat,NULL); is equivalent to
512 $           set size, type, etc of mat and pmat
513 
514 $         MatCreate(comm,&mat);
515 $         MatCreate(comm,&pmat);
516 $         KSP/PCSetOperators(ksp/pc,mat,pmat,SAME_NONZERO_PATTERN);
517 $         PetscObjectDereference((PetscObject)mat);
518 $         PetscObjectDereference((PetscObject)pmat);
519 $           set size, type, etc of mat and pmat
520 
521     The rational for this support is so that when creating a TS, SNES, or KSP the hierarchy
522     of underlying objects (i.e. SNES, KSP, PC, Mat) and their livespans can be completely
523     managed by the top most level object (i.e. the TS, SNES, or KSP). Another way to look
524     at this is when you create a SNES you do not NEED to create a KSP and attach it to
525     the SNES object (the SNES object manages it for you). Similarly when you create a KSP
526     you do not need to attach a PC to it (the KSP object manages the PC object for you).
527     Thus, why should YOU have to create the Mat and attach it to the SNES/KSP/PC, when
528     it can be created for you?
529 
530 .keywords: KSP, set, operators, matrix, preconditioner, linear system
531 
532 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPGetOperators()
533 @*/
534 PetscErrorCode  KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat,MatStructure flag)
535 {
536   MatNullSpace   nullsp;
537   PetscErrorCode ierr;
538 
539   PetscFunctionBegin;
540   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
541   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
542   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
543   if (Amat) PetscCheckSameComm(ksp,1,Amat,2);
544   if (Pmat) PetscCheckSameComm(ksp,1,Pmat,3);
545   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
546   ierr = PCSetOperators(ksp->pc,Amat,Pmat,flag);CHKERRQ(ierr);
547   if (ksp->setupstage == KSP_SETUP_NEWRHS) ksp->setupstage = KSP_SETUP_NEWMATRIX;  /* so that next solve call will call PCSetUp() on new matrix */
548   if (ksp->guess) {
549     ierr = KSPFischerGuessReset(ksp->guess);CHKERRQ(ierr);
550   }
551   if (Pmat) {
552     ierr = MatGetNullSpace(Pmat, &nullsp);CHKERRQ(ierr);
553     if (nullsp) {
554       ierr = KSPSetNullSpace(ksp, nullsp);CHKERRQ(ierr);
555     }
556   }
557   PetscFunctionReturn(0);
558 }
559 
560 #undef __FUNCT__
561 #define __FUNCT__ "KSPGetOperators"
562 /*@
563    KSPGetOperators - Gets the matrix associated with the linear system
564    and a (possibly) different one associated with the preconditioner.
565 
566    Collective on KSP and Mat
567 
568    Input Parameter:
569 .  ksp - the KSP context
570 
571    Output Parameters:
572 +  Amat - the matrix associated with the linear system
573 .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
574 -  flag - flag indicating information about the preconditioner matrix structure
575    during successive linear solves.  This flag is ignored the first time a
576    linear system is solved, and thus is irrelevant when solving just one linear
577    system.
578 
579     Level: intermediate
580 
581    Notes: DOES NOT increase the reference counts of the matrix, so you should NOT destroy them.
582 
583 .keywords: KSP, set, get, operators, matrix, preconditioner, linear system
584 
585 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPSetOperators(), KSPGetOperatorsSet()
586 @*/
587 PetscErrorCode  KSPGetOperators(KSP ksp,Mat *Amat,Mat *Pmat,MatStructure *flag)
588 {
589   PetscErrorCode ierr;
590 
591   PetscFunctionBegin;
592   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
593   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
594   ierr = PCGetOperators(ksp->pc,Amat,Pmat,flag);CHKERRQ(ierr);
595   PetscFunctionReturn(0);
596 }
597 
598 #undef __FUNCT__
599 #define __FUNCT__ "KSPGetOperatorsSet"
600 /*@C
601    KSPGetOperatorsSet - Determines if the matrix associated with the linear system and
602    possibly a different one associated with the preconditioner have been set in the KSP.
603 
604    Not collective, though the results on all processes should be the same
605 
606    Input Parameter:
607 .  pc - the KSP context
608 
609    Output Parameters:
610 +  mat - the matrix associated with the linear system was set
611 -  pmat - matrix associated with the preconditioner was set, usually the same
612 
613    Level: intermediate
614 
615 .keywords: KSP, get, operators, matrix, linear system
616 
617 .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperators(), PCGetOperatorsSet()
618 @*/
619 PetscErrorCode  KSPGetOperatorsSet(KSP ksp,PetscBool  *mat,PetscBool  *pmat)
620 {
621   PetscErrorCode ierr;
622 
623   PetscFunctionBegin;
624   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
625   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
626   ierr = PCGetOperatorsSet(ksp->pc,mat,pmat);CHKERRQ(ierr);
627   PetscFunctionReturn(0);
628 }
629 
630 #undef __FUNCT__
631 #define __FUNCT__ "KSPCreate"
632 /*@
633    KSPCreate - Creates the default KSP context.
634 
635    Collective on MPI_Comm
636 
637    Input Parameter:
638 .  comm - MPI communicator
639 
640    Output Parameter:
641 .  ksp - location to put the KSP context
642 
643    Notes:
644    The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt
645    orthogonalization.
646 
647    Level: beginner
648 
649 .keywords: KSP, create, context
650 
651 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP
652 @*/
653 PetscErrorCode  KSPCreate(MPI_Comm comm,KSP *inksp)
654 {
655   KSP            ksp;
656   PetscErrorCode ierr;
657   void           *ctx;
658 
659   PetscFunctionBegin;
660   PetscValidPointer(inksp,2);
661   *inksp = 0;
662 #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
663   ierr = KSPInitializePackage(NULL);CHKERRQ(ierr);
664 #endif
665 
666   ierr = PetscHeaderCreate(ksp,_p_KSP,struct _KSPOps,KSP_CLASSID,"KSP","Krylov Method","KSP",comm,KSPDestroy,KSPView);CHKERRQ(ierr);
667 
668   ksp->max_it  = 10000;
669   ksp->pc_side = PC_SIDE_DEFAULT;
670   ksp->rtol    = 1.e-5;
671   ksp->abstol  = 1.e-50;
672   ksp->divtol  = 1.e4;
673 
674   ksp->chknorm        = -1;
675   ksp->normtype       = KSP_NORM_DEFAULT;
676   ksp->rnorm          = 0.0;
677   ksp->its            = 0;
678   ksp->guess_zero     = PETSC_TRUE;
679   ksp->calc_sings     = PETSC_FALSE;
680   ksp->res_hist       = NULL;
681   ksp->res_hist_alloc = NULL;
682   ksp->res_hist_len   = 0;
683   ksp->res_hist_max   = 0;
684   ksp->res_hist_reset = PETSC_TRUE;
685   ksp->numbermonitors = 0;
686 
687   ierr                    = KSPDefaultConvergedCreate(&ctx);CHKERRQ(ierr);
688   ierr                    = KSPSetConvergenceTest(ksp,KSPDefaultConverged,ctx,KSPDefaultConvergedDestroy);CHKERRQ(ierr);
689   ksp->ops->buildsolution = KSPDefaultBuildSolution;
690   ksp->ops->buildresidual = KSPDefaultBuildResidual;
691 #if defined(PETSC_HAVE_AMS)
692   ((PetscObject)ksp)->bops->publish = KSPPublish_Petsc;
693 #endif
694 
695   ksp->vec_sol    = 0;
696   ksp->vec_rhs    = 0;
697   ksp->pc         = 0;
698   ksp->data       = 0;
699   ksp->nwork      = 0;
700   ksp->work       = 0;
701   ksp->reason     = KSP_CONVERGED_ITERATING;
702   ksp->setupstage = KSP_SETUP_NEW;
703 
704   ierr = KSPNormSupportTableReset_Private(ksp);CHKERRQ(ierr);
705 
706   *inksp = ksp;
707   PetscFunctionReturn(0);
708 }
709 
710 #undef __FUNCT__
711 #define __FUNCT__ "KSPSetType"
712 /*@C
713    KSPSetType - Builds KSP for a particular solver.
714 
715    Logically Collective on KSP
716 
717    Input Parameters:
718 +  ksp      - the Krylov space context
719 -  type - a known method
720 
721    Options Database Key:
722 .  -ksp_type  <method> - Sets the method; use -help for a list
723     of available methods (for instance, cg or gmres)
724 
725    Notes:
726    See "petsc/include/petscksp.h" for available methods (for instance,
727    KSPCG or KSPGMRES).
728 
729   Normally, it is best to use the KSPSetFromOptions() command and
730   then set the KSP type from the options database rather than by using
731   this routine.  Using the options database provides the user with
732   maximum flexibility in evaluating the many different Krylov methods.
733   The KSPSetType() routine is provided for those situations where it
734   is necessary to set the iterative solver independently of the command
735   line or options database.  This might be the case, for example, when
736   the choice of iterative solver changes during the execution of the
737   program, and the user's application is taking responsibility for
738   choosing the appropriate method.  In other words, this routine is
739   not for beginners.
740 
741   Level: intermediate
742 
743 .keywords: KSP, set, method
744 
745 .seealso: PCSetType(), KSPType
746 
747 @*/
748 PetscErrorCode  KSPSetType(KSP ksp, KSPType type)
749 {
750   PetscErrorCode ierr,(*r)(KSP);
751   PetscBool      match;
752 
753   PetscFunctionBegin;
754   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
755   PetscValidCharPointer(type,2);
756 
757   ierr = PetscObjectTypeCompare((PetscObject)ksp,type,&match);CHKERRQ(ierr);
758   if (match) PetscFunctionReturn(0);
759 
760   ierr =  PetscFunctionListFind(PetscObjectComm((PetscObject)ksp),KSPList,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
761   if (!r) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested KSP type %s",type);
762   /* Destroy the previous private KSP context */
763   if (ksp->ops->destroy) {
764     ierr              = (*ksp->ops->destroy)(ksp);CHKERRQ(ierr);
765     ksp->ops->destroy = NULL;
766   }
767   /* Reinitialize function pointers in KSPOps structure */
768   ierr                    = PetscMemzero(ksp->ops,sizeof(struct _KSPOps));CHKERRQ(ierr);
769   ksp->ops->buildsolution = KSPDefaultBuildSolution;
770   ksp->ops->buildresidual = KSPDefaultBuildResidual;
771   ierr                    = KSPNormSupportTableReset_Private(ksp);CHKERRQ(ierr);
772   /* Call the KSPCreate_XXX routine for this particular Krylov solver */
773   ksp->setupstage = KSP_SETUP_NEW;
774   ierr            = PetscObjectChangeTypeName((PetscObject)ksp,type);CHKERRQ(ierr);
775   ierr            = (*r)(ksp);CHKERRQ(ierr);
776 #if defined(PETSC_HAVE_AMS)
777   if (PetscAMSPublishAll) {
778     ierr = PetscObjectAMSPublish((PetscObject)ksp);CHKERRQ(ierr);
779   }
780 #endif
781   PetscFunctionReturn(0);
782 }
783 
784 #undef __FUNCT__
785 #define __FUNCT__ "KSPRegisterDestroy"
786 /*@
787    KSPRegisterDestroy - Frees the list of KSP methods that were
788    registered by KSPRegisterDynamic().
789 
790    Not Collective
791 
792    Level: advanced
793 
794 .keywords: KSP, register, destroy
795 
796 .seealso: KSPRegisterDynamic(), KSPRegisterAll()
797 @*/
798 PetscErrorCode  KSPRegisterDestroy(void)
799 {
800   PetscErrorCode ierr;
801 
802   PetscFunctionBegin;
803   ierr                 = PetscFunctionListDestroy(&KSPList);CHKERRQ(ierr);
804   KSPRegisterAllCalled = PETSC_FALSE;
805   PetscFunctionReturn(0);
806 }
807 
808 #undef __FUNCT__
809 #define __FUNCT__ "KSPGetType"
810 /*@C
811    KSPGetType - Gets the KSP type as a string from the KSP object.
812 
813    Not Collective
814 
815    Input Parameter:
816 .  ksp - Krylov context
817 
818    Output Parameter:
819 .  name - name of KSP method
820 
821    Level: intermediate
822 
823 .keywords: KSP, get, method, name
824 
825 .seealso: KSPSetType()
826 @*/
827 PetscErrorCode  KSPGetType(KSP ksp,KSPType *type)
828 {
829   PetscFunctionBegin;
830   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
831   PetscValidPointer(type,2);
832   *type = ((PetscObject)ksp)->type_name;
833   PetscFunctionReturn(0);
834 }
835 
836 #undef __FUNCT__
837 #define __FUNCT__ "KSPRegister"
838 /*@C
839   KSPRegister - See KSPRegisterDynamic()
840 
841   Level: advanced
842 @*/
843 PetscErrorCode  KSPRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(KSP))
844 {
845   PetscErrorCode ierr;
846   char           fullname[PETSC_MAX_PATH_LEN];
847 
848   PetscFunctionBegin;
849   ierr = PetscFunctionListConcat(path,name,fullname);CHKERRQ(ierr);
850   ierr = PetscFunctionListAdd(PETSC_COMM_WORLD,&KSPList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
851   PetscFunctionReturn(0);
852 }
853 
854 #undef __FUNCT__
855 #define __FUNCT__ "KSPSetNullSpace"
856 /*@
857   KSPSetNullSpace - Sets the null space of the operator
858 
859   Logically Collective on KSP
860 
861   Input Parameters:
862 +  ksp - the Krylov space object
863 -  nullsp - the null space of the operator
864 
865   Level: advanced
866 
867 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPGetNullSpace(), MatSetNullSpace()
868 @*/
869 PetscErrorCode  KSPSetNullSpace(KSP ksp,MatNullSpace nullsp)
870 {
871   PetscErrorCode ierr;
872 
873   PetscFunctionBegin;
874   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
875   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
876   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
877   if (ksp->nullsp) { ierr = MatNullSpaceDestroy(&ksp->nullsp);CHKERRQ(ierr); }
878   ksp->nullsp = nullsp;
879   PetscFunctionReturn(0);
880 }
881 
882 #undef __FUNCT__
883 #define __FUNCT__ "KSPGetNullSpace"
884 /*@
885   KSPGetNullSpace - Gets the null space of the operator
886 
887   Not Collective
888 
889   Input Parameters:
890 +  ksp - the Krylov space object
891 -  nullsp - the null space of the operator
892 
893   Level: advanced
894 
895 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPSetNullSpace()
896 @*/
897 PetscErrorCode  KSPGetNullSpace(KSP ksp,MatNullSpace *nullsp)
898 {
899   PetscFunctionBegin;
900   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
901   PetscValidPointer(nullsp,2);
902   *nullsp = ksp->nullsp;
903   PetscFunctionReturn(0);
904 }
905 
906