xref: /petsc/src/snes/mf/snesmfj.c (revision 3ec795f1650ef19b9b64b98f5b2fa31503b03712)
163dd3a1aSKris Buschelman #define PETSCSNES_DLL
281e6777dSBarry Smith 
30decc0a3SBarry Smith #include "include/private/snesimpl.h"  /*I  "petscsnes.h" I*/
4*3ec795f1SBarry Smith #include "include/private/matimpl.h"
5*3ec795f1SBarry Smith #include "src/mat/impls/mffd/mffdimpl.h"
681e6777dSBarry Smith 
7e884886fSBarry Smith #undef __FUNCT__
8e884886fSBarry Smith #define __FUNCT__ "MatMFFDComputeJacobian"
9e884886fSBarry Smith /*@
10e884886fSBarry Smith    MatMFFDComputeJacobian - Tells the matrix-free Jacobian object the new location at which
11e884886fSBarry Smith        Jacobian matrix vector products will be computed at, i.e. J(x) * a.
12e884886fSBarry Smith 
13e884886fSBarry Smith    Collective on SNES
14e884886fSBarry Smith 
15e884886fSBarry Smith    Input Parameters:
16e884886fSBarry Smith +   snes - the nonlinear solver context
17e884886fSBarry Smith .   x - the point at which the Jacobian vector products will be performed
18e884886fSBarry Smith .   jac - the matrix-free Jacobian object
19e884886fSBarry Smith .   B - either the same as jac or another matrix type (ignored)
20e884886fSBarry Smith .   flag - not relevent for matrix-free form
21e884886fSBarry Smith -   dummy - the user context (ignored)
22e884886fSBarry Smith 
23e884886fSBarry Smith    Level: developer
24e884886fSBarry Smith 
25e884886fSBarry Smith    Notes:
26e884886fSBarry Smith      This can be passed into SNESSetJacobian() when using a completely matrix-free solver,
27e884886fSBarry Smith      that is the B matrix is also the same matrix operator. This is used when you select
28e884886fSBarry Smith      -mat_mffd but rarely used directly by users.
29e884886fSBarry Smith 
300decc0a3SBarry Smith .seealso: MatMFFDGetH(), MatCreateSNESMF(), MatCreateMFFD(), MATMFFD,
31e884886fSBarry Smith           MatMFFDSetHHistory(),
32e884886fSBarry Smith           MatMFFDKSPMonitor(), MatMFFDSetFunctionError(), MatMFFDCreate(), SNESSetJacobian()
33e884886fSBarry Smith 
34e884886fSBarry Smith @*/
350decc0a3SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT MatMFFDComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy)
36e884886fSBarry Smith {
37e884886fSBarry Smith   PetscErrorCode ierr;
38e884886fSBarry Smith   PetscFunctionBegin;
39e884886fSBarry Smith   ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
40e884886fSBarry Smith   ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
41e884886fSBarry Smith   PetscFunctionReturn(0);
42e884886fSBarry Smith }
43e884886fSBarry Smith 
44*3ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_MFFD(Mat,MatAssemblyType);
45*3ec795f1SBarry Smith #undef __FUNCT__
46*3ec795f1SBarry Smith #define __FUNCT__ "MatAssemblyEnd_SNESMF"
47*3ec795f1SBarry Smith /*
48*3ec795f1SBarry Smith    MatAssemblyEnd_SNESMF - Calls MatAssemblyEnd_MFFD() and then sets the
49*3ec795f1SBarry Smith     base from the SNES context
50*3ec795f1SBarry Smith 
51*3ec795f1SBarry Smith */
52*3ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt)
53*3ec795f1SBarry Smith {
54*3ec795f1SBarry Smith   PetscErrorCode ierr;
55*3ec795f1SBarry Smith   MatMFFD        j = (MatMFFD)J->data;
56*3ec795f1SBarry Smith   SNES           snes = (SNES)j->funcctx;
57*3ec795f1SBarry Smith 
58*3ec795f1SBarry Smith   PetscFunctionBegin;
59*3ec795f1SBarry Smith   ierr = MatAssemblyEnd_MFFD(J,mt);CHKERRQ(ierr);
60*3ec795f1SBarry Smith 
61*3ec795f1SBarry Smith   ierr = SNESGetSolution(snes,&j->current_u);CHKERRQ(ierr);
62*3ec795f1SBarry Smith   ierr = SNESGetFunction(snes,&j->current_f,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
63*3ec795f1SBarry Smith   if (!j->w) {
64*3ec795f1SBarry Smith     ierr = VecDuplicate(j->current_u, &j->w);CHKERRQ(ierr);
65*3ec795f1SBarry Smith   }
66*3ec795f1SBarry Smith   PetscFunctionReturn(0);
67*3ec795f1SBarry Smith }
68*3ec795f1SBarry Smith 
69c5c390f1SBarry Smith #undef __FUNCT__
704a2ae208SSatish Balay #define __FUNCT__ "MatCreateSNESMF"
7152baeb72SSatish Balay /*@
7265f2ba5bSLois Curfman McInnes    MatCreateSNESMF - Creates a matrix-free matrix context for use with
7365f2ba5bSLois Curfman McInnes    a SNES solver.  This matrix can be used as the Jacobian argument for
7465f2ba5bSLois Curfman McInnes    the routine SNESSetJacobian().
75a4d4d686SBarry Smith 
76a4d4d686SBarry Smith    Collective on SNES and Vec
77a4d4d686SBarry Smith 
78a4d4d686SBarry Smith    Input Parameters:
79a4d4d686SBarry Smith +  snes - the SNES context
80a4d4d686SBarry Smith -  x - vector where SNES solution is to be stored.
81a4d4d686SBarry Smith 
82a4d4d686SBarry Smith    Output Parameter:
83a4d4d686SBarry Smith .  J - the matrix-free matrix
84a4d4d686SBarry Smith 
8515091d37SBarry Smith    Level: advanced
8615091d37SBarry Smith 
87a4d4d686SBarry Smith    Notes:
88a4d4d686SBarry Smith    The matrix-free matrix context merely contains the function pointers
89a4d4d686SBarry Smith    and work space for performing finite difference approximations of
9065f2ba5bSLois Curfman McInnes    Jacobian-vector products, F'(u)*a,
919a6cb015SBarry Smith 
929a6cb015SBarry Smith    The default code uses the following approach to compute h
93a4d4d686SBarry Smith 
94a4d4d686SBarry Smith .vb
9565f2ba5bSLois Curfman McInnes      F'(u)*a = [F(u+h*a) - F(u)]/h where
96a4d4d686SBarry Smith      h = error_rel*u'a/||a||^2                        if  |u'a| > umin*||a||_{1}
97a4d4d686SBarry Smith        = error_rel*umin*sign(u'a)*||a||_{1}/||a||^2   otherwise
98a4d4d686SBarry Smith  where
99a4d4d686SBarry Smith      error_rel = square root of relative error in function evaluation
100a4d4d686SBarry Smith      umin = minimum iterate parameter
101a4d4d686SBarry Smith .ve
102*3ec795f1SBarry Smith    (see MATMFFD_WP or MATMFFD_DS)
103a4d4d686SBarry Smith 
104*3ec795f1SBarry Smith    The user can set the error_rel via MatMFFDSetFunctionError() and
105*3ec795f1SBarry Smith    umin via MatMFFDDefaultSetUmin(); see the nonlinear solvers chapter
10665f2ba5bSLois Curfman McInnes    of the users manual for details.
107a4d4d686SBarry Smith 
108a4d4d686SBarry Smith    The user should call MatDestroy() when finished with the matrix-free
109a4d4d686SBarry Smith    matrix context.
110a4d4d686SBarry Smith 
111a4d4d686SBarry Smith    Options Database Keys:
1120decc0a3SBarry Smith +  -mat_mffd_err <error_rel> - Sets error_rel
113*3ec795f1SBarry Smith +  -mat_mffd_type - wp or ds (see MATMFFD_WP or MATMFFD_DS)
1140decc0a3SBarry Smith .  -mat_mffd_unim <umin> - Sets umin (for default PETSc routine that computes h only)
1150decc0a3SBarry Smith -  -mat_mffd_ksp_monitor - KSP monitor routine that prints differencing h
116a4d4d686SBarry Smith 
117a4d4d686SBarry Smith .keywords: SNES, default, matrix-free, create, matrix
118a4d4d686SBarry Smith 
119*3ec795f1SBarry Smith .seealso: MatDestroy(), MatMFFDSetFunctionError(), MatMFFDDefaultSetUmin()
120*3ec795f1SBarry Smith           MatMFFDSetHHistory(), MatMFFDResetHHistory(), MatCreateMF(),
121*3ec795f1SBarry Smith           MatMFFDGetH(),MatMFFDKSPMonitor(), MatMFFDRegisterDynamic), MatMFFDComputeJacobian()
122a4d4d686SBarry Smith 
123a4d4d686SBarry Smith @*/
12463dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT MatCreateSNESMF(SNES snes,Vec x,Mat *J)
125a4d4d686SBarry Smith {
126dfbe8321SBarry Smith   PetscErrorCode ierr;
1271d1367b7SBarry Smith 
1281d1367b7SBarry Smith   PetscFunctionBegin;
1290decc0a3SBarry Smith   ierr = MatCreateMFFD(x,J);CHKERRQ(ierr);
130*3ec795f1SBarry Smith   ierr = MatMFFDSetFunction(*J,(PetscErrorCode (*)(void*, _p_Vec*, _p_Vec*))SNESComputeFunction,snes);CHKERRQ(ierr);
131*3ec795f1SBarry Smith   (*J)->ops->assemblyend = MatAssemblyEnd_SNESMF;
132*3ec795f1SBarry Smith 
1331d1367b7SBarry Smith   PetscFunctionReturn(0);
1341d1367b7SBarry Smith }
1351d1367b7SBarry Smith 
136cf57b110SBarry Smith 
137cf57b110SBarry Smith 
138cf57b110SBarry Smith 
139cf57b110SBarry Smith 
140cf57b110SBarry Smith 
141