xref: /petsc/src/ksp/ksp/impls/gmres/fgmres/modpcf.c (revision 65c6dbde5b77e518f6ed8bf109ce6c9ab9061e55)
1 #include <petsc/private/kspimpl.h> /*I "petscksp.h" I*/
2 
3 /*@C
4   KSPFlexibleSetModifyPC - Sets the routine used by flexible `KSP` methods to modify the preconditioner. [](sec_flexibleksp)
5 
6   Logically Collective
7 
8   Input Parameters:
9 + ksp     - iterative context obtained from `KSPCreate()`
10 . fcn     - function to modify the `PC`, see `KSPFlexibleModifyPCFn`
11 . ctx     - optional context
12 - destroy - optional context destroy routine
13 
14   Level: intermediate
15 
16   Note:
17   Several `fcn` routines are predefined, including `KSPFlexibleModifyPCNoChange()` and `KSPFlexibleModifyPCKSP()`
18 
19 .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFCG`, `KSPPIPEFCG`, `KSPGCR`, `KSPPIPEGCR`, `KSPFlexibleModifyPCFn`, `KSPFlexibleModifyPCNoChange()`, `KSPFlexibleModifyPCKSP()`
20 @*/
KSPFlexibleSetModifyPC(KSP ksp,KSPFlexibleModifyPCFn * fcn,PetscCtx ctx,PetscCtxDestroyFn * destroy)21 PetscErrorCode KSPFlexibleSetModifyPC(KSP ksp, KSPFlexibleModifyPCFn *fcn, PetscCtx ctx, PetscCtxDestroyFn *destroy)
22 {
23   PetscFunctionBegin;
24   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
25   PetscTryMethod(ksp, "KSPFlexibleSetModifyPC_C", (KSP, KSPFlexibleModifyPCFn *, PetscCtx, PetscCtxDestroyFn *), (ksp, fcn, ctx, destroy));
26   PetscFunctionReturn(PETSC_SUCCESS);
27 }
28 
29 /*@C
30   KSPFlexibleModifyPCNoChange - this is the default used by the flexible Krylov methods - it doesn't change the preconditioner. [](sec_flexibleksp)
31 
32   Input Parameters:
33 + ksp       - the ksp context being used.
34 . total_its - the total number of `KSP` iterations that have occurred.
35 . loc_its   - the number of `KSP` iterations since last restart.
36 . res_norm  - the current residual norm.
37 - ctx       - context variable, unused in this routine
38 
39   Level: intermediate
40 
41   Note:
42   See `KSPFlexibleModifyPCKSP()` for a template for providing your own modification routines.
43 
44 .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFCG`, `KSPPIPEFCG`, `KSPGCR`, `KSPPIPEGCR`, `KSPFlexibleModifyPCFn`, `KSPFlexibleSetModifyPC()`, `KSPFlexibleModifyPCKSP()`
45 @*/
KSPFlexibleModifyPCNoChange(KSP ksp,PetscInt total_its,PetscInt loc_its,PetscReal res_norm,PetscCtx ctx)46 PetscErrorCode KSPFlexibleModifyPCNoChange(KSP ksp, PetscInt total_its, PetscInt loc_its, PetscReal res_norm, PetscCtx ctx)
47 {
48   PetscFunctionBegin;
49   PetscFunctionReturn(PETSC_SUCCESS);
50 }
51 
52 /*@C
53   KSPFlexibleModifyPCKSP - modifies the attributes of the `PCKSP` preconditioner, see [](sec_flexibleksp).
54 
55   Input Parameters:
56 + ksp       - the ksp context being used.
57 . total_its - the total number of `KSP` iterations that have occurred.
58 . loc_its   - the number of `KSP` iterations since last restart.
59 . res_norm  - the current residual norm.
60 - ctx       - context, unused in this routine
61 
62   Level: intermediate
63 
64   Notes:
65   You can use this as a template for writing a custom modification callback. See the source code for the change it makes.
66 
67   You can provide this to a `KSP` with `KSPFlexibleSetModifyPC()`
68 
69 .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFCG`, `KSPPIPEFCG`, `KSPGCR`, `KSPPIPEGCR`, `KSPFlexibleModifyPCFn`, `KSPFlexibleSetModifyPC()`
70 @*/
KSPFlexibleModifyPCKSP(KSP ksp,PetscInt total_its,PetscInt loc_its,PetscReal res_norm,PetscCtx ctx)71 PetscErrorCode KSPFlexibleModifyPCKSP(KSP ksp, PetscInt total_its, PetscInt loc_its, PetscReal res_norm, PetscCtx ctx)
72 {
73   PC        pc;
74   PetscInt  maxits;
75   KSP       sub_ksp;
76   PetscReal rtol, abstol, dtol;
77   PetscBool isksp;
78 
79   PetscFunctionBegin;
80   PetscCall(KSPGetPC(ksp, &pc));
81 
82   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCKSP, &isksp));
83   if (isksp) {
84     PetscCall(PCKSPGetKSP(pc, &sub_ksp));
85 
86     /* note that at this point you could check the type of KSP with KSPGetType() */
87 
88     /* Now we can use functions such as KSPGMRESSetRestart() or
89       KSPGMRESSetOrthogonalization() or KSPSetTolerances() */
90 
91     PetscCall(KSPGetTolerances(sub_ksp, &rtol, &abstol, &dtol, &maxits));
92     if (!loc_its) rtol = .1;
93     else rtol *= .9;
94     PetscCall(KSPSetTolerances(sub_ksp, rtol, abstol, dtol, maxits));
95   }
96   PetscFunctionReturn(PETSC_SUCCESS);
97 }
98