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:    Calling Sequence of `d`:
 24: $ PetscErrorCode d(void *ctx)

 26:    Options Database Keys:
 27: +   -ksp_fgmres_modifypcnochange - do not change the `PC`
 28: -   -ksp_fgmres_modifypcksp - changes the inner KSP solver tolerances

 30:    Level: intermediate

 32:    Note:
 33:    Several modifypc routines are predefined, including  `KSPFGMRESModifyPCNoChange()`, and  `KSPFGMRESModifyPCKSP()`

 35: .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFGMRESModifyPCNoChange()`, `KSPFGMRESModifyPCKSP()`
 36: @*/
 37: PetscErrorCode KSPFGMRESSetModifyPC(KSP ksp, PetscErrorCode (*fcn)(KSP, PetscInt, PetscInt, PetscReal, void *), void *ctx, PetscErrorCode (*d)(void *))
 38: {
 39:   PetscFunctionBegin;
 41:   PetscTryMethod(ksp, "KSPFGMRESSetModifyPC_C", (KSP, PetscErrorCode(*)(KSP, PetscInt, PetscInt, PetscReal, void *), void *, PetscErrorCode (*)(void *)), (ksp, fcn, ctx, d));
 42:   PetscFunctionReturn(PETSC_SUCCESS);
 43: }

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

 48:   Input Parameters:
 49: +    ksp - the ksp context being used.
 50: .    total_its     - the total number of `KSPFGMRES` iterations that have occurred.
 51: .    loc_its       - the number of `KSPFGMRES` iterations since last restart.
 52:                     a restart (so number of Krylov directions to be computed)
 53: .    res_norm      - the current residual norm.
 54: -    dummy         - context variable, unused in this routine

 56:    Level: intermediate

 58: .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFGMRESSetModifyPC()`, `KSPFGMRESModifyPCKSP()`
 59: @*/
 60: PetscErrorCode KSPFGMRESModifyPCNoChange(KSP ksp, PetscInt total_its, PetscInt loc_its, PetscReal res_norm, void *dummy)
 61: {
 62:   PetscFunctionBegin;
 63:   PetscFunctionReturn(PETSC_SUCCESS);
 64: }

 66: /*@
 67:      KSPFGMRESModifyPCKSP - modifies the attributes of the `KSPFGMRES` preconditioner. [](sec_flexibleksp). It serves as an example (not as something useful in practice)

 69:   Input Parameters:
 70: +    ksp - the ksp context being used.
 71: .    total_its     - the total number of `KSPFGMRES` iterations that have occurred.
 72: .    loc_its       - the number of `KSPFGMRES` iterations since last restart.
 73: .    res_norm      - the current residual norm.
 74: -    dummy         - context, not used here

 76:    Level: intermediate

 78:    Note:
 79:     You can use this as a template for writing a custom monification callback

 81: .seealso: [](ch_ksp), [](sec_flexibleksp), `KSPFGMRES`, `KSPFGMRESSetModifyPC()`, `KSPFGMRESModifyPCKSP()`
 82: @*/
 83: PetscErrorCode KSPFGMRESModifyPCKSP(KSP ksp, PetscInt total_its, PetscInt loc_its, PetscReal res_norm, void *dummy)
 84: {
 85:   PC        pc;
 86:   PetscInt  maxits;
 87:   KSP       sub_ksp;
 88:   PetscReal rtol, abstol, dtol;
 89:   PetscBool isksp;

 91:   PetscFunctionBegin;
 92:   PetscCall(KSPGetPC(ksp, &pc));

 94:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCKSP, &isksp));
 95:   if (isksp) {
 96:     PetscCall(PCKSPGetKSP(pc, &sub_ksp));

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

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

103:     PetscCall(KSPGetTolerances(sub_ksp, &rtol, &abstol, &dtol, &maxits));
104:     if (!loc_its) rtol = .1;
105:     else rtol *= .9;
106:     PetscCall(KSPSetTolerances(sub_ksp, rtol, abstol, dtol, maxits));
107:   }
108:   PetscFunctionReturn(PETSC_SUCCESS);
109: }