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