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: }