xref: /petsc/src/snes/mf/snesmfj.c (revision ece7ea46226218aab8b840c79b7c026dfacb4e03)
163dd3a1aSKris Buschelman #define PETSCSNES_DLL
281e6777dSBarry Smith 
30decc0a3SBarry Smith #include "include/private/snesimpl.h"  /*I  "petscsnes.h" I*/
43ec795f1SBarry Smith #include "include/private/matimpl.h"
53ec795f1SBarry 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
11174415d9SBarry Smith        Jacobian matrix vector products will be computed at, i.e. J(x) * a. The x is obtained
12174415d9SBarry Smith        from the SNES object (using SNESGetSolution()).
13e884886fSBarry Smith 
14e884886fSBarry Smith    Collective on SNES
15e884886fSBarry Smith 
16e884886fSBarry Smith    Input Parameters:
17e884886fSBarry Smith +   snes - the nonlinear solver context
18e884886fSBarry Smith .   x - the point at which the Jacobian vector products will be performed
19e884886fSBarry Smith .   jac - the matrix-free Jacobian object
20e884886fSBarry Smith .   B - either the same as jac or another matrix type (ignored)
21e884886fSBarry Smith .   flag - not relevent for matrix-free form
22e884886fSBarry Smith -   dummy - the user context (ignored)
23e884886fSBarry Smith 
24e884886fSBarry Smith    Level: developer
25e884886fSBarry Smith 
26174415d9SBarry Smith    Warning:
27174415d9SBarry Smith       If MatMFFDSetBase() is ever called on jac then this routine will NO longer get
28174415d9SBarry Smith     the x from the SNES object and MatMFFDSetBase() must from that point on be used to
29174415d9SBarry Smith     change the base vector x.
30174415d9SBarry Smith 
31e884886fSBarry Smith    Notes:
32e884886fSBarry Smith      This can be passed into SNESSetJacobian() when using a completely matrix-free solver,
33e884886fSBarry Smith      that is the B matrix is also the same matrix operator. This is used when you select
34174415d9SBarry Smith      -snes_mf but rarely used directly by users.
35e884886fSBarry Smith 
360decc0a3SBarry Smith .seealso: MatMFFDGetH(), MatCreateSNESMF(), MatCreateMFFD(), MATMFFD,
37e884886fSBarry Smith           MatMFFDSetHHistory(),
38e884886fSBarry Smith           MatMFFDKSPMonitor(), MatMFFDSetFunctionError(), MatMFFDCreate(), SNESSetJacobian()
39e884886fSBarry Smith 
40e884886fSBarry Smith @*/
410decc0a3SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT MatMFFDComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy)
42e884886fSBarry Smith {
43e884886fSBarry Smith   PetscErrorCode ierr;
44e884886fSBarry Smith   PetscFunctionBegin;
45e884886fSBarry Smith   ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
46e884886fSBarry Smith   ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
47e884886fSBarry Smith   PetscFunctionReturn(0);
48e884886fSBarry Smith }
49e884886fSBarry Smith 
503ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_MFFD(Mat,MatAssemblyType);
513ec795f1SBarry Smith #undef __FUNCT__
523ec795f1SBarry Smith #define __FUNCT__ "MatAssemblyEnd_SNESMF"
533ec795f1SBarry Smith /*
543ec795f1SBarry Smith    MatAssemblyEnd_SNESMF - Calls MatAssemblyEnd_MFFD() and then sets the
553ec795f1SBarry Smith     base from the SNES context
563ec795f1SBarry Smith 
573ec795f1SBarry Smith */
583ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt)
593ec795f1SBarry Smith {
603ec795f1SBarry Smith   PetscErrorCode ierr;
613ec795f1SBarry Smith   MatMFFD        j = (MatMFFD)J->data;
623ec795f1SBarry Smith   SNES           snes = (SNES)j->funcctx;
633ec795f1SBarry Smith 
643ec795f1SBarry Smith   PetscFunctionBegin;
653ec795f1SBarry Smith   ierr = MatAssemblyEnd_MFFD(J,mt);CHKERRQ(ierr);
663ec795f1SBarry Smith 
673ec795f1SBarry Smith   ierr = SNESGetSolution(snes,&j->current_u);CHKERRQ(ierr);
683ec795f1SBarry Smith   ierr = SNESGetFunction(snes,&j->current_f,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
693ec795f1SBarry Smith   if (!j->w) {
703ec795f1SBarry Smith     ierr = VecDuplicate(j->current_u, &j->w);CHKERRQ(ierr);
713ec795f1SBarry Smith   }
723ec795f1SBarry Smith   PetscFunctionReturn(0);
733ec795f1SBarry Smith }
743ec795f1SBarry Smith 
75174415d9SBarry Smith EXTERN_C_BEGIN
76174415d9SBarry Smith extern PetscErrorCode PETSCMAT_DLLEXPORT MatMFFDSetBase_FD(Mat,Vec,Vec);
77174415d9SBarry Smith /*
78174415d9SBarry Smith     This routine resets the MatAssemblyEnd() for the MatMFFD created from MatCreateSNESMF() so that it NO longer
79174415d9SBarry Smith   uses the solution in the SNES object to update the base. See the warning in MatCreateSNESMF().
80174415d9SBarry Smith */
81174415d9SBarry Smith #undef __FUNCT__
82174415d9SBarry Smith #define __FUNCT__ "MatMFFDSetBase_SNESMF"
83174415d9SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatMFFDSetBase_SNESMF(Mat J,Vec U,Vec F)
84174415d9SBarry Smith {
85174415d9SBarry Smith   PetscErrorCode ierr;
86174415d9SBarry Smith 
87174415d9SBarry Smith   PetscFunctionBegin;
88174415d9SBarry Smith   ierr = MatMFFDSetBase_FD(J,U,F);CHKERRQ(ierr);
89174415d9SBarry Smith   J->ops->assemblyend = MatAssemblyEnd_MFFD;
90174415d9SBarry Smith   PetscFunctionReturn(0);
91174415d9SBarry Smith }
92174415d9SBarry Smith EXTERN_C_END
93174415d9SBarry Smith 
94c5c390f1SBarry Smith #undef __FUNCT__
954a2ae208SSatish Balay #define __FUNCT__ "MatCreateSNESMF"
9652baeb72SSatish Balay /*@
9765f2ba5bSLois Curfman McInnes    MatCreateSNESMF - Creates a matrix-free matrix context for use with
9865f2ba5bSLois Curfman McInnes    a SNES solver.  This matrix can be used as the Jacobian argument for
99174415d9SBarry Smith    the routine SNESSetJacobian(). See MatCreateMFFD() for details on how
100174415d9SBarry Smith    the finite difference computation is done.
101a4d4d686SBarry Smith 
102a4d4d686SBarry Smith    Collective on SNES and Vec
103a4d4d686SBarry Smith 
104a4d4d686SBarry Smith    Input Parameters:
105fef1beadSBarry Smith .  snes - the SNES context
106a4d4d686SBarry Smith 
107a4d4d686SBarry Smith    Output Parameter:
108a4d4d686SBarry Smith .  J - the matrix-free matrix
109a4d4d686SBarry Smith 
11015091d37SBarry Smith    Level: advanced
11115091d37SBarry Smith 
112174415d9SBarry Smith    Warning:
113174415d9SBarry Smith       If MatMFFDSetBase() is ever called on jac then this routine will NO longer get
114174415d9SBarry Smith     the x from the SNES object and MatMFFDSetBase() must from that point on be used to
115174415d9SBarry Smith     change the base vector x.
1169a6cb015SBarry Smith 
117174415d9SBarry Smith    Notes: The difference between this routine and MatCreateMFFD() is that this matrix
118174415d9SBarry Smith      automatically gets the current base vector from the SNES object and not from an
119174415d9SBarry Smith      explicit call to MatMFFDSetBase().
120a4d4d686SBarry Smith 
1213ec795f1SBarry Smith .seealso: MatDestroy(), MatMFFDSetFunctionError(), MatMFFDDefaultSetUmin()
122174415d9SBarry Smith           MatMFFDSetHHistory(), MatMFFDResetHHistory(), MatCreateMFFD(),
1233ec795f1SBarry Smith           MatMFFDGetH(),MatMFFDKSPMonitor(), MatMFFDRegisterDynamic), MatMFFDComputeJacobian()
124a4d4d686SBarry Smith 
125a4d4d686SBarry Smith @*/
126fef1beadSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT MatCreateSNESMF(SNES snes,Mat *J)
127a4d4d686SBarry Smith {
128dfbe8321SBarry Smith   PetscErrorCode ierr;
129fef1beadSBarry Smith   PetscInt       n,N;
1301d1367b7SBarry Smith 
1311d1367b7SBarry Smith   PetscFunctionBegin;
132fef1beadSBarry Smith   if (!snes->vec_func) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
133fef1beadSBarry Smith 
134fef1beadSBarry Smith   ierr = VecGetLocalSize(snes->vec_func,&n);CHKERRQ(ierr);
135fef1beadSBarry Smith   ierr = VecGetSize(snes->vec_func,&N);CHKERRQ(ierr);
136fef1beadSBarry Smith   ierr = MatCreateMFFD(snes->comm,n,n,N,N,J);CHKERRQ(ierr);
137*ece7ea46SSatish Balay   ierr = MatMFFDSetFunction(*J,(PetscErrorCode (*)(void*,Vec,Vec))SNESComputeFunction,snes);CHKERRQ(ierr);
1383ec795f1SBarry Smith   (*J)->ops->assemblyend = MatAssemblyEnd_SNESMF;
139174415d9SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)*J,"MatMFFDSetBase_C","MatMFFDSetBase_SNESMF",MatMFFDSetBase_SNESMF);CHKERRQ(ierr);
1401d1367b7SBarry Smith   PetscFunctionReturn(0);
1411d1367b7SBarry Smith }
1421d1367b7SBarry Smith 
143cf57b110SBarry Smith 
144cf57b110SBarry Smith 
145cf57b110SBarry Smith 
146cf57b110SBarry Smith 
147cf57b110SBarry Smith 
148