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