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 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 471 Notes: 472 473 All future calls to KSPSetOperators() must use the same size matrices! 474 475 Passing a NULL for Amat or Pmat removes the matrix that is currently used. 476 477 If you wish to replace either Amat or Pmat but leave the other one untouched then 478 first call KSPGetOperators() to get the one you wish to keep, call PetscObjectReference() 479 on it and then pass it back in in your call to KSPSetOperators(). 480 481 Level: beginner 482 483 Alternative usage: If the operators have NOT been set with KSP/PCSetOperators() then the operators 484 are created in PC and returned to the user. In this case, if both operators 485 mat and pmat are requested, two DIFFERENT operators will be returned. If 486 only one is requested both operators in the PC will be the same (i.e. as 487 if one had called KSP/PCSetOperators() with the same argument for both Mats). 488 The user must set the sizes of the returned matrices and their type etc just 489 as if the user created them with MatCreate(). For example, 490 491 $ KSP/PCGetOperators(ksp/pc,&mat,NULL); is equivalent to 492 $ set size, type, etc of mat 493 494 $ MatCreate(comm,&mat); 495 $ KSP/PCSetOperators(ksp/pc,mat,mat); 496 $ PetscObjectDereference((PetscObject)mat); 497 $ set size, type, etc of mat 498 499 and 500 501 $ KSP/PCGetOperators(ksp/pc,&mat,&pmat); is equivalent to 502 $ set size, type, etc of mat and pmat 503 504 $ MatCreate(comm,&mat); 505 $ MatCreate(comm,&pmat); 506 $ KSP/PCSetOperators(ksp/pc,mat,pmat); 507 $ PetscObjectDereference((PetscObject)mat); 508 $ PetscObjectDereference((PetscObject)pmat); 509 $ set size, type, etc of mat and pmat 510 511 The rational for this support is so that when creating a TS, SNES, or KSP the hierarchy 512 of underlying objects (i.e. SNES, KSP, PC, Mat) and their livespans can be completely 513 managed by the top most level object (i.e. the TS, SNES, or KSP). Another way to look 514 at this is when you create a SNES you do not NEED to create a KSP and attach it to 515 the SNES object (the SNES object manages it for you). Similarly when you create a KSP 516 you do not need to attach a PC to it (the KSP object manages the PC object for you). 517 Thus, why should YOU have to create the Mat and attach it to the SNES/KSP/PC, when 518 it can be created for you? 519 520 .keywords: KSP, set, operators, matrix, preconditioner, linear system 521 522 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPGetOperators() 523 @*/ 524 PetscErrorCode KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat) 525 { 526 MatNullSpace nullsp; 527 PetscErrorCode ierr; 528 529 PetscFunctionBegin; 530 PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); 531 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 532 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 533 if (Amat) PetscCheckSameComm(ksp,1,Amat,2); 534 if (Pmat) PetscCheckSameComm(ksp,1,Pmat,3); 535 if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} 536 ierr = PCSetOperators(ksp->pc,Amat,Pmat);CHKERRQ(ierr); 537 if (ksp->setupstage == KSP_SETUP_NEWRHS) ksp->setupstage = KSP_SETUP_NEWMATRIX; /* so that next solve call will call PCSetUp() on new matrix */ 538 if (ksp->guess) { 539 ierr = KSPFischerGuessReset(ksp->guess);CHKERRQ(ierr); 540 } 541 if (Pmat) { 542 ierr = MatGetNullSpace(Pmat, &nullsp);CHKERRQ(ierr); 543 if (nullsp) { 544 ierr = KSPSetNullSpace(ksp, nullsp);CHKERRQ(ierr); 545 } 546 } 547 PetscFunctionReturn(0); 548 } 549 550 #undef __FUNCT__ 551 #define __FUNCT__ "KSPGetOperators" 552 /*@ 553 KSPGetOperators - Gets the matrix associated with the linear system 554 and a (possibly) different one associated with the preconditioner. 555 556 Collective on KSP and Mat 557 558 Input Parameter: 559 . ksp - the KSP context 560 561 Output Parameters: 562 + Amat - the matrix that defines the linear system 563 - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 564 565 Level: intermediate 566 567 Notes: DOES NOT increase the reference counts of the matrix, so you should NOT destroy them. 568 569 .keywords: KSP, set, get, operators, matrix, preconditioner, linear system 570 571 .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPSetOperators(), KSPGetOperatorsSet() 572 @*/ 573 PetscErrorCode KSPGetOperators(KSP ksp,Mat *Amat,Mat *Pmat) 574 { 575 PetscErrorCode ierr; 576 577 PetscFunctionBegin; 578 PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); 579 if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} 580 ierr = PCGetOperators(ksp->pc,Amat,Pmat);CHKERRQ(ierr); 581 PetscFunctionReturn(0); 582 } 583 584 #undef __FUNCT__ 585 #define __FUNCT__ "KSPGetOperatorsSet" 586 /*@C 587 KSPGetOperatorsSet - Determines if the matrix associated with the linear system and 588 possibly a different one associated with the preconditioner have been set in the KSP. 589 590 Not collective, though the results on all processes should be the same 591 592 Input Parameter: 593 . pc - the KSP context 594 595 Output Parameters: 596 + mat - the matrix associated with the linear system was set 597 - pmat - matrix associated with the preconditioner was set, usually the same 598 599 Level: intermediate 600 601 .keywords: KSP, get, operators, matrix, linear system 602 603 .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperators(), PCGetOperatorsSet() 604 @*/ 605 PetscErrorCode KSPGetOperatorsSet(KSP ksp,PetscBool *mat,PetscBool *pmat) 606 { 607 PetscErrorCode ierr; 608 609 PetscFunctionBegin; 610 PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); 611 if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} 612 ierr = PCGetOperatorsSet(ksp->pc,mat,pmat);CHKERRQ(ierr); 613 PetscFunctionReturn(0); 614 } 615 616 #undef __FUNCT__ 617 #define __FUNCT__ "KSPSetPreSolve" 618 /*@C 619 KSPSetPreSolve - Sets a function that is called before every KSPSolve() is started 620 621 Logically Collective on KSP 622 623 Input Parameters: 624 + ksp - the solver object 625 . presolve - the function to call before the solve 626 - prectx - any context needed by the function 627 628 Level: developer 629 630 .keywords: KSP, create, context 631 632 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP, KSPSetPostSolve() 633 @*/ 634 PetscErrorCode KSPSetPreSolve(KSP ksp,PetscErrorCode (*presolve)(KSP,Vec,Vec,void*),void *prectx) 635 { 636 PetscFunctionBegin; 637 PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); 638 ksp->presolve = presolve; 639 ksp->prectx = prectx; 640 PetscFunctionReturn(0); 641 } 642 643 #undef __FUNCT__ 644 #define __FUNCT__ "KSPSetPostSolve" 645 /*@C 646 KSPSetPostSolve - Sets a function that is called after every KSPSolve() completes (whether it converges or not) 647 648 Logically Collective on KSP 649 650 Input Parameters: 651 + ksp - the solver object 652 . postsolve - the function to call after the solve 653 - postctx - any context needed by the function 654 655 Level: developer 656 657 .keywords: KSP, create, context 658 659 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP, KSPSetPreSolve() 660 @*/ 661 PetscErrorCode KSPSetPostSolve(KSP ksp,PetscErrorCode (*postsolve)(KSP,Vec,Vec,void*),void *postctx) 662 { 663 PetscFunctionBegin; 664 PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); 665 ksp->postsolve = postsolve; 666 ksp->postctx = postctx; 667 PetscFunctionReturn(0); 668 } 669 670 #undef __FUNCT__ 671 #define __FUNCT__ "KSPCreate" 672 /*@ 673 KSPCreate - Creates the default KSP context. 674 675 Collective on MPI_Comm 676 677 Input Parameter: 678 . comm - MPI communicator 679 680 Output Parameter: 681 . ksp - location to put the KSP context 682 683 Notes: 684 The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt 685 orthogonalization. 686 687 Level: beginner 688 689 .keywords: KSP, create, context 690 691 .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP 692 @*/ 693 PetscErrorCode KSPCreate(MPI_Comm comm,KSP *inksp) 694 { 695 KSP ksp; 696 PetscErrorCode ierr; 697 void *ctx; 698 699 PetscFunctionBegin; 700 PetscValidPointer(inksp,2); 701 *inksp = 0; 702 ierr = KSPInitializePackage();CHKERRQ(ierr); 703 704 ierr = PetscHeaderCreate(ksp,_p_KSP,struct _KSPOps,KSP_CLASSID,"KSP","Krylov Method","KSP",comm,KSPDestroy,KSPView);CHKERRQ(ierr); 705 706 ksp->max_it = 10000; 707 ksp->pc_side = PC_SIDE_DEFAULT; 708 ksp->rtol = 1.e-5; 709 #if defined(PETSC_USE_REAL_SINGLE) 710 ksp->abstol = 1.e-25; 711 #else 712 ksp->abstol = 1.e-50; 713 #endif 714 ksp->divtol = 1.e4; 715 716 ksp->chknorm = -1; 717 ksp->normtype = KSP_NORM_DEFAULT; 718 ksp->rnorm = 0.0; 719 ksp->its = 0; 720 ksp->guess_zero = PETSC_TRUE; 721 ksp->calc_sings = PETSC_FALSE; 722 ksp->res_hist = NULL; 723 ksp->res_hist_alloc = NULL; 724 ksp->res_hist_len = 0; 725 ksp->res_hist_max = 0; 726 ksp->res_hist_reset = PETSC_TRUE; 727 ksp->numbermonitors = 0; 728 729 ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr); 730 ierr = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr); 731 ksp->ops->buildsolution = KSPBuildSolutionDefault; 732 ksp->ops->buildresidual = KSPBuildResidualDefault; 733 734 ksp->vec_sol = 0; 735 ksp->vec_rhs = 0; 736 ksp->pc = 0; 737 ksp->data = 0; 738 ksp->nwork = 0; 739 ksp->work = 0; 740 ksp->reason = KSP_CONVERGED_ITERATING; 741 ksp->setupstage = KSP_SETUP_NEW; 742 743 ierr = KSPNormSupportTableReset_Private(ksp);CHKERRQ(ierr); 744 745 *inksp = ksp; 746 PetscFunctionReturn(0); 747 } 748 749 #undef __FUNCT__ 750 #define __FUNCT__ "KSPSetType" 751 /*@C 752 KSPSetType - Builds KSP for a particular solver. 753 754 Logically Collective on KSP 755 756 Input Parameters: 757 + ksp - the Krylov space context 758 - type - a known method 759 760 Options Database Key: 761 . -ksp_type <method> - Sets the method; use -help for a list 762 of available methods (for instance, cg or gmres) 763 764 Notes: 765 See "petsc/include/petscksp.h" for available methods (for instance, 766 KSPCG or KSPGMRES). 767 768 Normally, it is best to use the KSPSetFromOptions() command and 769 then set the KSP type from the options database rather than by using 770 this routine. Using the options database provides the user with 771 maximum flexibility in evaluating the many different Krylov methods. 772 The KSPSetType() routine is provided for those situations where it 773 is necessary to set the iterative solver independently of the command 774 line or options database. This might be the case, for example, when 775 the choice of iterative solver changes during the execution of the 776 program, and the user's application is taking responsibility for 777 choosing the appropriate method. In other words, this routine is 778 not for beginners. 779 780 Level: intermediate 781 782 Developer Note: KSPRegister() is used to add Krylov types to KSPList from which they 783 are accessed by KSPSetType(). 784 785 .keywords: KSP, set, method 786 787 .seealso: PCSetType(), KSPType, KSPRegister(), KSPCreate() 788 789 @*/ 790 PetscErrorCode KSPSetType(KSP ksp, KSPType type) 791 { 792 PetscErrorCode ierr,(*r)(KSP); 793 PetscBool match; 794 795 PetscFunctionBegin; 796 PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); 797 PetscValidCharPointer(type,2); 798 799 ierr = PetscObjectTypeCompare((PetscObject)ksp,type,&match);CHKERRQ(ierr); 800 if (match) PetscFunctionReturn(0); 801 802 ierr = PetscFunctionListFind(KSPList,type,&r);CHKERRQ(ierr); 803 if (!r) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested KSP type %s",type); 804 /* Destroy the previous private KSP context */ 805 if (ksp->ops->destroy) { 806 ierr = (*ksp->ops->destroy)(ksp);CHKERRQ(ierr); 807 ksp->ops->destroy = NULL; 808 } 809 /* Reinitialize function pointers in KSPOps structure */ 810 ierr = PetscMemzero(ksp->ops,sizeof(struct _KSPOps));CHKERRQ(ierr); 811 ksp->ops->buildsolution = KSPBuildSolutionDefault; 812 ksp->ops->buildresidual = KSPBuildResidualDefault; 813 ierr = KSPNormSupportTableReset_Private(ksp);CHKERRQ(ierr); 814 /* Call the KSPCreate_XXX routine for this particular Krylov solver */ 815 ksp->setupstage = KSP_SETUP_NEW; 816 ierr = PetscObjectChangeTypeName((PetscObject)ksp,type);CHKERRQ(ierr); 817 ierr = (*r)(ksp);CHKERRQ(ierr); 818 PetscFunctionReturn(0); 819 } 820 821 #undef __FUNCT__ 822 #define __FUNCT__ "KSPGetType" 823 /*@C 824 KSPGetType - Gets the KSP type as a string from the KSP object. 825 826 Not Collective 827 828 Input Parameter: 829 . ksp - Krylov context 830 831 Output Parameter: 832 . name - name of KSP method 833 834 Level: intermediate 835 836 .keywords: KSP, get, method, name 837 838 .seealso: KSPSetType() 839 @*/ 840 PetscErrorCode KSPGetType(KSP ksp,KSPType *type) 841 { 842 PetscFunctionBegin; 843 PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); 844 PetscValidPointer(type,2); 845 *type = ((PetscObject)ksp)->type_name; 846 PetscFunctionReturn(0); 847 } 848 849 #undef __FUNCT__ 850 #define __FUNCT__ "KSPRegister" 851 /*@C 852 KSPRegister - Adds a method to the Krylov subspace solver package. 853 854 Not Collective 855 856 Input Parameters: 857 + name_solver - name of a new user-defined solver 858 - routine_create - routine to create method context 859 860 Notes: 861 KSPRegister() may be called multiple times to add several user-defined solvers. 862 863 Sample usage: 864 .vb 865 KSPRegister("my_solver",MySolverCreate); 866 .ve 867 868 Then, your solver can be chosen with the procedural interface via 869 $ KSPSetType(ksp,"my_solver") 870 or at runtime via the option 871 $ -ksp_type my_solver 872 873 Level: advanced 874 875 .keywords: KSP, register 876 877 .seealso: KSPRegisterAll(), KSPRegisterDestroy() 878 879 @*/ 880 PetscErrorCode KSPRegister(const char sname[],PetscErrorCode (*function)(KSP)) 881 { 882 PetscErrorCode ierr; 883 884 PetscFunctionBegin; 885 ierr = PetscFunctionListAdd(&KSPList,sname,function);CHKERRQ(ierr); 886 PetscFunctionReturn(0); 887 } 888 889 #undef __FUNCT__ 890 #define __FUNCT__ "KSPSetNullSpace" 891 /*@ 892 KSPSetNullSpace - Sets the null space of the operator 893 894 Logically Collective on KSP 895 896 Input Parameters: 897 + ksp - the Krylov space object 898 - nullsp - the null space of the operator 899 900 Notes: If the Mat provided to KSP has a nullspace added to it with MatSetNullSpace() then 901 KSP will automatically use the MatNullSpace and you don't need to call KSPSetNullSpace(). 902 903 Level: advanced 904 905 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPGetNullSpace(), MatSetNullSpace() 906 @*/ 907 PetscErrorCode KSPSetNullSpace(KSP ksp,MatNullSpace nullsp) 908 { 909 PetscErrorCode ierr; 910 911 PetscFunctionBegin; 912 PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); 913 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 914 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 915 if (ksp->nullsp) { ierr = MatNullSpaceDestroy(&ksp->nullsp);CHKERRQ(ierr); } 916 ksp->nullsp = nullsp; 917 PetscFunctionReturn(0); 918 } 919 920 #undef __FUNCT__ 921 #define __FUNCT__ "KSPGetNullSpace" 922 /*@ 923 KSPGetNullSpace - Gets the null space of the operator 924 925 Not Collective 926 927 Input Parameters: 928 + ksp - the Krylov space object 929 - nullsp - the null space of the operator 930 931 Level: advanced 932 933 .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPSetNullSpace() 934 @*/ 935 PetscErrorCode KSPGetNullSpace(KSP ksp,MatNullSpace *nullsp) 936 { 937 PetscFunctionBegin; 938 PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); 939 PetscValidPointer(nullsp,2); 940 *nullsp = ksp->nullsp; 941 PetscFunctionReturn(0); 942 } 943 944