Date: 2026-03-01T05:24:48+00:00

Actual source code: modpcf.c

      1: #include <petsc/private/kspimpl.h>

      3: /*@C
      4:   KSPFGMRESSetModifyPC - Sets the routine used by `KSPFGMRES` to modify the preconditioner. [](sec_flexibleksp)

      6:   Logically Collective

      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

     14:   Options Database Keys:
     15: + -ksp_fgmres_modifypcnochange - do not change the `PC`
     16: - -ksp_fgmres_modifypcksp      - changes the inner KSP solver tolerances

     18:   Level: intermediate

     20:   Note:
     21:   Several `fcn` routines are predefined, including `KSPFGMRESModifyPCNoChange()` and `KSPFGMRESModifyPCKSP()`

     23: .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFlexibleModifyPCFn`, `KSPFlexibleSetModifyPC()`, `KSPFGMRESModifyPCNoChange()`, `KSPFGMRESModifyPCKSP()`
     24: @*/
     25: PetscErrorCode KSPFGMRESSetModifyPC(KSP ksp, KSPFlexibleModifyPCFn *fcn, void *ctx, PetscCtxDestroyFn *destroy)
     26: {
     27:   PetscFunctionBegin;
     29:   PetscTryMethod(ksp, "KSPFGMRESSetModifyPC_C", (KSP, KSPFlexibleModifyPCFn *, void *, PetscCtxDestroyFn *), (ksp, fcn, ctx, destroy));
     30:   PetscFunctionReturn(PETSC_SUCCESS);
     31: }

     33: /*@C
     34:   KSPFlexibleSetModifyPC - Sets the routine used by flexible `KSP` methods to modify the preconditioner. [](sec_flexibleksp)

     36:   Logically Collective

     38:   Input Parameters:
     39: + ksp     - iterative context obtained from `KSPCreate()`
     40: . fcn     - function to modify the `PC`, see `KSPFlexibleModifyPCFn`
     41: . ctx     - optional context
     42: - destroy - optional context destroy routine

     44:   Level: intermediate

     46:   Note:
     47:   Several `fcn` routines are predefined, including `KSPFGMRESModifyPCNoChange()` and `KSPFGMRESModifyPCKSP()`

     49: .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFGMRESModifyPCNoChange()`, `KSPFGMRESModifyPCKSP()`
     50: @*/
     51: PetscErrorCode KSPFlexibleSetModifyPC(KSP ksp, KSPFlexibleModifyPCFn *fcn, void *ctx, PetscCtxDestroyFn *destroy)
     52: {
     53:   PetscFunctionBegin;
     55:   PetscTryMethod(ksp, "KSPFlexibleSetModifyPC_C", (KSP, KSPFlexibleModifyPCFn *, void *, PetscCtxDestroyFn *), (ksp, fcn, ctx, destroy));
     56:   PetscFunctionReturn(PETSC_SUCCESS);
     57: }

     59: /*@C
     60:   KSPFGMRESModifyPCNoChange - this is the default used by `KSPFMGMRES` - it doesn't change the preconditioner. [](sec_flexibleksp)

     62:   Input Parameters:
     63: + ksp       - the ksp context being used.
     64: . total_its - the total number of `KSPFGMRES` iterations that have occurred.
     65: . loc_its   - the number of `KSPFGMRES` iterations since last restart.
     66: . res_norm  - the current residual norm.
     67: - ctx       - context variable, unused in this routine

     69:   Level: intermediate

     71: .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFlexibleModifyPCFn`, `KSPFGMRESSetModifyPC()`, `KSPFGMRESModifyPCKSP()`
     72: @*/
     73: PetscErrorCode KSPFGMRESModifyPCNoChange(KSP ksp, PetscInt total_its, PetscInt loc_its, PetscReal res_norm, void *ctx)
     74: {
     75:   PetscFunctionBegin;
     76:   PetscFunctionReturn(PETSC_SUCCESS);
     77: }

     79: /*@C
     80:   KSPFGMRESModifyPCKSP - modifies the attributes of the `KSPFGMRES` preconditioner, see [](sec_flexibleksp).

     82:   Input Parameters:
     83: + ksp       - the ksp context being used.
     84: . total_its - the total number of `KSPFGMRES` iterations that have occurred.
     85: . loc_its   - the number of `KSPFGMRES` iterations since last restart.
     86: . res_norm  - the current residual norm.
     87: - ctx       - context, not used in this routine

     89:   Level: intermediate

     91:   Note:
     92:   You can use this as a template for writing a custom modification callback

     94: .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFlexibleModifyPCFn`, `KSPFGMRESSetModifyPC()`
     95: @*/
     96: PetscErrorCode KSPFGMRESModifyPCKSP(KSP ksp, PetscInt total_its, PetscInt loc_its, PetscReal res_norm, void *ctx)
     97: {
     98:   PC        pc;
     99:   PetscInt  maxits;
    100:   KSP       sub_ksp;
    101:   PetscReal rtol, abstol, dtol;
    102:   PetscBool isksp;

    104:   PetscFunctionBegin;
    105:   PetscCall(KSPGetPC(ksp, &pc));

    107:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCKSP, &isksp));
    108:   if (isksp) {
    109:     PetscCall(PCKSPGetKSP(pc, &sub_ksp));

    111:     /* note that at this point you could check the type of KSP with KSPGetType() */

    113:     /* Now we can use functions such as KSPGMRESSetRestart() or
    114:       KSPGMRESSetOrthogonalization() or KSPSetTolerances() */

    116:     PetscCall(KSPGetTolerances(sub_ksp, &rtol, &abstol, &dtol, &maxits));
    117:     if (!loc_its) rtol = .1;
    118:     else rtol *= .9;
    119:     PetscCall(KSPSetTolerances(sub_ksp, rtol, abstol, dtol, maxits));
    120:   }
    121:   PetscFunctionReturn(PETSC_SUCCESS);
    122: }