xref: /petsc/src/snes/mf/snesmfj.c (revision ce94432eddcd14845bc7e8083b7f8ea723b9bf7d)
181e6777dSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>  /*I  "petscsnes.h" I*/
3c6db04a5SJed Brown #include <../src/mat/impls/mffd/mffdimpl.h>
4b45d2f2cSJed Brown #include <petsc-private/matimpl.h>
581e6777dSBarry Smith 
6e884886fSBarry Smith #undef __FUNCT__
7e884886fSBarry Smith #define __FUNCT__ "MatMFFDComputeJacobian"
85fe378a3SBarry Smith /*@C
9e884886fSBarry Smith    MatMFFDComputeJacobian - Tells the matrix-free Jacobian object the new location at which
10174415d9SBarry Smith        Jacobian matrix vector products will be computed at, i.e. J(x) * a. The x is obtained
11174415d9SBarry Smith        from the SNES object (using SNESGetSolution()).
12e884886fSBarry Smith 
133f9fe445SBarry Smith    Logically 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 
25174415d9SBarry Smith    Warning:
26174415d9SBarry Smith       If MatMFFDSetBase() is ever called on jac then this routine will NO longer get
27174415d9SBarry Smith     the x from the SNES object and MatMFFDSetBase() must from that point on be used to
28174415d9SBarry Smith     change the base vector x.
29174415d9SBarry Smith 
30e884886fSBarry Smith    Notes:
31ecaffddaSVictor Eijkhout      This can be passed into SNESSetJacobian() as the Jacobian evaluation function argument
32ecaffddaSVictor Eijkhout      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
345fe378a3SBarry Smith      -snes_mf but rarely used directly by users. (All this routine does is call MatAssemblyBegin/End() on
355fe378a3SBarry Smith      the Mat jac.
365fe378a3SBarry Smith 
370decc0a3SBarry Smith .seealso: MatMFFDGetH(), MatCreateSNESMF(), MatCreateMFFD(), MATMFFD,
381d0fab5eSBarry Smith           MatMFFDSetHHistory(), MatMFFDSetFunctionError(), MatCreateMFFD(), SNESSetJacobian()
39e884886fSBarry Smith 
40e884886fSBarry Smith @*/
417087cfbeSBarry Smith PetscErrorCode  MatMFFDComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy)
42e884886fSBarry Smith {
43e884886fSBarry Smith   PetscErrorCode ierr;
445fd66863SKarl Rupp 
45e884886fSBarry Smith   PetscFunctionBegin;
46e884886fSBarry Smith   ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
47e884886fSBarry Smith   ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
48e884886fSBarry Smith   PetscFunctionReturn(0);
49e884886fSBarry Smith }
50e884886fSBarry Smith 
513ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_MFFD(Mat,MatAssemblyType);
52563d23a3SJed Brown EXTERN_C_BEGIN
53a8248277SBarry Smith PetscErrorCode MatMFFDSetBase_MFFD(Mat,Vec,Vec);
54563d23a3SJed Brown EXTERN_C_END
55563d23a3SJed Brown 
563ec795f1SBarry Smith #undef __FUNCT__
573ec795f1SBarry Smith #define __FUNCT__ "MatAssemblyEnd_SNESMF"
583ec795f1SBarry Smith /*
593ec795f1SBarry Smith    MatAssemblyEnd_SNESMF - Calls MatAssemblyEnd_MFFD() and then sets the
603ec795f1SBarry Smith     base from the SNES context
613ec795f1SBarry Smith 
623ec795f1SBarry Smith */
633ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt)
643ec795f1SBarry Smith {
653ec795f1SBarry Smith   PetscErrorCode ierr;
663ec795f1SBarry Smith   MatMFFD        j    = (MatMFFD)J->data;
673ec795f1SBarry Smith   SNES           snes = (SNES)j->funcctx;
6809ffd372SDmitry Karpeev   Vec            u,f;
693ec795f1SBarry Smith 
703ec795f1SBarry Smith   PetscFunctionBegin;
713ec795f1SBarry Smith   ierr = MatAssemblyEnd_MFFD(J,mt);CHKERRQ(ierr);
723ec795f1SBarry Smith 
73be4711e3SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
740298fd71SBarry Smith   ierr = SNESGetFunction(snes,&f,NULL,NULL);CHKERRQ(ierr);
7509ffd372SDmitry Karpeev   ierr = MatMFFDSetBase_MFFD(J,u,f);CHKERRQ(ierr);
763ec795f1SBarry Smith   PetscFunctionReturn(0);
773ec795f1SBarry Smith }
783ec795f1SBarry Smith 
79174415d9SBarry Smith EXTERN_C_BEGIN
80174415d9SBarry Smith /*
81174415d9SBarry Smith     This routine resets the MatAssemblyEnd() for the MatMFFD created from MatCreateSNESMF() so that it NO longer
82174415d9SBarry Smith   uses the solution in the SNES object to update the base. See the warning in MatCreateSNESMF().
83174415d9SBarry Smith */
84174415d9SBarry Smith #undef __FUNCT__
85174415d9SBarry Smith #define __FUNCT__ "MatMFFDSetBase_SNESMF"
867087cfbeSBarry Smith PetscErrorCode  MatMFFDSetBase_SNESMF(Mat J,Vec U,Vec F)
87174415d9SBarry Smith {
88174415d9SBarry Smith   PetscErrorCode ierr;
89174415d9SBarry Smith 
90174415d9SBarry Smith   PetscFunctionBegin;
91885877adSHong Zhang   ierr = MatMFFDSetBase_MFFD(J,U,F);CHKERRQ(ierr);
921aa26658SKarl Rupp 
93174415d9SBarry Smith   J->ops->assemblyend = MatAssemblyEnd_MFFD;
94174415d9SBarry Smith   PetscFunctionReturn(0);
95174415d9SBarry Smith }
96174415d9SBarry Smith EXTERN_C_END
97174415d9SBarry Smith 
98c5c390f1SBarry Smith #undef __FUNCT__
994a2ae208SSatish Balay #define __FUNCT__ "MatCreateSNESMF"
10052baeb72SSatish Balay /*@
10165f2ba5bSLois Curfman McInnes    MatCreateSNESMF - Creates a matrix-free matrix context for use with
10265f2ba5bSLois Curfman McInnes    a SNES solver.  This matrix can be used as the Jacobian argument for
103174415d9SBarry Smith    the routine SNESSetJacobian(). See MatCreateMFFD() for details on how
104174415d9SBarry Smith    the finite difference computation is done.
105a4d4d686SBarry Smith 
106a4d4d686SBarry Smith    Collective on SNES and Vec
107a4d4d686SBarry Smith 
108a4d4d686SBarry Smith    Input Parameters:
109fef1beadSBarry Smith .  snes - the SNES context
110a4d4d686SBarry Smith 
111a4d4d686SBarry Smith    Output Parameter:
112a4d4d686SBarry Smith .  J - the matrix-free matrix
113a4d4d686SBarry Smith 
11415091d37SBarry Smith    Level: advanced
11515091d37SBarry Smith 
116174415d9SBarry Smith    Warning:
117174415d9SBarry Smith       If MatMFFDSetBase() is ever called on jac then this routine will NO longer get
118174415d9SBarry Smith     the x from the SNES object and MatMFFDSetBase() must from that point on be used to
119174415d9SBarry Smith     change the base vector x.
1209a6cb015SBarry Smith 
121174415d9SBarry Smith    Notes: The difference between this routine and MatCreateMFFD() is that this matrix
122174415d9SBarry Smith      automatically gets the current base vector from the SNES object and not from an
123174415d9SBarry Smith      explicit call to MatMFFDSetBase().
124a4d4d686SBarry Smith 
1251d0fab5eSBarry Smith .seealso: MatDestroy(), MatMFFDSetFunctionError(), MatMFFDDSSetUmin()
126174415d9SBarry Smith           MatMFFDSetHHistory(), MatMFFDResetHHistory(), MatCreateMFFD(),
1271d0fab5eSBarry Smith           MatMFFDGetH(), MatMFFDRegisterDynamic), MatMFFDComputeJacobian()
128a4d4d686SBarry Smith 
129a4d4d686SBarry Smith @*/
1307087cfbeSBarry Smith PetscErrorCode  MatCreateSNESMF(SNES snes,Mat *J)
131a4d4d686SBarry Smith {
132dfbe8321SBarry Smith   PetscErrorCode ierr;
133fef1beadSBarry Smith   PetscInt       n,N;
1341d1367b7SBarry Smith 
1351d1367b7SBarry Smith   PetscFunctionBegin;
136a8248277SBarry Smith   if (snes->vec_func) {
137fef1beadSBarry Smith     ierr = VecGetLocalSize(snes->vec_func,&n);CHKERRQ(ierr);
138fef1beadSBarry Smith     ierr = VecGetSize(snes->vec_func,&N);CHKERRQ(ierr);
139a8248277SBarry Smith   } else if (snes->dm) {
140a8248277SBarry Smith     Vec tmp;
141a8248277SBarry Smith     ierr = DMGetGlobalVector(snes->dm,&tmp);CHKERRQ(ierr);
142a8248277SBarry Smith     ierr = VecGetLocalSize(tmp,&n);CHKERRQ(ierr);
143a8248277SBarry Smith     ierr = VecGetSize(tmp,&N);CHKERRQ(ierr);
144a8248277SBarry Smith     ierr = DMRestoreGlobalVector(snes->dm,&tmp);CHKERRQ(ierr);
145*ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first");
146*ce94432eSBarry Smith   ierr = MatCreateMFFD(PetscObjectComm((PetscObject)snes),n,n,N,N,J);CHKERRQ(ierr);
147ece7ea46SSatish Balay   ierr = MatMFFDSetFunction(*J,(PetscErrorCode (*)(void*,Vec,Vec))SNESComputeFunction,snes);CHKERRQ(ierr);
1481aa26658SKarl Rupp 
1493ec795f1SBarry Smith   (*J)->ops->assemblyend = MatAssemblyEnd_SNESMF;
1501aa26658SKarl Rupp 
151174415d9SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)*J,"MatMFFDSetBase_C","MatMFFDSetBase_SNESMF",MatMFFDSetBase_SNESMF);CHKERRQ(ierr);
1521d1367b7SBarry Smith   PetscFunctionReturn(0);
1531d1367b7SBarry Smith }
1541d1367b7SBarry Smith 
155cf57b110SBarry Smith 
156cf57b110SBarry Smith 
157cf57b110SBarry Smith 
158cf57b110SBarry Smith 
159cf57b110SBarry Smith 
160