Actual source code: modpcf.c
2: #include <petsc/private/kspimpl.h>
4: /*@C
5: KSPFGMRESSetModifyPC - Sets the routine used by `KSPFGMRES` to modify the preconditioner. [](sec_flexibleksp)
7: Logically Collective
9: Input Parameters:
10: + ksp - iterative context obtained from `KSPCreate()`
11: . fcn - modifypc function
12: . ctx - optional context
13: - d - optional context destroy routine
15: Calling Sequence of function:
16: PetscErrorCode fcn(KSP ksp,PetscInt total_its,PetscInt loc_its,PetscReal res_norm,void*ctx);
17: + ksp - the ksp context being used.
18: . total_its - the total number of FGMRES iterations that have occurred.
19: . loc_its - the number of FGMRES iterations since last restart.
20: . res_norm - the current residual norm.
21: - ctx - optional context variable
23: Options Database Keys:
24: + -ksp_fgmres_modifypcnochange - do not change the `PC`
25: - -ksp_fgmres_modifypcksp - changes the inner KSP solver tolerances
27: Level: intermediate
29: Note:
30: Several modifypc routines are predefined, including `KSPFGMRESModifyPCNoChange()`, and `KSPFGMRESModifyPCKSP()`
32: .seealso: [](chapter_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFGMRESModifyPCNoChange()`, `KSPFGMRESModifyPCKSP()`
33: @*/
34: PetscErrorCode KSPFGMRESSetModifyPC(KSP ksp, PetscErrorCode (*fcn)(KSP, PetscInt, PetscInt, PetscReal, void *), void *ctx, PetscErrorCode (*d)(void *))
35: {
37: PetscTryMethod(ksp, "KSPFGMRESSetModifyPC_C", (KSP, PetscErrorCode(*)(KSP, PetscInt, PetscInt, PetscReal, void *), void *, PetscErrorCode (*)(void *)), (ksp, fcn, ctx, d));
38: return 0;
39: }
41: /*@
42: KSPFGMRESModifyPCNoChange - this is the default used by `KSPFMGMRES` - it doesn't change the preconditioner. [](sec_flexibleksp)
44: Input Parameters:
45: + ksp - the ksp context being used.
46: . total_its - the total number of `KSPFGMRES` iterations that have occurred.
47: . loc_its - the number of `KSPFGMRES` iterations since last restart.
48: a restart (so number of Krylov directions to be computed)
49: . res_norm - the current residual norm.
50: - dummy - context variable, unused in this routine
52: Level: intermediate
54: .seealso: [](chapter_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFGMRESSetModifyPC()`, `KSPFGMRESModifyPCKSP()`
55: @*/
56: PetscErrorCode KSPFGMRESModifyPCNoChange(KSP ksp, PetscInt total_its, PetscInt loc_its, PetscReal res_norm, void *dummy)
57: {
58: return 0;
59: }
61: /*@
62: KSPFGMRESModifyPCKSP - modifies the attributes of the `KSPFGMRES` preconditioner. [](sec_flexibleksp). It serves as an example (not as something useful in practice)
64: Input Parameters:
65: + ksp - the ksp context being used.
66: . total_its - the total number of `KSPFGMRES` iterations that have occurred.
67: . loc_its - the number of `KSPFGMRES` iterations since last restart.
68: . res_norm - the current residual norm.
69: - dummy - context, not used here
71: Level: intermediate
73: Note:
74: You can use this as a template for writing a custom monification callback
76: .seealso: [](chapter_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFGMRESSetModifyPC()`, `KSPFGMRESModifyPCKSP()`
77: @*/
78: PetscErrorCode KSPFGMRESModifyPCKSP(KSP ksp, PetscInt total_its, PetscInt loc_its, PetscReal res_norm, void *dummy)
79: {
80: PC pc;
81: PetscInt maxits;
82: KSP sub_ksp;
83: PetscReal rtol, abstol, dtol;
84: PetscBool isksp;
86: KSPGetPC(ksp, &pc);
88: PetscObjectTypeCompare((PetscObject)pc, PCKSP, &isksp);
89: if (isksp) {
90: PCKSPGetKSP(pc, &sub_ksp);
92: /* note that at this point you could check the type of KSP with KSPGetType() */
94: /* Now we can use functions such as KSPGMRESSetRestart() or
95: KSPGMRESSetOrthogonalization() or KSPSetTolerances() */
97: KSPGetTolerances(sub_ksp, &rtol, &abstol, &dtol, &maxits);
98: if (!loc_its) rtol = .1;
99: else rtol *= .9;
100: KSPSetTolerances(sub_ksp, rtol, abstol, dtol, maxits);
101: }
102: return 0;
103: }