Actual source code: snesmfj.c
1: #define PETSCSNES_DLL
3: #include private/snesimpl.h
4: #include private/matimpl.h
5: #include ../src/mat/impls/mffd/mffdimpl.h
9: /*@C
10: MatMFFDComputeJacobian - Tells the matrix-free Jacobian object the new location at which
11: Jacobian matrix vector products will be computed at, i.e. J(x) * a. The x is obtained
12: from the SNES object (using SNESGetSolution()).
14: Collective on SNES
16: Input Parameters:
17: + snes - the nonlinear solver context
18: . x - the point at which the Jacobian vector products will be performed
19: . jac - the matrix-free Jacobian object
20: . B - either the same as jac or another matrix type (ignored)
21: . flag - not relevent for matrix-free form
22: - dummy - the user context (ignored)
24: Level: developer
26: Warning:
27: If MatMFFDSetBase() is ever called on jac then this routine will NO longer get
28: the x from the SNES object and MatMFFDSetBase() must from that point on be used to
29: change the base vector x.
31: Notes:
32: This can be passed into SNESSetJacobian() when using a completely matrix-free solver,
33: that is the B matrix is also the same matrix operator. This is used when you select
34: -snes_mf but rarely used directly by users. (All this routine does is call MatAssemblyBegin/End() on
35: the Mat jac.
37: .seealso: MatMFFDGetH(), MatCreateSNESMF(), MatCreateMFFD(), MATMFFD,
38: MatMFFDSetHHistory(),
39: MatMFFDKSPMonitor(), MatMFFDSetFunctionError(), MatMFFDCreate(), SNESSetJacobian()
41: @*/
42: PetscErrorCode MatMFFDComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy)
43: {
46: MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);
47: MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);
48: return(0);
49: }
51: PetscErrorCode MatAssemblyEnd_MFFD(Mat,MatAssemblyType);
54: /*
55: MatAssemblyEnd_SNESMF - Calls MatAssemblyEnd_MFFD() and then sets the
56: base from the SNES context
58: */
59: PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt)
60: {
62: MatMFFD j = (MatMFFD)J->data;
63: SNES snes = (SNES)j->funcctx;
64: Vec u,f;
67: MatAssemblyEnd_MFFD(J,mt);
69: SNESGetSolution(snes,&u);
70: SNESGetFunction(snes,&f,PETSC_NULL,PETSC_NULL);
71: MatMFFDSetBase(J,u,f);
72: return(0);
73: }
77: /*
78: This routine resets the MatAssemblyEnd() for the MatMFFD created from MatCreateSNESMF() so that it NO longer
79: uses the solution in the SNES object to update the base. See the warning in MatCreateSNESMF().
80: */
83: PetscErrorCode MatMFFDSetBase_SNESMF(Mat J,Vec U,Vec F)
84: {
88: MatMFFDSetBase_MFFD(J,U,F);
89: J->ops->assemblyend = MatAssemblyEnd_MFFD;
90: return(0);
91: }
96: /*@
97: MatCreateSNESMF - Creates a matrix-free matrix context for use with
98: a SNES solver. This matrix can be used as the Jacobian argument for
99: the routine SNESSetJacobian(). See MatCreateMFFD() for details on how
100: the finite difference computation is done.
102: Collective on SNES and Vec
104: Input Parameters:
105: . snes - the SNES context
107: Output Parameter:
108: . J - the matrix-free matrix
110: Level: advanced
112: Warning:
113: If MatMFFDSetBase() is ever called on jac then this routine will NO longer get
114: the x from the SNES object and MatMFFDSetBase() must from that point on be used to
115: change the base vector x.
117: Notes: The difference between this routine and MatCreateMFFD() is that this matrix
118: automatically gets the current base vector from the SNES object and not from an
119: explicit call to MatMFFDSetBase().
121: .seealso: MatDestroy(), MatMFFDSetFunctionError(), MatMFFDDefaultSetUmin()
122: MatMFFDSetHHistory(), MatMFFDResetHHistory(), MatCreateMFFD(),
123: MatMFFDGetH(),MatMFFDKSPMonitor(), MatMFFDRegisterDynamic), MatMFFDComputeJacobian()
124:
125: @*/
126: PetscErrorCode MatCreateSNESMF(SNES snes,Mat *J)
127: {
129: PetscInt n,N;
132: if (!snes->vec_func) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
133:
134: VecGetLocalSize(snes->vec_func,&n);
135: VecGetSize(snes->vec_func,&N);
136: MatCreateMFFD(((PetscObject)snes)->comm,n,n,N,N,J);
137: MatMFFDSetFunction(*J,(PetscErrorCode (*)(void*,Vec,Vec))SNESComputeFunction,snes);
138: (*J)->ops->assemblyend = MatAssemblyEnd_SNESMF;
139: PetscObjectComposeFunctionDynamic((PetscObject)*J,"MatMFFDSetBase_C","MatMFFDSetBase_SNESMF",MatMFFDSetBase_SNESMF);
140: return(0);
141: }