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