Actual source code: modpcf.c

      1: #define PETSCKSP_DLL

     3:  #include petscksp.h
      6: /*@C
      7:    KSPFGMRESSetModifyPC - Sets the routine used by FGMRES to modify the preconditioner.

      9:    Collective on KSP

     11:    Input Parameters:
     12: +  ksp - iterative context obtained from KSPCreate
     13: .  fcn - modifypc function
     14: .  ctx - optional contex
     15: -  d - optional context destroy routine

     17:    Calling Sequence of function:
     18:     int fcn(KSP ksp,int total_its,int loc_its,PetscReal res_norm,void*ctx);

     20:     ksp - the ksp context being used.
     21:     total_its     - the total number of FGMRES iterations that have occurred.
     22:     loc_its       - the number of FGMRES iterations since last restart.
     23:     res_norm      - the current residual norm.
     24:     ctx           - optional context variable

     26:    Options Database Keys:
     27:    -ksp_fgmres_modifypcnochange
     28:    -ksp_fgmres_modifypcksp

     30:    Level: intermediate

     32:    Contributed by Allison Baker

     34:    Notes:
     35:    Several modifypc routines are predefined, including
     36:     KSPFGMRESModifyPCNoChange()
     37:     KSPFGMRESModifyPCKSP()

     39: .seealso: KSPFGMRESModifyPCNoChange(), KSPFGMRESModifyPCKSP()

     41: @*/
     42: PetscErrorCode PETSCKSP_DLLEXPORT KSPFGMRESSetModifyPC(KSP ksp,PetscErrorCode (*fcn)(KSP,PetscInt,PetscInt,PetscReal,void*),void* ctx,PetscErrorCode (*d)(void*))
     43: {
     44:   PetscErrorCode ierr,(*f)(KSP,PetscErrorCode (*)(KSP,PetscInt,PetscInt,PetscReal,void*),void*,PetscErrorCode (*)(void*));

     48:   PetscObjectQueryFunction((PetscObject)ksp,"KSPFGMRESSetModifyPC_C",(void (**)(void))&f);
     49:   if (f) {
     50:     (*f)(ksp,fcn,ctx,d);
     51:   }
     52:   return(0);
     53: }

     56: /* The following are different routines used to modify the preconditioner */

     60: /*@C

     62:   KSPFGMRESModifyPCNoChange - this is the default used by fgmres - it doesn't change the preconditioner.

     64:   Input Parameters:
     65: +    ksp - the ksp context being used.
     66: .    total_its     - the total number of FGMRES iterations that have occurred.
     67: .    loc_its       - the number of FGMRES iterations since last restart.
     68:                     a restart (so number of Krylov directions to be computed)
     69: .    res_norm      - the current residual norm.
     70: -    dummy         - context variable, unused in this routine

     72:    Level: intermediate

     74:    Contributed by Allison Baker

     76: You can use this as a template!

     78: .seealso: KSPFGMRESSetModifyPC(), KSPFGMRESModifyPCKSP()

     80: @*/
     81: PetscErrorCode PETSCKSP_DLLEXPORT KSPFGMRESModifyPCNoChange(KSP ksp,PetscInt total_its,PetscInt loc_its,PetscReal res_norm,void* dummy)
     82: {

     85:   return(0);
     86: }

     90: /*@C

     92:  KSPFGMRESModifyPCKSP - modifies the attributes of the
     93:      GMRES preconditioner.  It serves as an example (not as something
     94:      useful!)

     96:   Input Parameters:
     97: +    ksp - the ksp context being used.
     98: .    total_its     - the total number of FGMRES iterations that have occurred.
     99: .    loc_its       - the number of FGMRES iterations since last restart.
    100: .    res_norm      - the current residual norm.
    101: -    dummy         - context, not used here

    103:    Level: intermediate

    105:    Contributed by Allison Baker

    107:  This could be used as a template!

    109: .seealso: KSPFGMRESSetModifyPC(), KSPFGMRESModifyPCKSP()

    111: @*/
    112: PetscErrorCode PETSCKSP_DLLEXPORT KSPFGMRESModifyPCKSP(KSP ksp,PetscInt total_its,PetscInt loc_its,PetscReal res_norm,void *dummy)
    113: {
    114:   PC             pc;
    116:   PetscInt       maxits;
    117:   KSP            sub_ksp;
    118:   PetscReal      rtol,abstol,dtol;
    119:   PetscTruth     isksp;

    122:   KSPGetPC(ksp,&pc);

    124:   PetscTypeCompare((PetscObject)pc,PCKSP,&isksp);
    125:   if (isksp) {
    126:     PCKSPGetKSP(pc,&sub_ksp);
    127:
    128:     /* note that at this point you could check the type of KSP with KSPGetType() */

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

    133:     KSPGetTolerances(sub_ksp,&rtol,&abstol,&dtol,&maxits);
    134:     if (!loc_its) {
    135:       rtol = .1;
    136:     } else {
    137:       rtol *= .9;
    138:     }
    139:     KSPSetTolerances(sub_ksp,rtol,abstol,dtol,maxits);
    140:   }
    141:   return(0);
    142: }