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; 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(0); 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 Keys: 80 . -ksp_view - print the `KSP` data structure at the end of each `KSPSolve()` call 81 82 Notes: 83 The available visualization contexts include 84 + `PETSC_VIEWER_STDOUT_SELF` - standard output (default) 85 - `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard 86 output where only the first processor opens 87 the file. All other processors send their 88 data to the first processor to print. 89 90 The available formats include 91 + `PETSC_VIEWER_DEFAULT` - standard output (default) 92 - `PETSC_VIEWER_ASCII_INFO_DETAIL` - more verbose output for PCBJACOBI and PCASM 93 94 The user can open an alternative visualization context with 95 `PetscViewerASCIIOpen()` - output to a specified file. 96 97 In the debugger you can do call `KSPView(ksp,0)` to display the `KSP`. (The same holds for any PETSc object viewer). 98 99 Level: beginner 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->guess_knoll) PetscCall(PetscViewerASCIIPrintf(viewer, " using preconditioner applied to right hand side for initial guess\n")); 134 PetscCall(PetscViewerASCIIPrintf(viewer, " tolerances: relative=%g, absolute=%g, divergence=%g\n", (double)ksp->rtol, (double)ksp->abstol, (double)ksp->divtol)); 135 if (ksp->pc_side == PC_RIGHT) { 136 PetscCall(PetscViewerASCIIPrintf(viewer, " right preconditioning\n")); 137 } else if (ksp->pc_side == PC_SYMMETRIC) { 138 PetscCall(PetscViewerASCIIPrintf(viewer, " symmetric preconditioning\n")); 139 } else { 140 PetscCall(PetscViewerASCIIPrintf(viewer, " left preconditioning\n")); 141 } 142 if (ksp->guess) { 143 PetscCall(PetscViewerASCIIPushTab(viewer)); 144 PetscCall(KSPGuessView(ksp->guess, viewer)); 145 PetscCall(PetscViewerASCIIPopTab(viewer)); 146 } 147 if (ksp->dscale) PetscCall(PetscViewerASCIIPrintf(viewer, " diagonally scaled system\n")); 148 PetscCall(PetscViewerASCIIPrintf(viewer, " using %s norm type for convergence test\n", KSPNormTypes[ksp->normtype])); 149 } else if (isbinary) { 150 PetscInt classid = KSP_FILE_CLASSID; 151 MPI_Comm comm; 152 PetscMPIInt rank; 153 char type[256]; 154 155 PetscCall(PetscObjectGetComm((PetscObject)ksp, &comm)); 156 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 157 if (rank == 0) { 158 PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT)); 159 PetscCall(PetscStrncpy(type, ((PetscObject)ksp)->type_name, 256)); 160 PetscCall(PetscViewerBinaryWrite(viewer, type, 256, PETSC_CHAR)); 161 } 162 PetscTryTypeMethod(ksp, view, viewer); 163 } else if (isstring) { 164 const char *type; 165 PetscCall(KSPGetType(ksp, &type)); 166 PetscCall(PetscViewerStringSPrintf(viewer, " KSPType: %-7.7s", type)); 167 PetscTryTypeMethod(ksp, view, viewer); 168 } else if (isdraw) { 169 PetscDraw draw; 170 char str[36]; 171 PetscReal x, y, bottom, h; 172 PetscBool flg; 173 174 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 175 PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y)); 176 PetscCall(PetscObjectTypeCompare((PetscObject)ksp, KSPPREONLY, &flg)); 177 if (!flg) { 178 PetscCall(PetscStrncpy(str, "KSP: ", sizeof(str))); 179 PetscCall(PetscStrlcat(str, ((PetscObject)ksp)->type_name, sizeof(str))); 180 PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_RED, PETSC_DRAW_BLACK, str, NULL, &h)); 181 bottom = y - h; 182 } else { 183 bottom = y; 184 } 185 PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom)); 186 #if defined(PETSC_HAVE_SAWS) 187 } else if (issaws) { 188 PetscMPIInt rank; 189 const char *name; 190 191 PetscCall(PetscObjectGetName((PetscObject)ksp, &name)); 192 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 193 if (!((PetscObject)ksp)->amsmem && rank == 0) { 194 char dir[1024]; 195 196 PetscCall(PetscObjectViewSAWs((PetscObject)ksp, viewer)); 197 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/its", name)); 198 PetscCallSAWs(SAWs_Register, (dir, &ksp->its, 1, SAWs_READ, SAWs_INT)); 199 if (!ksp->res_hist) PetscCall(KSPSetResidualHistory(ksp, NULL, PETSC_DECIDE, PETSC_TRUE)); 200 PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/res_hist", name)); 201 PetscCallSAWs(SAWs_Register, (dir, ksp->res_hist, 10, SAWs_READ, SAWs_DOUBLE)); 202 } 203 #endif 204 } else PetscTryTypeMethod(ksp, view, viewer); 205 if (ksp->pc) PetscCall(PCView(ksp->pc, viewer)); 206 if (isdraw) { 207 PetscDraw draw; 208 PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 209 PetscCall(PetscDrawPopCurrentPoint(draw)); 210 } 211 PetscFunctionReturn(0); 212 } 213 214 /*@C 215 KSPViewFromOptions - View a `KSP` object based on values in the options database 216 217 Collective 218 219 Input Parameters: 220 + A - Krylov solver context 221 . obj - Optional object 222 - name - command line option 223 224 Level: intermediate 225 226 .seealso: `KSP`, `KSPView`, `PetscObjectViewFromOptions()`, `KSPCreate()` 227 @*/ 228 PetscErrorCode KSPViewFromOptions(KSP A, PetscObject obj, const char name[]) 229 { 230 PetscFunctionBegin; 231 PetscValidHeaderSpecific(A, KSP_CLASSID, 1); 232 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 233 PetscFunctionReturn(0); 234 } 235 236 /*@ 237 KSPSetNormType - Sets the norm that is used for convergence testing. 238 239 Logically Collective 240 241 Input Parameters: 242 + ksp - Krylov solver context 243 - normtype - one of 244 .vb 245 KSP_NORM_NONE - skips computing the norm, this should generally only be used if you are using 246 the Krylov method as a smoother with a fixed small number of iterations. 247 Implicitly sets KSPConvergedSkip() as KSP convergence test. 248 Note that certain algorithms such as KSPGMRES ALWAYS require the norm calculation, 249 for these methods the norms are still computed, they are just not used in 250 the convergence test. 251 KSP_NORM_PRECONDITIONED - the default for left preconditioned solves, uses the l2 norm 252 of the preconditioned residual P^{-1}(b - A x) 253 KSP_NORM_UNPRECONDITIONED - uses the l2 norm of the true b - Ax residual. 254 KSP_NORM_NATURAL - supported by KSPCG, KSPCR, KSPCGNE, KSPCGS 255 .ve 256 257 Options Database Key: 258 . -ksp_norm_type <none,preconditioned,unpreconditioned,natural> - set `KSP` norm type 259 260 Level: advanced 261 262 Note: 263 Not all combinations of preconditioner side (see `KSPSetPCSide()`) and norm type are supported by all Krylov methods. 264 If only one is set, PETSc tries to automatically change the other to find a compatible pair. If no such combination 265 is supported, PETSc will generate an error. 266 267 Developer Note: 268 Supported combinations of norm and preconditioner side are set using `KSPSetSupportedNorm()`. 269 270 .seealso: `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSPConvergedSkip()`, `KSPSetCheckNormIteration()`, `KSPSetPCSide()`, `KSPGetPCSide()`, `KSPNormType` 271 @*/ 272 PetscErrorCode KSPSetNormType(KSP ksp, KSPNormType normtype) 273 { 274 PetscFunctionBegin; 275 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); 276 PetscValidLogicalCollectiveEnum(ksp, normtype, 2); 277 ksp->normtype = ksp->normtype_set = normtype; 278 PetscFunctionReturn(0); 279 } 280 281 /*@ 282 KSPSetCheckNormIteration - Sets the first iteration at which the norm of the residual will be 283 computed and used in the convergence test. 284 285 Logically Collective 286 287 Input Parameters: 288 + ksp - Krylov solver context 289 - it - use -1 to check at all iterations 290 291 Notes: 292 Currently only works with `KSPCG`, `KSPBCGS` and `KSPIBCGS` 293 294 Use `KSPSetNormType`(ksp,`KSP_NORM_NONE`) to never check the norm 295 296 On steps where the norm is not computed, the previous norm is still in the variable, so if you run with, for example, 297 -ksp_monitor the residual norm will appear to be unchanged for several iterations (though it is not really unchanged). 298 Level: advanced 299 300 .seealso: `KSP`, `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSPConvergedSkip()`, `KSPSetNormType()` 301 @*/ 302 PetscErrorCode KSPSetCheckNormIteration(KSP ksp, PetscInt it) 303 { 304 PetscFunctionBegin; 305 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); 306 PetscValidLogicalCollectiveInt(ksp, it, 2); 307 ksp->chknorm = it; 308 PetscFunctionReturn(0); 309 } 310 311 /*@ 312 KSPSetLagNorm - Lags the residual norm calculation so that it is computed as part of the `MPI_Allreduce()` for 313 computing the inner products for the next iteration. This can reduce communication costs at the expense of doing 314 one additional iteration. 315 316 Logically Collective 317 318 Input Parameters: 319 + ksp - Krylov solver context 320 - flg - `PETSC_TRUE` or `PETSC_FALSE` 321 322 Options Database Keys: 323 . -ksp_lag_norm - lag the calculated residual norm 324 325 Level: advanced 326 327 Notes: 328 Currently only works with `KSPIBCGS`. 329 330 Use `KSPSetNormType`(ksp,`KSP_NORM_NONE`) to never check the norm 331 332 If you lag the norm and run with, for example, -ksp_monitor, the residual norm reported will be the lagged one. 333 334 .seealso: `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSPConvergedSkip()`, `KSPSetNormType()`, `KSPSetCheckNormIteration()` 335 @*/ 336 PetscErrorCode KSPSetLagNorm(KSP ksp, PetscBool flg) 337 { 338 PetscFunctionBegin; 339 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); 340 PetscValidLogicalCollectiveBool(ksp, flg, 2); 341 ksp->lagnorm = flg; 342 PetscFunctionReturn(0); 343 } 344 345 /*@ 346 KSPSetSupportedNorm - Sets a norm and preconditioner side supported by a `KSP` 347 348 Logically Collective 349 350 Input Parameters: 351 + ksp - Krylov method 352 . normtype - supported norm type 353 . pcside - preconditioner side that can be used with this norm 354 - priority - positive integer preference for this combination; larger values have higher priority 355 356 Level: developer 357 358 Note: 359 This function should be called from the implementation files `KSPCreate_XXX()` to declare 360 which norms and preconditioner sides are supported. Users should not need to call this 361 function. 362 363 .seealso: `KSP`, `KSPNormType`, `PCSide`, `KSPSetNormType()`, `KSPSetPCSide()` 364 @*/ 365 PetscErrorCode KSPSetSupportedNorm(KSP ksp, KSPNormType normtype, PCSide pcside, PetscInt priority) 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 PetscFunctionBegin; 376 PetscCall(PetscMemzero(ksp->normsupporttable, sizeof(ksp->normsupporttable))); 377 ksp->pc_side = ksp->pc_side_set; 378 ksp->normtype = ksp->normtype_set; 379 PetscFunctionReturn(0); 380 } 381 382 PetscErrorCode KSPSetUpNorms_Private(KSP ksp, PetscBool errorifnotsupported, KSPNormType *normtype, PCSide *pcside) 383 { 384 PetscInt i, j, best, ibest = 0, jbest = 0; 385 386 PetscFunctionBegin; 387 best = 0; 388 for (i = 0; i < KSP_NORM_MAX; i++) { 389 for (j = 0; j < PC_SIDE_MAX; j++) { 390 if ((ksp->normtype == KSP_NORM_DEFAULT || ksp->normtype == i) && (ksp->pc_side == PC_SIDE_DEFAULT || ksp->pc_side == j) && (ksp->normsupporttable[i][j] > best)) { 391 best = ksp->normsupporttable[i][j]; 392 ibest = i; 393 jbest = j; 394 } 395 } 396 } 397 if (best < 1 && errorifnotsupported) { 398 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); 399 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]); 400 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]); 401 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]); 402 } 403 if (normtype) *normtype = (KSPNormType)ibest; 404 if (pcside) *pcside = (PCSide)jbest; 405 PetscFunctionReturn(0); 406 } 407 408 /*@ 409 KSPGetNormType - Gets the norm that is used for convergence testing. 410 411 Not Collective 412 413 Input Parameter: 414 . ksp - Krylov solver context 415 416 Output Parameter: 417 . normtype - norm that is used for convergence testing 418 419 Level: advanced 420 421 .seealso: `KSPNormType`, `KSPSetNormType()`, `KSPConvergedSkip()` 422 @*/ 423 PetscErrorCode KSPGetNormType(KSP ksp, KSPNormType *normtype) 424 { 425 PetscFunctionBegin; 426 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); 427 PetscValidPointer(normtype, 2); 428 PetscCall(KSPSetUpNorms_Private(ksp, PETSC_TRUE, &ksp->normtype, &ksp->pc_side)); 429 *normtype = ksp->normtype; 430 PetscFunctionReturn(0); 431 } 432 433 #if defined(PETSC_HAVE_SAWS) 434 #include <petscviewersaws.h> 435 #endif 436 437 /*@ 438 KSPSetOperators - Sets the matrix associated with the linear system 439 and a (possibly) different one from which the preconditioner will be built 440 441 Collective 442 443 Input Parameters: 444 + ksp - the `KSP` context 445 . Amat - the matrix that defines the linear system 446 - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 447 448 Level: beginner 449 450 Notes: 451 If you know the operator Amat has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null 452 space to Amat and the `KSP` solvers will automatically use that null space as needed during the solution process. 453 454 All future calls to `KSPSetOperators()` must use the same size matrices! 455 456 Passing a NULL for Amat or Pmat removes the matrix that is currently used. 457 458 If you wish to replace either Amat or Pmat but leave the other one untouched then 459 first call KSPGetOperators() to get the one you wish to keep, call `PetscObjectReference()` 460 on it and then pass it back in in your call to `KSPSetOperators()`. 461 462 Developer Notes: 463 If the operators have NOT been set with `KSPSetOperators()` then the operators 464 are created in the `PC` and returned to the user. In this case, if both operators 465 mat and pmat are requested, two DIFFERENT operators will be returned. If 466 only one is requested both operators in the PC will be the same (i.e. as 467 if one had called `KSPSetOperators()` with the same argument for both `Mat`s). 468 The user must set the sizes of the returned matrices and their type etc just 469 as if the user created them with `MatCreate()`. For example, 470 471 .vb 472 KSPGetOperators(ksp/pc,&mat,NULL); is equivalent to 473 set size, type, etc of mat 474 475 MatCreate(comm,&mat); 476 KSP/PCSetOperators(ksp/pc,mat,mat); 477 PetscObjectDereference((PetscObject)mat); 478 set size, type, etc of mat 479 480 and 481 482 KSP/PCGetOperators(ksp/pc,&mat,&pmat); is equivalent to 483 set size, type, etc of mat and pmat 484 485 MatCreate(comm,&mat); 486 MatCreate(comm,&pmat); 487 KSP/PCSetOperators(ksp/pc,mat,pmat); 488 PetscObjectDereference((PetscObject)mat); 489 PetscObjectDereference((PetscObject)pmat); 490 set size, type, etc of mat and pmat 491 .ve 492 493 The rationale for this support is so that when creating a `TS`, `SNES`, or `KSP` the hierarchy 494 of underlying objects (i.e. `SNES`, `KSP`, `PC`, `Mat`) and their livespans can be completely 495 managed by the top most level object (i.e. the `TS`, `SNES`, or `KSP`). Another way to look 496 at this is when you create a `SNES` you do not NEED to create a `KSP` and attach it to 497 the `SNES` object (the `SNES` object manages it for you). Similarly when you create a `KSP` 498 you do not need to attach a `PC` to it (the `KSP` object manages the `PC` object for you). 499 Thus, why should YOU have to create the `Mat` and attach it to the `SNES`/`KSP`/`PC`, when 500 it can be created for you? 501 502 .seealso: `KSP`, `Mat`, `KSPSolve()`, `KSPGetPC()`, `PCGetOperators()`, `PCSetOperators()`, `KSPGetOperators()`, `KSPSetComputeOperators()`, `KSPSetComputeInitialGuess()`, `KSPSetComputeRHS()` 503 @*/ 504 PetscErrorCode KSPSetOperators(KSP ksp, Mat Amat, Mat Pmat) 505 { 506 PetscFunctionBegin; 507 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); 508 if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 509 if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3); 510 if (Amat) PetscCheckSameComm(ksp, 1, Amat, 2); 511 if (Pmat) PetscCheckSameComm(ksp, 1, Pmat, 3); 512 if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc)); 513 PetscCall(PCSetOperators(ksp->pc, Amat, Pmat)); 514 if (ksp->setupstage == KSP_SETUP_NEWRHS) ksp->setupstage = KSP_SETUP_NEWMATRIX; /* so that next solve call will call PCSetUp() on new matrix */ 515 PetscFunctionReturn(0); 516 } 517 518 /*@ 519 KSPGetOperators - Gets the matrix associated with the linear system 520 and a (possibly) different one used to construct the preconditioner. 521 522 Collective 523 524 Input Parameter: 525 . ksp - the `KSP` context 526 527 Output Parameters: 528 + Amat - the matrix that defines the linear system 529 - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 530 531 Level: intermediate 532 533 Note: 534 DOES NOT increase the reference counts of the matrix, so you should NOT destroy them. 535 536 .seealso: `KSP`, `KSPSolve()`, `KSPGetPC()`, `PCGetOperators()`, `PCSetOperators()`, `KSPSetOperators()`, `KSPGetOperatorsSet()` 537 @*/ 538 PetscErrorCode KSPGetOperators(KSP ksp, Mat *Amat, Mat *Pmat) 539 { 540 PetscFunctionBegin; 541 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); 542 if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc)); 543 PetscCall(PCGetOperators(ksp->pc, Amat, Pmat)); 544 PetscFunctionReturn(0); 545 } 546 547 /*@C 548 KSPGetOperatorsSet - Determines if the matrix associated with the linear system and 549 possibly a different one associated with the preconditioner have been set in the `KSP`. 550 551 Not collective, though the results on all processes should be the same 552 553 Input Parameter: 554 . pc - the `KSP` context 555 556 Output Parameters: 557 + mat - the matrix associated with the linear system was set 558 - pmat - matrix associated with the preconditioner was set, usually the same 559 560 Level: intermediate 561 562 Note: 563 This routine exists because if you call `KSPGetOperators()` on a `KSP` that does not yet have operators they are 564 automatically created in the call. 565 566 .seealso: `KSP`, `PCSetOperators()`, `KSPGetOperators()`, `KSPSetOperators()`, `PCGetOperators()`, `PCGetOperatorsSet()` 567 @*/ 568 PetscErrorCode KSPGetOperatorsSet(KSP ksp, PetscBool *mat, PetscBool *pmat) 569 { 570 PetscFunctionBegin; 571 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); 572 if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc)); 573 PetscCall(PCGetOperatorsSet(ksp->pc, mat, pmat)); 574 PetscFunctionReturn(0); 575 } 576 577 /*@C 578 KSPSetPreSolve - Sets a function that is called at the beginning of each `KSPSolve()` 579 580 Logically Collective 581 582 Input Parameters: 583 + ksp - the solver object 584 . presolve - the function to call before the solve 585 - prectx - any context needed by the function 586 587 Calling sequence of presolve: 588 $ func(KSP ksp,Vec rhs,Vec x,void *ctx) 589 590 + ksp - the `KSP` context 591 . rhs - the right-hand side vector 592 . x - the solution vector 593 - ctx - optional user-provided context 594 595 Level: developer 596 597 .seealso: `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSP`, `KSPSetPostSolve()`, `PCEISENSTAT` 598 @*/ 599 PetscErrorCode KSPSetPreSolve(KSP ksp, PetscErrorCode (*presolve)(KSP, Vec, Vec, void *), void *prectx) 600 { 601 PetscFunctionBegin; 602 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); 603 ksp->presolve = presolve; 604 ksp->prectx = prectx; 605 PetscFunctionReturn(0); 606 } 607 608 /*@C 609 KSPSetPostSolve - Sets a function that is called at the end of each `KSPSolve()` (whether it converges or not) 610 611 Logically Collective 612 613 Input Parameters: 614 + ksp - the solver object 615 . postsolve - the function to call after the solve 616 - postctx - any context needed by the function 617 618 Calling sequence of postsolve: 619 $ func(KSP ksp,Vec rhs,Vec x,void *ctx) 620 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(0); 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 . ksp - location to put the `KSP` context 649 650 Note: 651 The default `KSPType` is `KSPGMRES` with a restart of 30, using modified Gram-Schmidt orthogonalization. 652 653 Level: beginner 654 655 .seealso: [](chapter_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(0); 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 Notes: 733 See "petsc/include/petscksp.h" for available methods (for instance, `KSPCG` or `KSPGMRES`). 734 735 Normally, it is best to use the `KSPSetFromOptions()` command and 736 then set the `KSP` type from the options database rather than by using 737 this routine. Using the options database provides the user with 738 maximum flexibility in evaluating the many different Krylov methods. 739 The `KSPSetType()` routine is provided for those situations where it 740 is necessary to set the iterative solver independently of the command 741 line or options database. This might be the case, for example, when 742 the choice of iterative solver changes during the execution of the 743 program, and the user's application is taking responsibility for 744 choosing the appropriate method. In other words, this routine is 745 not for beginners. 746 747 Level: intermediate 748 749 Developer Note: 750 `KSPRegister()` is used to add Krylov types to `KSPList` from which they are accessed by `KSPSetType()`. 751 752 .seealso: [](chapter_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(0); 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->setupnewmatrix = PETSC_FALSE; // restore default (setup not called in case of new matrix) 778 /* Call the KSPCreate_XXX routine for this particular Krylov solver */ 779 ksp->setupstage = KSP_SETUP_NEW; 780 PetscCall((*r)(ksp)); 781 PetscCall(PetscObjectChangeTypeName((PetscObject)ksp, type)); 782 PetscFunctionReturn(0); 783 } 784 785 /*@C 786 KSPGetType - Gets the `KSP` type as a string from the KSP object. 787 788 Not Collective 789 790 Input Parameter: 791 . ksp - Krylov context 792 793 Output Parameter: 794 . name - name of the `KSP` method 795 796 Level: intermediate 797 798 .seealso: [](chapter_ksp), `KSPType`, `KSP`, `KSPSetType()` 799 @*/ 800 PetscErrorCode KSPGetType(KSP ksp, KSPType *type) 801 { 802 PetscFunctionBegin; 803 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1); 804 PetscValidPointer(type, 2); 805 *type = ((PetscObject)ksp)->type_name; 806 PetscFunctionReturn(0); 807 } 808 809 /*@C 810 KSPRegister - Adds a method, `KSPType`, to the Krylov subspace solver package. 811 812 Not Collective 813 814 Input Parameters: 815 + name_solver - name of a new user-defined solver 816 - routine_create - routine to create method context 817 818 Level: advanced 819 820 Note: 821 `KSPRegister()` may be called multiple times to add several user-defined solvers. 822 823 Sample usage: 824 .vb 825 KSPRegister("my_solver",MySolverCreate); 826 .ve 827 828 Then, your solver can be chosen with the procedural interface via 829 $ ` KSPSetType`(ksp,"my_solver") 830 or at runtime via the option 831 $ -ksp_type my_solver 832 833 .seealso: [](chapter_ksp), `KSP`, `KSPType`, `KSPSetType`, `KSPRegisterAll()` 834 @*/ 835 PetscErrorCode KSPRegister(const char sname[], PetscErrorCode (*function)(KSP)) 836 { 837 PetscFunctionBegin; 838 PetscCall(KSPInitializePackage()); 839 PetscCall(PetscFunctionListAdd(&KSPList, sname, function)); 840 PetscFunctionReturn(0); 841 } 842 843 PetscErrorCode KSPMonitorMakeKey_Internal(const char name[], PetscViewerType vtype, PetscViewerFormat format, char key[]) 844 { 845 PetscFunctionBegin; 846 PetscCall(PetscStrncpy(key, name, PETSC_MAX_PATH_LEN)); 847 PetscCall(PetscStrlcat(key, ":", PETSC_MAX_PATH_LEN)); 848 PetscCall(PetscStrlcat(key, vtype, PETSC_MAX_PATH_LEN)); 849 PetscCall(PetscStrlcat(key, ":", PETSC_MAX_PATH_LEN)); 850 PetscCall(PetscStrlcat(key, PetscViewerFormats[format], PETSC_MAX_PATH_LEN)); 851 PetscFunctionReturn(0); 852 } 853 854 /*@C 855 KSPMonitorRegister - Registers a Krylov subspace solver monitor routine that may be accessed with `KSPMonitorSetFromOptions()` 856 857 Not Collective 858 859 Input Parameters: 860 + name - name of a new monitor routine 861 . vtype - A `PetscViewerType` for the output 862 . format - A `PetscViewerFormat` for the output 863 . monitor - Monitor routine 864 . create - Creation routine, or NULL 865 - destroy - Destruction routine, or NULL 866 867 Level: advanced 868 869 Note: 870 `KSPMonitorRegister()` may be called multiple times to add several user-defined monitors. 871 872 Sample usage: 873 .vb 874 KSPMonitorRegister("my_monitor",PETSCVIEWERASCII,PETSC_VIEWER_ASCII_INFO_DETAIL,MyMonitor,NULL,NULL); 875 .ve 876 877 Then, your monitor can be chosen with the procedural interface via 878 $ KSPMonitorSetFromOptions(ksp,"-ksp_monitor_my_monitor","my_monitor",NULL) 879 or at runtime via the option 880 $ -ksp_monitor_my_monitor 881 882 .seealso: [](chapter_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorRegisterAll()`, `KSPMonitorSetFromOptions()` 883 @*/ 884 PetscErrorCode KSPMonitorRegister(const char name[], PetscViewerType vtype, PetscViewerFormat format, PetscErrorCode (*monitor)(KSP, PetscInt, PetscReal, PetscViewerAndFormat *), PetscErrorCode (*create)(PetscViewer, PetscViewerFormat, void *, PetscViewerAndFormat **), PetscErrorCode (*destroy)(PetscViewerAndFormat **)) 885 { 886 char key[PETSC_MAX_PATH_LEN]; 887 888 PetscFunctionBegin; 889 PetscCall(KSPInitializePackage()); 890 PetscCall(KSPMonitorMakeKey_Internal(name, vtype, format, key)); 891 PetscCall(PetscFunctionListAdd(&KSPMonitorList, key, monitor)); 892 if (create) PetscCall(PetscFunctionListAdd(&KSPMonitorCreateList, key, create)); 893 if (destroy) PetscCall(PetscFunctionListAdd(&KSPMonitorDestroyList, key, destroy)); 894 PetscFunctionReturn(0); 895 } 896