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