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