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