xref: /petsc/src/snes/mf/snesmfj.c (revision 00de8ff0695ff394d09a2c60082aeaab5870b6e2)
181e6777dSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>  /*I  "petscsnes.h" I*/
31e25c274SJed Brown #include <petscdm.h>                 /*I  "petscdm.h"   I*/
4c6db04a5SJed Brown #include <../src/mat/impls/mffd/mffdimpl.h>
5b45d2f2cSJed Brown #include <petsc-private/matimpl.h>
681e6777dSBarry Smith 
7e884886fSBarry Smith #undef __FUNCT__
8e884886fSBarry Smith #define __FUNCT__ "MatMFFDComputeJacobian"
95fe378a3SBarry Smith /*@C
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 
143f9fe445SBarry Smith    Logically 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:
32ecaffddaSVictor Eijkhout      This can be passed into SNESSetJacobian() as the Jacobian evaluation function argument
33ecaffddaSVictor Eijkhout      when using a completely matrix-free solver,
34e884886fSBarry Smith      that is the B matrix is also the same matrix operator. This is used when you select
355fe378a3SBarry Smith      -snes_mf but rarely used directly by users. (All this routine does is call MatAssemblyBegin/End() on
365fe378a3SBarry Smith      the Mat jac.
375fe378a3SBarry Smith 
380decc0a3SBarry Smith .seealso: MatMFFDGetH(), MatCreateSNESMF(), MatCreateMFFD(), MATMFFD,
391d0fab5eSBarry Smith           MatMFFDSetHHistory(), MatMFFDSetFunctionError(), MatCreateMFFD(), SNESSetJacobian()
40e884886fSBarry Smith 
41e884886fSBarry Smith @*/
427087cfbeSBarry Smith PetscErrorCode  MatMFFDComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy)
43e884886fSBarry Smith {
44e884886fSBarry Smith   PetscErrorCode ierr;
455fd66863SKarl Rupp 
46e884886fSBarry Smith   PetscFunctionBegin;
47e884886fSBarry Smith   ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
48e884886fSBarry Smith   ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
49e884886fSBarry Smith   PetscFunctionReturn(0);
50e884886fSBarry Smith }
51e884886fSBarry Smith 
523ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_MFFD(Mat,MatAssemblyType);
53563d23a3SJed Brown EXTERN_C_BEGIN
54a8248277SBarry Smith PetscErrorCode MatMFFDSetBase_MFFD(Mat,Vec,Vec);
55563d23a3SJed Brown EXTERN_C_END
56563d23a3SJed Brown 
573ec795f1SBarry Smith #undef __FUNCT__
583ec795f1SBarry Smith #define __FUNCT__ "MatAssemblyEnd_SNESMF"
593ec795f1SBarry Smith /*
603ec795f1SBarry Smith    MatAssemblyEnd_SNESMF - Calls MatAssemblyEnd_MFFD() and then sets the
613ec795f1SBarry Smith     base from the SNES context
623ec795f1SBarry Smith 
633ec795f1SBarry Smith */
643ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt)
653ec795f1SBarry Smith {
663ec795f1SBarry Smith   PetscErrorCode ierr;
673ec795f1SBarry Smith   MatMFFD        j    = (MatMFFD)J->data;
683ec795f1SBarry Smith   SNES           snes = (SNES)j->funcctx;
6909ffd372SDmitry Karpeev   Vec            u,f;
703ec795f1SBarry Smith 
713ec795f1SBarry Smith   PetscFunctionBegin;
723ec795f1SBarry Smith   ierr = MatAssemblyEnd_MFFD(J,mt);CHKERRQ(ierr);
733ec795f1SBarry Smith 
74be4711e3SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
750298fd71SBarry Smith   ierr = SNESGetFunction(snes,&f,NULL,NULL);CHKERRQ(ierr);
7609ffd372SDmitry Karpeev   ierr = MatMFFDSetBase_MFFD(J,u,f);CHKERRQ(ierr);
773ec795f1SBarry Smith   PetscFunctionReturn(0);
783ec795f1SBarry Smith }
793ec795f1SBarry Smith 
80174415d9SBarry Smith EXTERN_C_BEGIN
81174415d9SBarry Smith /*
82174415d9SBarry Smith     This routine resets the MatAssemblyEnd() for the MatMFFD created from MatCreateSNESMF() so that it NO longer
83174415d9SBarry Smith   uses the solution in the SNES object to update the base. See the warning in MatCreateSNESMF().
84174415d9SBarry Smith */
85174415d9SBarry Smith #undef __FUNCT__
86174415d9SBarry Smith #define __FUNCT__ "MatMFFDSetBase_SNESMF"
877087cfbeSBarry Smith PetscErrorCode  MatMFFDSetBase_SNESMF(Mat J,Vec U,Vec F)
88174415d9SBarry Smith {
89174415d9SBarry Smith   PetscErrorCode ierr;
90174415d9SBarry Smith 
91174415d9SBarry Smith   PetscFunctionBegin;
92885877adSHong Zhang   ierr = MatMFFDSetBase_MFFD(J,U,F);CHKERRQ(ierr);
931aa26658SKarl Rupp 
94174415d9SBarry Smith   J->ops->assemblyend = MatAssemblyEnd_MFFD;
95174415d9SBarry Smith   PetscFunctionReturn(0);
96174415d9SBarry Smith }
97174415d9SBarry Smith EXTERN_C_END
98174415d9SBarry Smith 
99c5c390f1SBarry Smith #undef __FUNCT__
1004a2ae208SSatish Balay #define __FUNCT__ "MatCreateSNESMF"
10152baeb72SSatish Balay /*@
10265f2ba5bSLois Curfman McInnes    MatCreateSNESMF - Creates a matrix-free matrix context for use with
10365f2ba5bSLois Curfman McInnes    a SNES solver.  This matrix can be used as the Jacobian argument for
104174415d9SBarry Smith    the routine SNESSetJacobian(). See MatCreateMFFD() for details on how
105174415d9SBarry Smith    the finite difference computation is done.
106a4d4d686SBarry Smith 
107a4d4d686SBarry Smith    Collective on SNES and Vec
108a4d4d686SBarry Smith 
109a4d4d686SBarry Smith    Input Parameters:
110fef1beadSBarry Smith .  snes - the SNES context
111a4d4d686SBarry Smith 
112a4d4d686SBarry Smith    Output Parameter:
113a4d4d686SBarry Smith .  J - the matrix-free matrix
114a4d4d686SBarry Smith 
11515091d37SBarry Smith    Level: advanced
11615091d37SBarry Smith 
117174415d9SBarry Smith    Warning:
118174415d9SBarry Smith       If MatMFFDSetBase() is ever called on jac then this routine will NO longer get
119174415d9SBarry Smith     the x from the SNES object and MatMFFDSetBase() must from that point on be used to
120174415d9SBarry Smith     change the base vector x.
1219a6cb015SBarry Smith 
122174415d9SBarry Smith    Notes: The difference between this routine and MatCreateMFFD() is that this matrix
123174415d9SBarry Smith      automatically gets the current base vector from the SNES object and not from an
124174415d9SBarry Smith      explicit call to MatMFFDSetBase().
125a4d4d686SBarry Smith 
1261d0fab5eSBarry Smith .seealso: MatDestroy(), MatMFFDSetFunctionError(), MatMFFDDSSetUmin()
127174415d9SBarry Smith           MatMFFDSetHHistory(), MatMFFDResetHHistory(), MatCreateMFFD(),
1281d0fab5eSBarry Smith           MatMFFDGetH(), MatMFFDRegisterDynamic), MatMFFDComputeJacobian()
129a4d4d686SBarry Smith 
130a4d4d686SBarry Smith @*/
1317087cfbeSBarry Smith PetscErrorCode  MatCreateSNESMF(SNES snes,Mat *J)
132a4d4d686SBarry Smith {
133dfbe8321SBarry Smith   PetscErrorCode ierr;
134fef1beadSBarry Smith   PetscInt       n,N;
1351d1367b7SBarry Smith 
1361d1367b7SBarry Smith   PetscFunctionBegin;
137a8248277SBarry Smith   if (snes->vec_func) {
138fef1beadSBarry Smith     ierr = VecGetLocalSize(snes->vec_func,&n);CHKERRQ(ierr);
139fef1beadSBarry Smith     ierr = VecGetSize(snes->vec_func,&N);CHKERRQ(ierr);
140a8248277SBarry Smith   } else if (snes->dm) {
141a8248277SBarry Smith     Vec tmp;
142a8248277SBarry Smith     ierr = DMGetGlobalVector(snes->dm,&tmp);CHKERRQ(ierr);
143a8248277SBarry Smith     ierr = VecGetLocalSize(tmp,&n);CHKERRQ(ierr);
144a8248277SBarry Smith     ierr = VecGetSize(tmp,&N);CHKERRQ(ierr);
145a8248277SBarry Smith     ierr = DMRestoreGlobalVector(snes->dm,&tmp);CHKERRQ(ierr);
146ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first");
147ce94432eSBarry Smith   ierr = MatCreateMFFD(PetscObjectComm((PetscObject)snes),n,n,N,N,J);CHKERRQ(ierr);
148ece7ea46SSatish Balay   ierr = MatMFFDSetFunction(*J,(PetscErrorCode (*)(void*,Vec,Vec))SNESComputeFunction,snes);CHKERRQ(ierr);
1491aa26658SKarl Rupp 
1503ec795f1SBarry Smith   (*J)->ops->assemblyend = MatAssemblyEnd_SNESMF;
1511aa26658SKarl Rupp 
152*00de8ff0SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)*J,"MatMFFDSetBase_C","MatMFFDSetBase_SNESMF",MatMFFDSetBase_SNESMF);CHKERRQ(ierr);
1531d1367b7SBarry Smith   PetscFunctionReturn(0);
1541d1367b7SBarry Smith }
1551d1367b7SBarry Smith 
156cf57b110SBarry Smith 
157cf57b110SBarry Smith 
158cf57b110SBarry Smith 
159cf57b110SBarry Smith 
160cf57b110SBarry Smith 
161