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