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