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