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