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