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