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