Actual source code: wp.c

petsc-3.3-p7 2013-05-11
  2: /*MC
  3:      MATMFFD_WP - Implements an alternative approach for computing the differencing parameter
  4:         h used with the finite difference based matrix-free Jacobian.  This code
  5:         implements the strategy of M. Pernice and H. Walker:

  7:       h = error_rel * sqrt(1 + ||U||) / ||a||

  9:       Notes:
 10:         1) || U || does not change between linear iterations so is reused
 11:         2) In GMRES || a || == 1 and so does not need to ever be computed except at restart
 12:            when it is recomputed.

 14:       Reference:  M. Pernice and H. F. Walker, "NITSOL: A Newton Iterative 
 15:       Solver for Nonlinear Systems", SIAM J. Sci. Stat. Comput.", 1998, 
 16:       vol 19, pp. 302--318.

 18:    Options Database Keys:
 19: .   -mat_mffd_compute_normu -Compute the norm of u everytime see MatMFFDWPSetComputeNormU()


 22:    Level: intermediate

 24:    Notes: Requires no global collectives when used with GMRES

 26:    Formula used:
 27:      F'(u)*a = [F(u+h*a) - F(u)]/h where

 29: .seealso: MATMFFD, MatCreateMFFD(), MatCreateSNESMF(), MATMFFD_DS

 31: M*/

 33: /*
 34:     This include file defines the data structure  MatMFFD that 
 35:    includes information about the computation of h. It is shared by 
 36:    all implementations that people provide.

 38:    See snesmfjdef.c for  a full set of comments on the routines below.
 39: */
 40: #include <petsc-private/matimpl.h>
 41: #include <../src/mat/impls/mffd/mffdimpl.h>   /*I  "petscmat.h"   I*/

 43: typedef struct {
 44:   PetscReal  normUfact;                   /* previous sqrt(1.0 + || U ||) */
 45:   PetscBool  computenormU;
 46: } MatMFFD_WP;

 50: /*
 51:      MatMFFDCompute_WP - Standard PETSc code for 
 52:    computing h with matrix-free finite differences.

 54:   Input Parameters:
 55: +   ctx - the matrix free context
 56: .   U - the location at which you want the Jacobian
 57: -   a - the direction you want the derivative

 59:   Output Parameter:
 60: .   h - the scale computed

 62: */
 63: static PetscErrorCode MatMFFDCompute_WP(MatMFFD ctx,Vec U,Vec a,PetscScalar *h,PetscBool  *zeroa)
 64: {
 65:   MatMFFD_WP    *hctx = (MatMFFD_WP*)ctx->hctx;
 66:   PetscReal      normU,norma;

 70:   if (!(ctx->count % ctx->recomputeperiod)) {
 71:     if (hctx->computenormU || !ctx->ncurrenth) {
 72:       VecNorm(U,NORM_2,&normU);
 73:       hctx->normUfact = PetscSqrtReal(1.0+normU);
 74:     }
 75:     VecNorm(a,NORM_2,&norma);
 76:     if (norma == 0.0) {
 77:       *zeroa = PETSC_TRUE;
 78:       return(0);
 79:     }
 80:     *zeroa = PETSC_FALSE;
 81:     *h = ctx->error_rel*hctx->normUfact/norma;
 82:   } else {
 83:     *h = ctx->currenth;
 84:   }
 85:   return(0);
 86: }

 90: /*
 91:    MatMFFDView_WP - Prints information about this particular 
 92:      method for computing h. Note that this does not print the general
 93:      information about the matrix free, that is printed by the calling
 94:      routine.

 96:   Input Parameters:
 97: +   ctx - the matrix free context
 98: -   viewer - the PETSc viewer

100: */
101: static PetscErrorCode MatMFFDView_WP(MatMFFD ctx,PetscViewer viewer)
102: {
103:   MatMFFD_WP     *hctx = (MatMFFD_WP *)ctx->hctx;
105:   PetscBool      iascii;

108:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
109:   if (iascii) {
110:     if (hctx->computenormU){ PetscViewerASCIIPrintf(viewer,"    Computes normU\n");}
111:     else                   { PetscViewerASCIIPrintf(viewer,"    Does not compute normU\n");}
112:   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for SNES matrix-free WP",((PetscObject)viewer)->type_name);
113:   return(0);
114: }

118: /*
119:    MatMFFDSetFromOptions_WP - Looks in the options database for 
120:      any options appropriate for this method

122:   Input Parameter:
123: .  ctx - the matrix free context

125: */
126: static PetscErrorCode MatMFFDSetFromOptions_WP(MatMFFD ctx)
127: {
129:   MatMFFD_WP     *hctx = (MatMFFD_WP*)ctx->hctx;

132:   PetscOptionsHead("Walker-Pernice options");
133:     PetscOptionsBool("-mat_mffd_compute_normu","Compute the norm of u","MatMFFDWPSetComputeNormU", hctx->computenormU,&hctx->computenormU,0);
134:   PetscOptionsTail();
135:   return(0);
136: }

140: /*
141:    MatMFFDDestroy_WP - Frees the space allocated by 
142:        MatCreateMFFD_WP(). 

144:   Input Parameter:
145: .  ctx - the matrix free context

147:    Notes: does not free the ctx, that is handled by the calling routine

149: */
150: static PetscErrorCode MatMFFDDestroy_WP(MatMFFD ctx)
151: {
154:   PetscFree(ctx->hctx);
155:   return(0);
156: }

158: EXTERN_C_BEGIN
161: PetscErrorCode  MatMFFDWPSetComputeNormU_P(Mat mat,PetscBool  flag)
162: {
163:   MatMFFD     ctx = (MatMFFD)mat->data;
164:   MatMFFD_WP  *hctx = (MatMFFD_WP*)ctx->hctx;

167:   hctx->computenormU = flag;
168:   return(0);
169: }
170: EXTERN_C_END

174: /*@
175:     MatMFFDWPSetComputeNormU - Sets whether it computes the ||U|| used by the WP
176:              PETSc routine for computing h. With any Krylov solver this need only 
177:              be computed during the first iteration and kept for later.

179:   Input Parameters:
180: +   A - the matrix created with MatCreateSNESMF()
181: -   flag - PETSC_TRUE causes it to compute ||U||, PETSC_FALSE uses the previous value

183:   Options Database Key:
184: .   -mat_mffd_compute_normu <true,false> - true by default, false can save calculations but you 
185:               must be sure that ||U|| has not changed in the mean time.

187:   Level: advanced

189:   Notes:
190:    See the manual page for MATMFFD_WP for a complete description of the
191:    algorithm used to compute h.

193: .seealso: MatMFFDSetFunctionError(), MatCreateSNESMF()

195: @*/
196: PetscErrorCode  MatMFFDWPSetComputeNormU(Mat A,PetscBool  flag)
197: {

202:   PetscTryMethod(A,"MatMFFDWPSetComputeNormU_C",(Mat,PetscBool),(A,flag));
203:   return(0);
204: }

206: EXTERN_C_BEGIN
209: /*
210:      MatCreateMFFD_WP - Standard PETSc code for 
211:    computing h with matrix-free finite differences.

213:    Input Parameter:
214: .  ctx - the matrix free context created by MatCreateMFFD()

216: */
217: PetscErrorCode  MatCreateMFFD_WP(MatMFFD ctx)
218: {
220:   MatMFFD_WP     *hctx;


224:   /* allocate my own private data structure */
225:   PetscNewLog(ctx,MatMFFD_WP,&hctx);
226:   ctx->hctx          = (void*)hctx;
227:   hctx->computenormU = PETSC_FALSE;

229:   /* set the functions I am providing */
230:   ctx->ops->compute        = MatMFFDCompute_WP;
231:   ctx->ops->destroy        = MatMFFDDestroy_WP;
232:   ctx->ops->view           = MatMFFDView_WP;
233:   ctx->ops->setfromoptions = MatMFFDSetFromOptions_WP;

235:   PetscObjectComposeFunctionDynamic((PetscObject)ctx->mat,"MatMFFDWPSetComputeNormU_C","MatMFFDWPSetComputeNormU_P",MatMFFDWPSetComputeNormU_P);

237:   return(0);
238: }
239: EXTERN_C_END