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