xref: /petsc/src/mat/impls/mffd/wp.c (revision b45d2f2cb7e031d9c0de5873eca80614ca7b863b)
1e884886fSBarry Smith 
2e884886fSBarry Smith /*MC
3e884886fSBarry Smith      MATMFFD_WP - Implements an alternative approach for computing the differencing parameter
4e884886fSBarry Smith         h used with the finite difference based matrix-free Jacobian.  This code
5e884886fSBarry Smith         implements the strategy of M. Pernice and H. Walker:
6e884886fSBarry Smith 
7e884886fSBarry Smith       h = error_rel * sqrt(1 + ||U||) / ||a||
8e884886fSBarry Smith 
9e884886fSBarry Smith       Notes:
10e884886fSBarry Smith         1) || U || does not change between linear iterations so is reused
11e884886fSBarry Smith         2) In GMRES || a || == 1 and so does not need to ever be computed except at restart
12e884886fSBarry Smith            when it is recomputed.
13e884886fSBarry Smith 
14e884886fSBarry Smith       Reference:  M. Pernice and H. F. Walker, "NITSOL: A Newton Iterative
15e884886fSBarry Smith       Solver for Nonlinear Systems", SIAM J. Sci. Stat. Comput.", 1998,
16e884886fSBarry Smith       vol 19, pp. 302--318.
17e884886fSBarry Smith 
18e884886fSBarry Smith    Options Database Keys:
19e884886fSBarry Smith .   -mat_mffd_compute_normu -Compute the norm of u everytime see MatMFFDWPSetComputeNormU()
20e884886fSBarry Smith 
21e884886fSBarry Smith 
22e884886fSBarry Smith    Level: intermediate
23e884886fSBarry Smith 
24e884886fSBarry Smith    Notes: Requires no global collectives when used with GMRES
25e884886fSBarry Smith 
26e884886fSBarry Smith    Formula used:
27e884886fSBarry Smith      F'(u)*a = [F(u+h*a) - F(u)]/h where
28e884886fSBarry Smith 
29e884886fSBarry Smith .seealso: MATMFFD, MatCreateMFFD(), MatCreateSNESMF(), MATMFFD_DS
30e884886fSBarry Smith 
31e884886fSBarry Smith M*/
32e884886fSBarry Smith 
33e884886fSBarry Smith /*
34e884886fSBarry Smith     This include file defines the data structure  MatMFFD that
35e884886fSBarry Smith    includes information about the computation of h. It is shared by
36e884886fSBarry Smith    all implementations that people provide.
37e884886fSBarry Smith 
38e884886fSBarry Smith    See snesmfjdef.c for  a full set of comments on the routines below.
39e884886fSBarry Smith */
40*b45d2f2cSJed Brown #include <petsc-private/matimpl.h>
41c6db04a5SJed Brown #include <../src/mat/impls/mffd/mffdimpl.h>   /*I  "petscmat.h"   I*/
42e884886fSBarry Smith 
43e884886fSBarry Smith typedef struct {
44e884886fSBarry Smith   PetscReal  normUfact;                   /* previous sqrt(1.0 + || U ||) */
45ace3abfcSBarry Smith   PetscBool  computenormU;
46e884886fSBarry Smith } MatMFFD_WP;
47e884886fSBarry Smith 
48e884886fSBarry Smith #undef __FUNCT__
49e884886fSBarry Smith #define __FUNCT__ "MatMFFDCompute_WP"
50e884886fSBarry Smith /*
51e884886fSBarry Smith      MatMFFDCompute_WP - Standard PETSc code for
52e884886fSBarry Smith    computing h with matrix-free finite differences.
53e884886fSBarry Smith 
54e884886fSBarry Smith   Input Parameters:
55e884886fSBarry Smith +   ctx - the matrix free context
56e884886fSBarry Smith .   U - the location at which you want the Jacobian
57e884886fSBarry Smith -   a - the direction you want the derivative
58e884886fSBarry Smith 
59e884886fSBarry Smith   Output Parameter:
60e884886fSBarry Smith .   h - the scale computed
61e884886fSBarry Smith 
62e884886fSBarry Smith */
63ace3abfcSBarry Smith static PetscErrorCode MatMFFDCompute_WP(MatMFFD ctx,Vec U,Vec a,PetscScalar *h,PetscBool  *zeroa)
64e884886fSBarry Smith {
65e884886fSBarry Smith   MatMFFD_WP    *hctx = (MatMFFD_WP*)ctx->hctx;
6651a79602SBarry Smith   PetscReal      normU,norma;
67e884886fSBarry Smith   PetscErrorCode ierr;
68e884886fSBarry Smith 
69e884886fSBarry Smith   PetscFunctionBegin;
70e884886fSBarry Smith   if (!(ctx->count % ctx->recomputeperiod)) {
7151a79602SBarry Smith     if (hctx->computenormU || !ctx->ncurrenth) {
72e884886fSBarry Smith       ierr = VecNorm(U,NORM_2,&normU);CHKERRQ(ierr);
738f1a2a5eSBarry Smith       hctx->normUfact = PetscSqrtReal(1.0+normU);
74e884886fSBarry Smith     }
7551a79602SBarry Smith     ierr = VecNorm(a,NORM_2,&norma);CHKERRQ(ierr);
76e884886fSBarry Smith     if (norma == 0.0) {
77e884886fSBarry Smith       *zeroa = PETSC_TRUE;
78e884886fSBarry Smith       PetscFunctionReturn(0);
79e884886fSBarry Smith     }
80e884886fSBarry Smith     *zeroa = PETSC_FALSE;
81e884886fSBarry Smith     *h = ctx->error_rel*hctx->normUfact/norma;
82e884886fSBarry Smith   } else {
83e884886fSBarry Smith     *h = ctx->currenth;
84e884886fSBarry Smith   }
85e884886fSBarry Smith   PetscFunctionReturn(0);
86e884886fSBarry Smith }
87e884886fSBarry Smith 
88e884886fSBarry Smith #undef __FUNCT__
89e884886fSBarry Smith #define __FUNCT__ "MatMFFDView_WP"
90e884886fSBarry Smith /*
91e884886fSBarry Smith    MatMFFDView_WP - Prints information about this particular
92e884886fSBarry Smith      method for computing h. Note that this does not print the general
93e884886fSBarry Smith      information about the matrix free, that is printed by the calling
94e884886fSBarry Smith      routine.
95e884886fSBarry Smith 
96e884886fSBarry Smith   Input Parameters:
97e884886fSBarry Smith +   ctx - the matrix free context
98e884886fSBarry Smith -   viewer - the PETSc viewer
99e884886fSBarry Smith 
100e884886fSBarry Smith */
101e884886fSBarry Smith static PetscErrorCode MatMFFDView_WP(MatMFFD ctx,PetscViewer viewer)
102e884886fSBarry Smith {
103e884886fSBarry Smith   MatMFFD_WP     *hctx = (MatMFFD_WP *)ctx->hctx;
104e884886fSBarry Smith   PetscErrorCode ierr;
105ace3abfcSBarry Smith   PetscBool      iascii;
106e884886fSBarry Smith 
107e884886fSBarry Smith   PetscFunctionBegin;
1082692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
109e884886fSBarry Smith   if (iascii) {
110e884886fSBarry Smith     if (hctx->computenormU){ierr =  PetscViewerASCIIPrintf(viewer,"    Computes normU\n");CHKERRQ(ierr);}
111e884886fSBarry Smith     else                   {ierr =  PetscViewerASCIIPrintf(viewer,"    Does not compute normU\n");CHKERRQ(ierr);}
1129c6ac3b3SBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for SNES matrix-free WP",((PetscObject)viewer)->type_name);
113e884886fSBarry Smith   PetscFunctionReturn(0);
114e884886fSBarry Smith }
115e884886fSBarry Smith 
116e884886fSBarry Smith #undef __FUNCT__
117e884886fSBarry Smith #define __FUNCT__ "MatMFFDSetFromOptions_WP"
118e884886fSBarry Smith /*
119e884886fSBarry Smith    MatMFFDSetFromOptions_WP - Looks in the options database for
120e884886fSBarry Smith      any options appropriate for this method
121e884886fSBarry Smith 
122e884886fSBarry Smith   Input Parameter:
123e884886fSBarry Smith .  ctx - the matrix free context
124e884886fSBarry Smith 
125e884886fSBarry Smith */
126e884886fSBarry Smith static PetscErrorCode MatMFFDSetFromOptions_WP(MatMFFD ctx)
127e884886fSBarry Smith {
128e884886fSBarry Smith   PetscErrorCode ierr;
129e884886fSBarry Smith   MatMFFD_WP     *hctx = (MatMFFD_WP*)ctx->hctx;
130e884886fSBarry Smith 
131e884886fSBarry Smith   PetscFunctionBegin;
132e884886fSBarry Smith   ierr = PetscOptionsHead("Walker-Pernice options");CHKERRQ(ierr);
1339c6ac3b3SBarry Smith     ierr = PetscOptionsBool("-mat_mffd_compute_normu","Compute the norm of u","MatMFFDWPSetComputeNormU", hctx->computenormU,&hctx->computenormU,0);CHKERRQ(ierr);
134e884886fSBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
135e884886fSBarry Smith   PetscFunctionReturn(0);
136e884886fSBarry Smith }
137e884886fSBarry Smith 
138e884886fSBarry Smith #undef __FUNCT__
139e884886fSBarry Smith #define __FUNCT__ "MatMFFDDestroy_WP"
140e884886fSBarry Smith /*
141e884886fSBarry Smith    MatMFFDDestroy_WP - Frees the space allocated by
1421d0fab5eSBarry Smith        MatCreateMFFD_WP().
143e884886fSBarry Smith 
144e884886fSBarry Smith   Input Parameter:
145e884886fSBarry Smith .  ctx - the matrix free context
146e884886fSBarry Smith 
147e884886fSBarry Smith    Notes: does not free the ctx, that is handled by the calling routine
148e884886fSBarry Smith 
149e884886fSBarry Smith */
150e884886fSBarry Smith static PetscErrorCode MatMFFDDestroy_WP(MatMFFD ctx)
151e884886fSBarry Smith {
152e884886fSBarry Smith   PetscErrorCode ierr;
153e884886fSBarry Smith   PetscFunctionBegin;
154e884886fSBarry Smith   ierr = PetscFree(ctx->hctx);CHKERRQ(ierr);
155e884886fSBarry Smith   PetscFunctionReturn(0);
156e884886fSBarry Smith }
157e884886fSBarry Smith 
158e884886fSBarry Smith EXTERN_C_BEGIN
159e884886fSBarry Smith #undef __FUNCT__
160e884886fSBarry Smith #define __FUNCT__ "MatMFFDWPSetComputeNormU_P"
1617087cfbeSBarry Smith PetscErrorCode  MatMFFDWPSetComputeNormU_P(Mat mat,PetscBool  flag)
162e884886fSBarry Smith {
163e884886fSBarry Smith   MatMFFD     ctx = (MatMFFD)mat->data;
164e884886fSBarry Smith   MatMFFD_WP  *hctx = (MatMFFD_WP*)ctx->hctx;
165e884886fSBarry Smith 
166e884886fSBarry Smith   PetscFunctionBegin;
167e884886fSBarry Smith   hctx->computenormU = flag;
168e884886fSBarry Smith   PetscFunctionReturn(0);
169e884886fSBarry Smith }
170e884886fSBarry Smith EXTERN_C_END
171e884886fSBarry Smith 
172e884886fSBarry Smith #undef __FUNCT__
173e884886fSBarry Smith #define __FUNCT__ "MatMFFDWPSetComputeNormU"
174e884886fSBarry Smith /*@
175e884886fSBarry Smith     MatMFFDWPSetComputeNormU - Sets whether it computes the ||U|| used by the WP
176e884886fSBarry Smith              PETSc routine for computing h. With any Krylov solver this need only
177e884886fSBarry Smith              be computed during the first iteration and kept for later.
178e884886fSBarry Smith 
179e884886fSBarry Smith   Input Parameters:
180e884886fSBarry Smith +   A - the matrix created with MatCreateSNESMF()
181e884886fSBarry Smith -   flag - PETSC_TRUE causes it to compute ||U||, PETSC_FALSE uses the previous value
182e884886fSBarry Smith 
183e884886fSBarry Smith   Options Database Key:
184e884886fSBarry Smith .   -mat_mffd_compute_normu <true,false> - true by default, false can save calculations but you
185e884886fSBarry Smith               must be sure that ||U|| has not changed in the mean time.
186e884886fSBarry Smith 
187e884886fSBarry Smith   Level: advanced
188e884886fSBarry Smith 
189e884886fSBarry Smith   Notes:
190e884886fSBarry Smith    See the manual page for MATMFFD_WP for a complete description of the
191e884886fSBarry Smith    algorithm used to compute h.
192e884886fSBarry Smith 
193e884886fSBarry Smith .seealso: MatMFFDSetFunctionError(), MatCreateSNESMF()
194e884886fSBarry Smith 
195e884886fSBarry Smith @*/
1967087cfbeSBarry Smith PetscErrorCode  MatMFFDWPSetComputeNormU(Mat A,PetscBool  flag)
197e884886fSBarry Smith {
1984ac538c5SBarry Smith   PetscErrorCode ierr;
199e884886fSBarry Smith 
200e884886fSBarry Smith   PetscFunctionBegin;
2010700a824SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2024ac538c5SBarry Smith   ierr = PetscTryMethod(A,"MatMFFDWPSetComputeNormU_C",(Mat,PetscBool),(A,flag));CHKERRQ(ierr);
203e884886fSBarry Smith   PetscFunctionReturn(0);
204e884886fSBarry Smith }
205e884886fSBarry Smith 
206e884886fSBarry Smith EXTERN_C_BEGIN
207e884886fSBarry Smith #undef __FUNCT__
2081d0fab5eSBarry Smith #define __FUNCT__ "MatCreateMFFD_WP"
209e884886fSBarry Smith /*
2101d0fab5eSBarry Smith      MatCreateMFFD_WP - Standard PETSc code for
211e884886fSBarry Smith    computing h with matrix-free finite differences.
212e884886fSBarry Smith 
213e884886fSBarry Smith    Input Parameter:
2141d0fab5eSBarry Smith .  ctx - the matrix free context created by MatCreateMFFD()
215e884886fSBarry Smith 
216e884886fSBarry Smith */
2177087cfbeSBarry Smith PetscErrorCode  MatCreateMFFD_WP(MatMFFD ctx)
218e884886fSBarry Smith {
219e884886fSBarry Smith   PetscErrorCode ierr;
220e884886fSBarry Smith   MatMFFD_WP     *hctx;
221e884886fSBarry Smith 
222e884886fSBarry Smith   PetscFunctionBegin;
223e884886fSBarry Smith 
224e884886fSBarry Smith   /* allocate my own private data structure */
22538f2d2fdSLisandro Dalcin   ierr               = PetscNewLog(ctx,MatMFFD_WP,&hctx);CHKERRQ(ierr);
226e884886fSBarry Smith   ctx->hctx          = (void*)hctx;
227e884886fSBarry Smith   hctx->computenormU = PETSC_FALSE;
228e884886fSBarry Smith 
229e884886fSBarry Smith   /* set the functions I am providing */
230e884886fSBarry Smith   ctx->ops->compute        = MatMFFDCompute_WP;
231e884886fSBarry Smith   ctx->ops->destroy        = MatMFFDDestroy_WP;
232e884886fSBarry Smith   ctx->ops->view           = MatMFFDView_WP;
233e884886fSBarry Smith   ctx->ops->setfromoptions = MatMFFDSetFromOptions_WP;
234e884886fSBarry Smith 
2359c6ac3b3SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ctx->mat,"MatMFFDWPSetComputeNormU_C","MatMFFDWPSetComputeNormU_P",MatMFFDWPSetComputeNormU_P);CHKERRQ(ierr);
236e884886fSBarry Smith 
237e884886fSBarry Smith   PetscFunctionReturn(0);
238e884886fSBarry Smith }
239e884886fSBarry Smith EXTERN_C_END
240e884886fSBarry Smith 
241e884886fSBarry Smith 
242e884886fSBarry Smith 
243