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