xref: /petsc/src/ksp/ksp/interface/itcreate.c (revision f3be49ca30a5b63307daac95dd3149ecefeed79a)
1 #define PETSCKSP_DLL
2 
3 /*
4      The basic KSP routines, Create, View etc. are here.
5 */
6 #include "include/private/kspimpl.h"      /*I "petscksp.h" I*/
7 #include "petscsys.h"
8 
9 /* Logging support */
10 PetscCookie PETSCKSP_DLLEXPORT KSP_COOKIE = 0;
11 PetscEvent  KSP_GMRESOrthogonalization = 0, KSP_SetUp = 0, KSP_Solve = 0;
12 
13 
14 PetscTruth KSPRegisterAllCalled = PETSC_FALSE;
15 
16 #undef __FUNCT__
17 #define __FUNCT__ "KSPView"
18 /*@C
19    KSPView - Prints the KSP data structure.
20 
21    Collective on KSP
22 
23    Input Parameters:
24 +  ksp - the Krylov space context
25 -  viewer - visualization context
26 
27    Options Database Keys:
28 .  -ksp_view - print the ksp data structure at the end of a KSPSolve call
29 
30    Note:
31    The available visualization contexts include
32 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
33 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
34          output where only the first processor opens
35          the file.  All other processors send their
36          data to the first processor to print.
37 
38    The user can open an alternative visualization context with
39    PetscViewerASCIIOpen() - output to a specified file.
40 
41    Level: beginner
42 
43 .keywords: KSP, view
44 
45 .seealso: PCView(), PetscViewerASCIIOpen()
46 @*/
47 PetscErrorCode PETSCKSP_DLLEXPORT KSPView(KSP ksp,PetscViewer viewer)
48 {
49   const char     *type;
50   PetscErrorCode ierr;
51   PetscTruth     iascii;
52 
53   PetscFunctionBegin;
54   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
55   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(ksp->comm);
56   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2);
57   PetscCheckSameComm(ksp,1,viewer,2);
58 
59   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
60   if (iascii) {
61     ierr = KSPGetType(ksp,&type);CHKERRQ(ierr);
62     if (ksp->prefix) {
63       ierr = PetscViewerASCIIPrintf(viewer,"KSP Object:(%s)\n",ksp->prefix);CHKERRQ(ierr);
64     } else {
65       ierr = PetscViewerASCIIPrintf(viewer,"KSP Object:\n");CHKERRQ(ierr);
66     }
67     if (type) {
68       ierr = PetscViewerASCIIPrintf(viewer,"  type: %s\n",type);CHKERRQ(ierr);
69     } else {
70       ierr = PetscViewerASCIIPrintf(viewer,"  type: not yet set\n");CHKERRQ(ierr);
71     }
72     if (ksp->ops->view) {
73       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
74       ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
75       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
76     }
77     if (ksp->guess_zero) {ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, initial guess is zero\n",ksp->max_it);CHKERRQ(ierr);}
78     else                 {ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", ksp->max_it);CHKERRQ(ierr);}
79     if (ksp->guess_knoll) {ierr = PetscViewerASCIIPrintf(viewer,"  using preconditioner applied to right hand side for initial guess\n");CHKERRQ(ierr);}
80     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances:  relative=%G, absolute=%G, divergence=%G\n",ksp->rtol,ksp->abstol,ksp->divtol);CHKERRQ(ierr);
81     if (ksp->pc_side == PC_RIGHT)          {ierr = PetscViewerASCIIPrintf(viewer,"  right preconditioning\n");CHKERRQ(ierr);}
82     else if (ksp->pc_side == PC_SYMMETRIC) {ierr = PetscViewerASCIIPrintf(viewer,"  symmetric preconditioning\n");CHKERRQ(ierr);}
83     else                                   {ierr = PetscViewerASCIIPrintf(viewer,"  left preconditioning\n");CHKERRQ(ierr);}
84   } else {
85     if (ksp->ops->view) {
86       ierr = (*ksp->ops->view)(ksp,viewer);CHKERRQ(ierr);
87     }
88   }
89   ierr = PCView(ksp->pc,viewer);CHKERRQ(ierr);
90   PetscFunctionReturn(0);
91 }
92 
93 /*
94    Contains the list of registered KSP routines
95 */
96 PetscFList KSPList = 0;
97 
98 #undef __FUNCT__
99 #define __FUNCT__ "KSPSetNormType"
100 /*@
101    KSPSetNormType - Sets the norm that is used for convergence testing.
102 
103    Collective on KSP
104 
105    Input Parameter:
106 +  ksp - Krylov solver context
107 -  normtype - one of
108 $   KSP_NORM_NO - skips computing the norm, this should only be used if you are using
109 $                 the Krylov method as a smoother with a fixed small number of iterations.
110 $                 You must also call KSPSetConvergenceTest(ksp,KSPSkipConverged,PETSC_NULL);
111 $                 supported only by CG, Richardson, Bi-CG-stab, CR, and CGS methods.
112 $   KSP_NORM_PRECONDITIONED - the default for left preconditioned solves, uses the l2 norm
113 $                 of the preconditioned residual
114 $   KSP_NORM_UNPRECONDITIONED - uses the l2 norm of the true b - Ax residual, supported only by
115 $                 CG, CHEBYCHEV, and RICHARDSON, automatically true for right (see KSPSetPreconditioningSide())
116 $                 preconditioning..
117 $   KSP_NORM_NATURAL - supported  by cg, cr, and cgs
118 
119 
120    Options Database Key:
121 .   -ksp_norm_type <none,preconditioned,unpreconditioned,natural>
122 
123    Notes:
124    Currently only works with the CG, Richardson, Bi-CG-stab, CR, and CGS methods.
125 
126    Level: advanced
127 
128 .keywords: KSP, create, context, norms
129 
130 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged()
131 @*/
132 PetscErrorCode PETSCKSP_DLLEXPORT KSPSetNormType(KSP ksp,KSPNormType normtype)
133 {
134   PetscErrorCode ierr;
135 
136   PetscFunctionBegin;
137   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
138   ksp->normtype = normtype;
139   if (normtype == KSP_NORM_NO) {
140     ierr = PetscInfo(ksp,"Warning seting KSPNormType to skip computing the norm\n\
141   make sure you set the KSP convergence test to KSPSkipConvergence\n");CHKERRQ(ierr);
142   }
143   PetscFunctionReturn(0);
144 }
145 
146 #undef __FUNCT__
147 #define __FUNCT__ "KSPGetNormType"
148 /*@
149    KSPGetNormType - Sets the norm that is used for convergence testing.
150 
151    Not Collective
152 
153    Input Parameter:
154 .  ksp - Krylov solver context
155 
156    Output Parameter:
157 .  normtype - norm that is used for convergence testing
158 
159    Level: advanced
160 
161 .keywords: KSP, create, context, norms
162 
163 .seealso: KSPNormType, KSPSetNormType(), KSPSkipConverged()
164 @*/
165 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetNormType(KSP ksp, KSPNormType *normtype) {
166   PetscFunctionBegin;
167   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
168   PetscValidPointer(normtype, 2);
169   *normtype = ksp->normtype;
170   PetscFunctionReturn(0);
171 }
172 
173 #undef __FUNCT__
174 #define __FUNCT__ "KSPPublish_Petsc"
175 static PetscErrorCode KSPPublish_Petsc(PetscObject obj)
176 {
177   PetscFunctionBegin;
178   PetscFunctionReturn(0);
179 }
180 
181 #undef __FUNCT__
182 #define __FUNCT__ "KSPSetOperators"
183 /*@
184    KSPSetOperators - Sets the matrix associated with the linear system
185    and a (possibly) different one associated with the preconditioner.
186 
187    Collective on KSP and Mat
188 
189    Input Parameters:
190 +  ksp - the KSP context
191 .  Amat - the matrix associated with the linear system
192 .  Pmat - the matrix to be used in constructing the preconditioner, usually the
193           same as Amat.
194 -  flag - flag indicating information about the preconditioner matrix structure
195    during successive linear solves.  This flag is ignored the first time a
196    linear system is solved, and thus is irrelevant when solving just one linear
197    system.
198 
199    Notes:
200    The flag can be used to eliminate unnecessary work in the preconditioner
201    during the repeated solution of linear systems of the same size.  The
202    available options are
203 $    SAME_PRECONDITIONER -
204 $      Pmat is identical during successive linear solves.
205 $      This option is intended for folks who are using
206 $      different Amat and Pmat matrices and want to reuse the
207 $      same preconditioner matrix.  For example, this option
208 $      saves work by not recomputing incomplete factorization
209 $      for ILU/ICC preconditioners.
210 $    SAME_NONZERO_PATTERN -
211 $      Pmat has the same nonzero structure during
212 $      successive linear solves.
213 $    DIFFERENT_NONZERO_PATTERN -
214 $      Pmat does not have the same nonzero structure.
215 
216     Caution:
217     If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
218     and does not check the structure of the matrix.  If you erroneously
219     claim that the structure is the same when it actually is not, the new
220     preconditioner will not function correctly.  Thus, use this optimization
221     feature carefully!
222 
223     If in doubt about whether your preconditioner matrix has changed
224     structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
225 
226     Level: beginner
227 
228    Alternative usage: If the operators have NOT been set with KSP/PCSetOperators() then the operators
229       are created in PC and returned to the user. In this case, if both operators
230       mat and pmat are requested, two DIFFERENT operators will be returned. If
231       only one is requested both operators in the PC will be the same (i.e. as
232       if one had called KSP/PCSetOperators() with the same argument for both Mats).
233       The user must set the sizes of the returned matrices and their type etc just
234       as if the user created them with MatCreate(). For example,
235 
236 $         KSP/PCGetOperators(ksp/pc,&mat,PETSC_NULL,PETSC_NULL); is equivalent to
237 $           set size, type, etc of mat
238 
239 $         MatCreate(comm,&mat);
240 $         KSP/PCSetOperators(ksp/pc,mat,mat,SAME_NONZERO_PATTERN);
241 $         PetscObjectDereference((PetscObject)mat);
242 $           set size, type, etc of mat
243 
244      and
245 
246 $         KSP/PCGetOperators(ksp/pc,&mat,&pmat,PETSC_NULL); is equivalent to
247 $           set size, type, etc of mat and pmat
248 
249 $         MatCreate(comm,&mat);
250 $         MatCreate(comm,&pmat);
251 $         KSP/PCSetOperators(ksp/pc,mat,pmat,SAME_NONZERO_PATTERN);
252 $         PetscObjectDereference((PetscObject)mat);
253 $         PetscObjectDereference((PetscObject)pmat);
254 $           set size, type, etc of mat and pmat
255 
256     The rational for this support is so that when creating a TS, SNES, or KSP the hierarchy
257     of underlying objects (i.e. SNES, KSP, PC, Mat) and their livespans can be completely
258     managed by the top most level object (i.e. the TS, SNES, or KSP). Another way to look
259     at this is when you create a SNES you do not NEED to create a KSP and attach it to
260     the SNES object (the SNES object manages it for you). Similarly when you create a KSP
261     you do not need to attach a PC to it (the KSP object manages the PC object for you).
262     Thus, why should YOU have to create the Mat and attach it to the SNES/KSP/PC, when
263     it can be created for you?
264 
265 .keywords: KSP, set, operators, matrix, preconditioner, linear system
266 
267 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPGetOperators()
268 @*/
269 PetscErrorCode PETSCKSP_DLLEXPORT KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat,MatStructure flag)
270 {
271   PetscErrorCode ierr;
272 
273   PetscFunctionBegin;
274   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
275   if (Amat) PetscValidHeaderSpecific(Amat,MAT_COOKIE,2);
276   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_COOKIE,3);
277   if (Amat) PetscCheckSameComm(ksp,1,Amat,2);
278   if (Pmat) PetscCheckSameComm(ksp,1,Pmat,3);
279   ierr = PCSetOperators(ksp->pc,Amat,Pmat,flag);CHKERRQ(ierr);
280   if (ksp->setupcalled > 1) ksp->setupcalled = 1;  /* so that next solve call will call setup */
281   PetscFunctionReturn(0);
282 }
283 
284 #undef __FUNCT__
285 #define __FUNCT__ "KSPGetOperators"
286 /*@
287    KSPGetOperators - Gets the matrix associated with the linear system
288    and a (possibly) different one associated with the preconditioner.
289 
290    Collective on KSP and Mat
291 
292    Input Parameter:
293 .  ksp - the KSP context
294 
295    Output Parameters:
296 +  Amat - the matrix associated with the linear system
297 .  Pmat - the matrix to be used in constructing the preconditioner, usually the
298           same as Amat.
299 -  flag - flag indicating information about the preconditioner matrix structure
300    during successive linear solves.  This flag is ignored the first time a
301    linear system is solved, and thus is irrelevant when solving just one linear
302    system.
303 
304     Level: intermediate
305 
306 .keywords: KSP, set, get, operators, matrix, preconditioner, linear system
307 
308 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPSetOperators(), KSPGetOperatorsSet()
309 @*/
310 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetOperators(KSP ksp,Mat *Amat,Mat *Pmat,MatStructure *flag)
311 {
312   PetscErrorCode ierr;
313 
314   PetscFunctionBegin;
315   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
316   ierr = PCGetOperators(ksp->pc,Amat,Pmat,flag);CHKERRQ(ierr);
317   PetscFunctionReturn(0);
318 }
319 
320 #undef __FUNCT__
321 #define __FUNCT__ "KSPGetOperatorsSet"
322 /*@C
323    KSPGetOperatorsSet - Determines if the matrix associated with the linear system and
324    possibly a different one associated with the preconditioner have been set in the KSP.
325 
326    Not collective, though the results on all processes should be the same
327 
328    Input Parameter:
329 .  pc - the preconditioner context
330 
331    Output Parameters:
332 +  mat - the matrix associated with the linear system was set
333 -  pmat - matrix associated with the preconditioner was set, usually the same
334 
335    Level: intermediate
336 
337 .keywords: KSP, get, operators, matrix, linear system
338 
339 .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperators(), PCGetOperatorsSet()
340 @*/
341 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetOperatorsSet(KSP ksp,PetscTruth *mat,PetscTruth *pmat)
342 {
343   PetscErrorCode ierr;
344 
345   PetscFunctionBegin;
346   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
347   ierr = PCGetOperatorsSet(ksp->pc,mat,pmat);CHKERRQ(ierr);
348   PetscFunctionReturn(0);
349 }
350 
351 #undef __FUNCT__
352 #define __FUNCT__ "KSPCreate"
353 /*@
354    KSPCreate - Creates the default KSP context.
355 
356    Collective on MPI_Comm
357 
358    Input Parameter:
359 .  comm - MPI communicator
360 
361    Output Parameter:
362 .  ksp - location to put the KSP context
363 
364    Notes:
365    The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt
366    orthogonalization.
367 
368    Level: beginner
369 
370 .keywords: KSP, create, context
371 
372 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP
373 @*/
374 PetscErrorCode PETSCKSP_DLLEXPORT KSPCreate(MPI_Comm comm,KSP *inksp)
375 {
376   KSP            ksp;
377   PetscErrorCode ierr;
378 
379   PetscFunctionBegin;
380   PetscValidPointer(inksp,2);
381   *inksp = 0;
382 #ifndef PETSC_USE_DYNAMIC_LIBRARIES
383   ierr = KSPInitializePackage(PETSC_NULL);CHKERRQ(ierr);
384 #endif
385 
386   ierr = PetscHeaderCreate(ksp,_p_KSP,struct _KSPOps,KSP_COOKIE,-1,"KSP",comm,KSPDestroy,KSPView);CHKERRQ(ierr);
387   ksp->bops->publish = KSPPublish_Petsc;
388 
389   ksp->type          = -1;
390   ksp->max_it        = 10000;
391   ksp->pc_side       = PC_LEFT;
392   ksp->rtol          = 1.e-5;
393   ksp->abstol        = 1.e-50;
394   ksp->divtol        = 1.e4;
395 
396   ksp->normtype            = KSP_NORM_PRECONDITIONED;
397   ksp->rnorm               = 0.0;
398   ksp->its                 = 0;
399   ksp->guess_zero          = PETSC_TRUE;
400   ksp->calc_sings          = PETSC_FALSE;
401   ksp->res_hist            = PETSC_NULL;
402   ksp->res_hist_alloc      = PETSC_NULL;
403   ksp->res_hist_len        = 0;
404   ksp->res_hist_max        = 0;
405   ksp->res_hist_reset      = PETSC_TRUE;
406   ksp->numbermonitors      = 0;
407 
408   ksp->converged           = KSPDefaultConverged;
409   ksp->ops->buildsolution  = KSPDefaultBuildSolution;
410   ksp->ops->buildresidual  = KSPDefaultBuildResidual;
411 
412   ksp->vec_sol         = 0;
413   ksp->vec_rhs         = 0;
414   ksp->pc              = 0;
415   ksp->data            = 0;
416   ksp->nwork           = 0;
417   ksp->work            = 0;
418   ksp->cnvP            = 0;
419   ksp->reason          = KSP_CONVERGED_ITERATING;
420   ksp->setupcalled     = 0;
421 
422   ierr = PetscPublishAll(ksp);CHKERRQ(ierr);
423   ierr = PCCreate(comm,&ksp->pc);CHKERRQ(ierr);
424   *inksp = ksp;
425   PetscFunctionReturn(0);
426 }
427 
428 #undef __FUNCT__
429 #define __FUNCT__ "KSPSetType"
430 /*@C
431    KSPSetType - Builds KSP for a particular solver.
432 
433    Collective on KSP
434 
435    Input Parameters:
436 +  ksp      - the Krylov space context
437 -  type - a known method
438 
439    Options Database Key:
440 .  -ksp_type  <method> - Sets the method; use -help for a list
441     of available methods (for instance, cg or gmres)
442 
443    Notes:
444    See "petsc/include/petscksp.h" for available methods (for instance,
445    KSPCG or KSPGMRES).
446 
447   Normally, it is best to use the KSPSetFromOptions() command and
448   then set the KSP type from the options database rather than by using
449   this routine.  Using the options database provides the user with
450   maximum flexibility in evaluating the many different Krylov methods.
451   The KSPSetType() routine is provided for those situations where it
452   is necessary to set the iterative solver independently of the command
453   line or options database.  This might be the case, for example, when
454   the choice of iterative solver changes during the execution of the
455   program, and the user's application is taking responsibility for
456   choosing the appropriate method.  In other words, this routine is
457   not for beginners.
458 
459   Level: intermediate
460 
461 .keywords: KSP, set, method
462 
463 .seealso: PCSetType(), KSPType
464 
465 @*/
466 PetscErrorCode PETSCKSP_DLLEXPORT KSPSetType(KSP ksp, KSPType type)
467 {
468   PetscErrorCode ierr,(*r)(KSP);
469   PetscTruth     match;
470 
471   PetscFunctionBegin;
472   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
473   PetscValidCharPointer(type,2);
474 
475   ierr = PetscTypeCompare((PetscObject)ksp,type,&match);CHKERRQ(ierr);
476   if (match) PetscFunctionReturn(0);
477 
478   ierr =  PetscFListFind(KSPList,ksp->comm,type,(void (**)(void)) &r);CHKERRQ(ierr);
479   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested KSP type %s",type);
480   /* Destroy the previous private KSP context */
481   if (ksp->ops->destroy) { ierr = (*ksp->ops->destroy)(ksp);CHKERRQ(ierr); }
482   /* Reinitialize function pointers in KSPOps structure */
483   ierr = PetscMemzero(ksp->ops,sizeof(struct _KSPOps));CHKERRQ(ierr);
484   ksp->ops->buildsolution = KSPDefaultBuildSolution;
485   ksp->ops->buildresidual = KSPDefaultBuildResidual;
486   /* Call the KSPCreate_XXX routine for this particular Krylov solver */
487   ksp->setupcalled = 0;
488   ierr = (*r)(ksp);CHKERRQ(ierr);
489   ierr = PetscObjectChangeTypeName((PetscObject)ksp,type);CHKERRQ(ierr);
490   PetscFunctionReturn(0);
491 }
492 
493 #undef __FUNCT__
494 #define __FUNCT__ "KSPRegisterDestroy"
495 /*@
496    KSPRegisterDestroy - Frees the list of KSP methods that were
497    registered by KSPRegisterDynamic().
498 
499    Not Collective
500 
501    Level: advanced
502 
503 .keywords: KSP, register, destroy
504 
505 .seealso: KSPRegisterDynamic(), KSPRegisterAll()
506 @*/
507 PetscErrorCode PETSCKSP_DLLEXPORT KSPRegisterDestroy(void)
508 {
509   PetscErrorCode ierr;
510 
511   PetscFunctionBegin;
512   ierr = PetscFListDestroy(&KSPList);CHKERRQ(ierr);
513   KSPRegisterAllCalled = PETSC_FALSE;
514   PetscFunctionReturn(0);
515 }
516 
517 #undef __FUNCT__
518 #define __FUNCT__ "KSPGetType"
519 /*@C
520    KSPGetType - Gets the KSP type as a string from the KSP object.
521 
522    Not Collective
523 
524    Input Parameter:
525 .  ksp - Krylov context
526 
527    Output Parameter:
528 .  name - name of KSP method
529 
530    Level: intermediate
531 
532 .keywords: KSP, get, method, name
533 
534 .seealso: KSPSetType()
535 @*/
536 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetType(KSP ksp,KSPType *type)
537 {
538   PetscFunctionBegin;
539   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
540   PetscValidPointer(type,2);
541   *type = ksp->type_name;
542   PetscFunctionReturn(0);
543 }
544 
545 #undef __FUNCT__
546 #define __FUNCT__ "KSPRegister"
547 /*@C
548   KSPRegister - See KSPRegisterDynamic()
549 
550   Level: advanced
551 @*/
552 PetscErrorCode PETSCKSP_DLLEXPORT KSPRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(KSP))
553 {
554   PetscErrorCode ierr;
555   char           fullname[PETSC_MAX_PATH_LEN];
556 
557   PetscFunctionBegin;
558   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
559   ierr = PetscFListAdd(&KSPList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
560   PetscFunctionReturn(0);
561 }
562 
563 #undef __FUNCT__
564 #define __FUNCT__ "KSPSetNullSpace"
565 /*@
566   KSPSetNullSpace - Sets the null space of the operator
567 
568   Collective on KSP
569 
570   Input Parameters:
571 +  ksp - the Krylov space object
572 -  nullsp - the null space of the operator
573 
574   Level: advanced
575 
576 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPGetNullSpace()
577 @*/
578 PetscErrorCode PETSCKSP_DLLEXPORT KSPSetNullSpace(KSP ksp,MatNullSpace nullsp)
579 {
580   PetscErrorCode ierr;
581 
582   PetscFunctionBegin;
583   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
584   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
585   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
586   if (ksp->nullsp) { ierr = MatNullSpaceDestroy(ksp->nullsp);CHKERRQ(ierr); }
587   ksp->nullsp = nullsp;
588   PetscFunctionReturn(0);
589 }
590 
591 #undef __FUNCT__
592 #define __FUNCT__ "KSPGetNullSpace"
593 /*@
594   KSPGetNullSpace - Gets the null space of the operator
595 
596   Collective on KSP
597 
598   Input Parameters:
599 +  ksp - the Krylov space object
600 -  nullsp - the null space of the operator
601 
602   Level: advanced
603 
604 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPSetNullSpace()
605 @*/
606 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetNullSpace(KSP ksp,MatNullSpace *nullsp)
607 {
608   PetscFunctionBegin;
609   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
610   PetscValidPointer(nullsp,2);
611   *nullsp = ksp->nullsp;
612   PetscFunctionReturn(0);
613 }
614 
615