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