xref: /petsc/src/ksp/ksp/interface/itcreate.c (revision 7dcf0eaabfd24a99cab9067fb7513f2271c036d2)
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_NO_NORM - 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_PRECONDITIONED_NORM - the default for left preconditioned solves, uses the l2 norm
113 $                 of the preconditioned residual
114 $   KSP_UNPRECONDITIONED_NORM - 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_NATURAL_NORM - 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_NO_NORM) {
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__ "KSPPublish_Petsc"
148 static PetscErrorCode KSPPublish_Petsc(PetscObject obj)
149 {
150   PetscFunctionBegin;
151   PetscFunctionReturn(0);
152 }
153 
154 #undef __FUNCT__
155 #define __FUNCT__ "KSPSetOperators"
156 /*@
157    KSPSetOperators - Sets the matrix associated with the linear system
158    and a (possibly) different one associated with the preconditioner.
159 
160    Collective on KSP and Mat
161 
162    Input Parameters:
163 +  ksp - the KSP context
164 .  Amat - the matrix associated with the linear system
165 .  Pmat - the matrix to be used in constructing the preconditioner, usually the
166           same as Amat.
167 -  flag - flag indicating information about the preconditioner matrix structure
168    during successive linear solves.  This flag is ignored the first time a
169    linear system is solved, and thus is irrelevant when solving just one linear
170    system.
171 
172    Notes:
173    The flag can be used to eliminate unnecessary work in the preconditioner
174    during the repeated solution of linear systems of the same size.  The
175    available options are
176 $    SAME_PRECONDITIONER -
177 $      Pmat is identical during successive linear solves.
178 $      This option is intended for folks who are using
179 $      different Amat and Pmat matrices and want to reuse the
180 $      same preconditioner matrix.  For example, this option
181 $      saves work by not recomputing incomplete factorization
182 $      for ILU/ICC preconditioners.
183 $    SAME_NONZERO_PATTERN -
184 $      Pmat has the same nonzero structure during
185 $      successive linear solves.
186 $    DIFFERENT_NONZERO_PATTERN -
187 $      Pmat does not have the same nonzero structure.
188 
189     Caution:
190     If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
191     and does not check the structure of the matrix.  If you erroneously
192     claim that the structure is the same when it actually is not, the new
193     preconditioner will not function correctly.  Thus, use this optimization
194     feature carefully!
195 
196     If in doubt about whether your preconditioner matrix has changed
197     structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
198 
199     Level: beginner
200 
201    Alternative usage: If the operators have NOT been set with KSP/PCSetOperators() then the operators
202       are created in PC and returned to the user. In this case, if both operators
203       mat and pmat are requested, two DIFFERENT operators will be returned. If
204       only one is requested both operators in the PC will be the same (i.e. as
205       if one had called KSP/PCSetOperators() with the same argument for both Mats).
206       The user must set the sizes of the returned matrices and their type etc just
207       as if the user created them with MatCreate(). For example,
208 
209 $         KSP/PCGetOperators(ksp/pc,&mat,PETSC_NULL,PETSC_NULL); is equivalent to
210 $           set size, type, etc of mat
211 
212 $         MatCreate(comm,&mat);
213 $         KSP/PCSetOperators(ksp/pc,mat,mat,SAME_NONZERO_PATTERN);
214 $         PetscObjectDereference((PetscObject)mat);
215 $           set size, type, etc of mat
216 
217      and
218 
219 $         KSP/PCGetOperators(ksp/pc,&mat,&pmat,PETSC_NULL); is equivalent to
220 $           set size, type, etc of mat and pmat
221 
222 $         MatCreate(comm,&mat);
223 $         MatCreate(comm,&pmat);
224 $         KSP/PCSetOperators(ksp/pc,mat,pmat,SAME_NONZERO_PATTERN);
225 $         PetscObjectDereference((PetscObject)mat);
226 $         PetscObjectDereference((PetscObject)pmat);
227 $           set size, type, etc of mat and pmat
228 
229     The rational for this support is so that when creating a TS, SNES, or KSP the hierarchy
230     of underlying objects (i.e. SNES, KSP, PC, Mat) and their livespans can be completely
231     managed by the top most level object (i.e. the TS, SNES, or KSP). Another way to look
232     at this is when you create a SNES you do not NEED to create a KSP and attach it to
233     the SNES object (the SNES object manages it for you). Similarly when you create a KSP
234     you do not need to attach a PC to it (the KSP object manages the PC object for you).
235     Thus, why should YOU have to create the Mat and attach it to the SNES/KSP/PC, when
236     it can be created for you?
237 
238 .keywords: KSP, set, operators, matrix, preconditioner, linear system
239 
240 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPGetOperators()
241 @*/
242 PetscErrorCode PETSCKSP_DLLEXPORT KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat,MatStructure flag)
243 {
244   PetscErrorCode ierr;
245 
246   PetscFunctionBegin;
247   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
248   if (Amat) PetscValidHeaderSpecific(Amat,MAT_COOKIE,2);
249   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_COOKIE,3);
250   if (Amat) PetscCheckSameComm(ksp,1,Amat,2);
251   if (Pmat) PetscCheckSameComm(ksp,1,Pmat,3);
252   ierr = PCSetOperators(ksp->pc,Amat,Pmat,flag);CHKERRQ(ierr);
253   if (ksp->setupcalled > 1) ksp->setupcalled = 1;  /* so that next solve call will call setup */
254   PetscFunctionReturn(0);
255 }
256 
257 #undef __FUNCT__
258 #define __FUNCT__ "KSPGetOperators"
259 /*@
260    KSPGetOperators - Gets the matrix associated with the linear system
261    and a (possibly) different one associated with the preconditioner.
262 
263    Collective on KSP and Mat
264 
265    Input Parameter:
266 .  ksp - the KSP context
267 
268    Output Parameters:
269 +  Amat - the matrix associated with the linear system
270 .  Pmat - the matrix to be used in constructing the preconditioner, usually the
271           same as Amat.
272 -  flag - flag indicating information about the preconditioner matrix structure
273    during successive linear solves.  This flag is ignored the first time a
274    linear system is solved, and thus is irrelevant when solving just one linear
275    system.
276 
277     Level: intermediate
278 
279 .keywords: KSP, set, get, operators, matrix, preconditioner, linear system
280 
281 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPSetOperators(), KSPGetOperatorsSet()
282 @*/
283 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetOperators(KSP ksp,Mat *Amat,Mat *Pmat,MatStructure *flag)
284 {
285   PetscErrorCode ierr;
286 
287   PetscFunctionBegin;
288   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
289   ierr = PCGetOperators(ksp->pc,Amat,Pmat,flag);CHKERRQ(ierr);
290   PetscFunctionReturn(0);
291 }
292 
293 #undef __FUNCT__
294 #define __FUNCT__ "KSPGetOperatorsSet"
295 /*@C
296    KSPGetOperatorsSet - Determines if the matrix associated with the linear system and
297    possibly a different one associated with the preconditioner have been set in the KSP.
298 
299    Not collective, though the results on all processes should be the same
300 
301    Input Parameter:
302 .  pc - the preconditioner context
303 
304    Output Parameters:
305 +  mat - the matrix associated with the linear system was set
306 -  pmat - matrix associated with the preconditioner was set, usually the same
307 
308    Level: intermediate
309 
310 .keywords: KSP, get, operators, matrix, linear system
311 
312 .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperators(), PCGetOperatorsSet()
313 @*/
314 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetOperatorsSet(KSP ksp,PetscTruth *mat,PetscTruth *pmat)
315 {
316   PetscErrorCode ierr;
317 
318   PetscFunctionBegin;
319   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
320   ierr = PCGetOperatorsSet(ksp->pc,mat,pmat);CHKERRQ(ierr);
321   PetscFunctionReturn(0);
322 }
323 
324 #undef __FUNCT__
325 #define __FUNCT__ "KSPCreate"
326 /*@
327    KSPCreate - Creates the default KSP context.
328 
329    Collective on MPI_Comm
330 
331    Input Parameter:
332 .  comm - MPI communicator
333 
334    Output Parameter:
335 .  ksp - location to put the KSP context
336 
337    Notes:
338    The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt
339    orthogonalization.
340 
341    Level: beginner
342 
343 .keywords: KSP, create, context
344 
345 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP
346 @*/
347 PetscErrorCode PETSCKSP_DLLEXPORT KSPCreate(MPI_Comm comm,KSP *inksp)
348 {
349   KSP            ksp;
350   PetscErrorCode ierr;
351 
352   PetscFunctionBegin;
353   PetscValidPointer(inksp,2);
354   *inksp = 0;
355 #ifndef PETSC_USE_DYNAMIC_LIBRARIES
356   ierr = KSPInitializePackage(PETSC_NULL);CHKERRQ(ierr);
357 #endif
358 
359   ierr = PetscHeaderCreate(ksp,_p_KSP,struct _KSPOps,KSP_COOKIE,-1,"KSP",comm,KSPDestroy,KSPView);CHKERRQ(ierr);
360   *inksp             = ksp;
361   ksp->bops->publish = KSPPublish_Petsc;
362 
363   ksp->type          = -1;
364   ksp->max_it        = 10000;
365   ksp->pc_side       = PC_LEFT;
366   ksp->rtol          = 1.e-5;
367   ksp->abstol          = 1.e-50;
368   ksp->divtol        = 1.e4;
369 
370   ksp->normtype            = KSP_PRECONDITIONED_NORM;
371   ksp->rnorm               = 0.0;
372   ksp->its                 = 0;
373   ksp->guess_zero          = PETSC_TRUE;
374   ksp->calc_sings          = PETSC_FALSE;
375   ksp->res_hist            = PETSC_NULL;
376   ksp->res_hist_len        = 0;
377   ksp->res_hist_max        = 0;
378   ksp->res_hist_reset      = PETSC_TRUE;
379   ksp->numbermonitors      = 0;
380   ksp->converged           = KSPDefaultConverged;
381   ksp->ops->buildsolution  = KSPDefaultBuildSolution;
382   ksp->ops->buildresidual  = KSPDefaultBuildResidual;
383 
384   ksp->ops->setfromoptions = 0;
385 
386   ksp->vec_sol         = 0;
387   ksp->vec_rhs         = 0;
388   ksp->pc              = 0;
389 
390   ksp->ops->solve      = 0;
391   ksp->ops->setup      = 0;
392   ksp->ops->destroy    = 0;
393 
394   ksp->data            = 0;
395   ksp->nwork           = 0;
396   ksp->work            = 0;
397 
398   ksp->cnvP            = 0;
399 
400   ksp->reason          = KSP_CONVERGED_ITERATING;
401 
402   ksp->setupcalled     = 0;
403   ierr = PetscPublishAll(ksp);CHKERRQ(ierr);
404   ierr = PCCreate(comm,&ksp->pc);CHKERRQ(ierr);
405   PetscFunctionReturn(0);
406 }
407 
408 #undef __FUNCT__
409 #define __FUNCT__ "KSPSetType"
410 /*@C
411    KSPSetType - Builds KSP for a particular solver.
412 
413    Collective on KSP
414 
415    Input Parameters:
416 +  ksp      - the Krylov space context
417 -  type - a known method
418 
419    Options Database Key:
420 .  -ksp_type  <method> - Sets the method; use -help for a list
421     of available methods (for instance, cg or gmres)
422 
423    Notes:
424    See "petsc/include/petscksp.h" for available methods (for instance,
425    KSPCG or KSPGMRES).
426 
427   Normally, it is best to use the KSPSetFromOptions() command and
428   then set the KSP type from the options database rather than by using
429   this routine.  Using the options database provides the user with
430   maximum flexibility in evaluating the many different Krylov methods.
431   The KSPSetType() routine is provided for those situations where it
432   is necessary to set the iterative solver independently of the command
433   line or options database.  This might be the case, for example, when
434   the choice of iterative solver changes during the execution of the
435   program, and the user's application is taking responsibility for
436   choosing the appropriate method.  In other words, this routine is
437   not for beginners.
438 
439   Level: intermediate
440 
441 .keywords: KSP, set, method
442 
443 .seealso: PCSetType(), KSPType
444 
445 @*/
446 PetscErrorCode PETSCKSP_DLLEXPORT KSPSetType(KSP ksp, KSPType type)
447 {
448   PetscErrorCode ierr,(*r)(KSP);
449   PetscTruth     match;
450 
451   PetscFunctionBegin;
452   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
453   PetscValidCharPointer(type,2);
454 
455   ierr = PetscTypeCompare((PetscObject)ksp,type,&match);CHKERRQ(ierr);
456   if (match) PetscFunctionReturn(0);
457 
458   if (ksp->data) {
459     /* destroy the old private KSP context */
460     ierr = (*ksp->ops->destroy)(ksp);CHKERRQ(ierr);
461     ksp->data = 0;
462   }
463   /* Get the function pointers for the iterative method requested */
464   if (!KSPRegisterAllCalled) {ierr = KSPRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
465   ierr =  PetscFListFind(ksp->comm,KSPList,type,(void (**)(void)) &r);CHKERRQ(ierr);
466   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown KSP type given: %s",type);
467   ksp->setupcalled = 0;
468   ierr = (*r)(ksp);CHKERRQ(ierr);
469   ierr = PetscObjectChangeTypeName((PetscObject)ksp,type);CHKERRQ(ierr);
470   PetscFunctionReturn(0);
471 }
472 
473 #undef __FUNCT__
474 #define __FUNCT__ "KSPRegisterDestroy"
475 /*@
476    KSPRegisterDestroy - Frees the list of KSP methods that were
477    registered by KSPRegisterDynamic().
478 
479    Not Collective
480 
481    Level: advanced
482 
483 .keywords: KSP, register, destroy
484 
485 .seealso: KSPRegisterDynamic(), KSPRegisterAll()
486 @*/
487 PetscErrorCode PETSCKSP_DLLEXPORT KSPRegisterDestroy(void)
488 {
489   PetscErrorCode ierr;
490 
491   PetscFunctionBegin;
492   if (KSPList) {
493     ierr = PetscFListDestroy(&KSPList);CHKERRQ(ierr);
494     KSPList = 0;
495   }
496   KSPRegisterAllCalled = PETSC_FALSE;
497   PetscFunctionReturn(0);
498 }
499 
500 #undef __FUNCT__
501 #define __FUNCT__ "KSPGetType"
502 /*@C
503    KSPGetType - Gets the KSP type as a string from the KSP object.
504 
505    Not Collective
506 
507    Input Parameter:
508 .  ksp - Krylov context
509 
510    Output Parameter:
511 .  name - name of KSP method
512 
513    Level: intermediate
514 
515 .keywords: KSP, get, method, name
516 
517 .seealso: KSPSetType()
518 @*/
519 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetType(KSP ksp,KSPType *type)
520 {
521   PetscFunctionBegin;
522   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
523   PetscValidPointer(type,2);
524   *type = ksp->type_name;
525   PetscFunctionReturn(0);
526 }
527 
528 #undef __FUNCT__
529 #define __FUNCT__ "KSPRegister"
530 /*@C
531   KSPRegister - See KSPRegisterDynamic()
532 
533   Level: advanced
534 @*/
535 PetscErrorCode PETSCKSP_DLLEXPORT KSPRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(KSP))
536 {
537   PetscErrorCode ierr;
538   char           fullname[PETSC_MAX_PATH_LEN];
539 
540   PetscFunctionBegin;
541   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
542   ierr = PetscFListAdd(&KSPList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
543   PetscFunctionReturn(0);
544 }
545 
546 #undef __FUNCT__
547 #define __FUNCT__ "KSPSetNullSpace"
548 /*@
549   KSPSetNullSpace - Sets the null space of the operator
550 
551   Collective on KSP
552 
553   Input Parameters:
554 +  ksp - the Krylov space object
555 -  nullsp - the null space of the operator
556 
557   Level: advanced
558 
559 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPGetNullSpace()
560 @*/
561 PetscErrorCode PETSCKSP_DLLEXPORT KSPSetNullSpace(KSP ksp,MatNullSpace nullsp)
562 {
563   PetscErrorCode ierr;
564 
565   PetscFunctionBegin;
566   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
567   if (ksp->nullsp) { ierr = MatNullSpaceDestroy(ksp->nullsp);CHKERRQ(ierr); }
568   ksp->nullsp = nullsp;
569   PetscFunctionReturn(0);
570 }
571 
572 #undef __FUNCT__
573 #define __FUNCT__ "KSPGetNullSpace"
574 /*@
575   KSPGetNullSpace - Gets the null space of the operator
576 
577   Collective on KSP
578 
579   Input Parameters:
580 +  ksp - the Krylov space object
581 -  nullsp - the null space of the operator
582 
583   Level: advanced
584 
585 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPSetNullSpace()
586 @*/
587 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetNullSpace(KSP ksp,MatNullSpace *nullsp)
588 {
589   PetscFunctionBegin;
590   *nullsp = ksp->nullsp;
591   PetscFunctionReturn(0);
592 }
593 
594