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