xref: /petsc/src/ksp/ksp/interface/itcreate.c (revision 56a740aa71ca6bf86587d8f0542c8a1991cb5f80)
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__ "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   *inksp             = ksp;
388   ksp->bops->publish = KSPPublish_Petsc;
389 
390   ksp->type          = -1;
391   ksp->max_it        = 10000;
392   ksp->pc_side       = PC_LEFT;
393   ksp->rtol          = 1.e-5;
394   ksp->abstol          = 1.e-50;
395   ksp->divtol        = 1.e4;
396 
397   ksp->normtype            = KSP_PRECONDITIONED_NORM;
398   ksp->rnorm               = 0.0;
399   ksp->its                 = 0;
400   ksp->guess_zero          = PETSC_TRUE;
401   ksp->calc_sings          = PETSC_FALSE;
402   ksp->res_hist            = 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   ksp->converged           = KSPDefaultConverged;
408   ksp->ops->buildsolution  = KSPDefaultBuildSolution;
409   ksp->ops->buildresidual  = KSPDefaultBuildResidual;
410 
411   ksp->ops->setfromoptions = 0;
412 
413   ksp->vec_sol         = 0;
414   ksp->vec_rhs         = 0;
415   ksp->pc              = 0;
416 
417   ksp->ops->solve      = 0;
418   ksp->ops->setup      = 0;
419   ksp->ops->destroy    = 0;
420 
421   ksp->data            = 0;
422   ksp->nwork           = 0;
423   ksp->work            = 0;
424 
425   ksp->cnvP            = 0;
426 
427   ksp->reason          = KSP_CONVERGED_ITERATING;
428 
429   ksp->setupcalled     = 0;
430   ierr = PetscPublishAll(ksp);CHKERRQ(ierr);
431   ierr = PCCreate(comm,&ksp->pc);CHKERRQ(ierr);
432   PetscFunctionReturn(0);
433 }
434 
435 #undef __FUNCT__
436 #define __FUNCT__ "KSPSetType"
437 /*@C
438    KSPSetType - Builds KSP for a particular solver.
439 
440    Collective on KSP
441 
442    Input Parameters:
443 +  ksp      - the Krylov space context
444 -  type - a known method
445 
446    Options Database Key:
447 .  -ksp_type  <method> - Sets the method; use -help for a list
448     of available methods (for instance, cg or gmres)
449 
450    Notes:
451    See "petsc/include/petscksp.h" for available methods (for instance,
452    KSPCG or KSPGMRES).
453 
454   Normally, it is best to use the KSPSetFromOptions() command and
455   then set the KSP type from the options database rather than by using
456   this routine.  Using the options database provides the user with
457   maximum flexibility in evaluating the many different Krylov methods.
458   The KSPSetType() routine is provided for those situations where it
459   is necessary to set the iterative solver independently of the command
460   line or options database.  This might be the case, for example, when
461   the choice of iterative solver changes during the execution of the
462   program, and the user's application is taking responsibility for
463   choosing the appropriate method.  In other words, this routine is
464   not for beginners.
465 
466   Level: intermediate
467 
468 .keywords: KSP, set, method
469 
470 .seealso: PCSetType(), KSPType
471 
472 @*/
473 PetscErrorCode PETSCKSP_DLLEXPORT KSPSetType(KSP ksp, KSPType type)
474 {
475   PetscErrorCode ierr,(*r)(KSP);
476   PetscTruth     match;
477 
478   PetscFunctionBegin;
479   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
480   PetscValidCharPointer(type,2);
481 
482   ierr = PetscTypeCompare((PetscObject)ksp,type,&match);CHKERRQ(ierr);
483   if (match) PetscFunctionReturn(0);
484 
485   if (ksp->data) {
486     /* destroy the old private KSP context */
487     ierr = (*ksp->ops->destroy)(ksp);CHKERRQ(ierr);
488     ksp->data = 0;
489   }
490   /* Get the function pointers for the iterative method requested */
491   if (!KSPRegisterAllCalled) {ierr = KSPRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
492   ierr =  PetscFListFind(ksp->comm,KSPList,type,(void (**)(void)) &r);CHKERRQ(ierr);
493   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown KSP type given: %s",type);
494   ksp->setupcalled = 0;
495   ierr = (*r)(ksp);CHKERRQ(ierr);
496   ierr = PetscObjectChangeTypeName((PetscObject)ksp,type);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 #undef __FUNCT__
501 #define __FUNCT__ "KSPRegisterDestroy"
502 /*@
503    KSPRegisterDestroy - Frees the list of KSP methods that were
504    registered by KSPRegisterDynamic().
505 
506    Not Collective
507 
508    Level: advanced
509 
510 .keywords: KSP, register, destroy
511 
512 .seealso: KSPRegisterDynamic(), KSPRegisterAll()
513 @*/
514 PetscErrorCode PETSCKSP_DLLEXPORT KSPRegisterDestroy(void)
515 {
516   PetscErrorCode ierr;
517 
518   PetscFunctionBegin;
519   if (KSPList) {
520     ierr = PetscFListDestroy(&KSPList);CHKERRQ(ierr);
521     KSPList = 0;
522   }
523   KSPRegisterAllCalled = PETSC_FALSE;
524   PetscFunctionReturn(0);
525 }
526 
527 #undef __FUNCT__
528 #define __FUNCT__ "KSPGetType"
529 /*@C
530    KSPGetType - Gets the KSP type as a string from the KSP object.
531 
532    Not Collective
533 
534    Input Parameter:
535 .  ksp - Krylov context
536 
537    Output Parameter:
538 .  name - name of KSP method
539 
540    Level: intermediate
541 
542 .keywords: KSP, get, method, name
543 
544 .seealso: KSPSetType()
545 @*/
546 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetType(KSP ksp,KSPType *type)
547 {
548   PetscFunctionBegin;
549   PetscValidHeaderSpecific(ksp,KSP_COOKIE,1);
550   PetscValidPointer(type,2);
551   *type = ksp->type_name;
552   PetscFunctionReturn(0);
553 }
554 
555 #undef __FUNCT__
556 #define __FUNCT__ "KSPRegister"
557 /*@C
558   KSPRegister - See KSPRegisterDynamic()
559 
560   Level: advanced
561 @*/
562 PetscErrorCode PETSCKSP_DLLEXPORT KSPRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(KSP))
563 {
564   PetscErrorCode ierr;
565   char           fullname[PETSC_MAX_PATH_LEN];
566 
567   PetscFunctionBegin;
568   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
569   ierr = PetscFListAdd(&KSPList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
570   PetscFunctionReturn(0);
571 }
572 
573 #undef __FUNCT__
574 #define __FUNCT__ "KSPSetNullSpace"
575 /*@
576   KSPSetNullSpace - Sets the null space of the operator
577 
578   Collective on KSP
579 
580   Input Parameters:
581 +  ksp - the Krylov space object
582 -  nullsp - the null space of the operator
583 
584   Level: advanced
585 
586 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPGetNullSpace()
587 @*/
588 PetscErrorCode PETSCKSP_DLLEXPORT KSPSetNullSpace(KSP ksp,MatNullSpace nullsp)
589 {
590   PetscErrorCode ierr;
591 
592   PetscFunctionBegin;
593   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
594   if (ksp->nullsp) { ierr = MatNullSpaceDestroy(ksp->nullsp);CHKERRQ(ierr); }
595   ksp->nullsp = nullsp;
596   PetscFunctionReturn(0);
597 }
598 
599 #undef __FUNCT__
600 #define __FUNCT__ "KSPGetNullSpace"
601 /*@
602   KSPGetNullSpace - Gets the null space of the operator
603 
604   Collective on KSP
605 
606   Input Parameters:
607 +  ksp - the Krylov space object
608 -  nullsp - the null space of the operator
609 
610   Level: advanced
611 
612 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPSetNullSpace()
613 @*/
614 PetscErrorCode PETSCKSP_DLLEXPORT KSPGetNullSpace(KSP ksp,MatNullSpace *nullsp)
615 {
616   PetscFunctionBegin;
617   *nullsp = ksp->nullsp;
618   PetscFunctionReturn(0);
619 }
620 
621