1 #define PETSCSNES_DLL 2 3 #include "include/private/snesimpl.h" /*I "petscsnes.h" I*/ 4 #include "include/private/matimpl.h" 5 #include "src/mat/impls/mffd/mffdimpl.h" 6 7 #undef __FUNCT__ 8 #define __FUNCT__ "MatMFFDComputeJacobian" 9 /*@ 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()). 13 14 Collective on SNES 15 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) 23 24 Level: developer 25 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. 30 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. 35 36 .seealso: MatMFFDGetH(), MatCreateSNESMF(), MatCreateMFFD(), MATMFFD, 37 MatMFFDSetHHistory(), 38 MatMFFDKSPMonitor(), MatMFFDSetFunctionError(), MatMFFDCreate(), SNESSetJacobian() 39 40 @*/ 41 PetscErrorCode PETSCSNES_DLLEXPORT MatMFFDComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy) 42 { 43 PetscErrorCode ierr; 44 PetscFunctionBegin; 45 ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46 ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 47 PetscFunctionReturn(0); 48 } 49 50 PetscErrorCode MatAssemblyEnd_MFFD(Mat,MatAssemblyType); 51 #undef __FUNCT__ 52 #define __FUNCT__ "MatAssemblyEnd_SNESMF" 53 /* 54 MatAssemblyEnd_SNESMF - Calls MatAssemblyEnd_MFFD() and then sets the 55 base from the SNES context 56 57 */ 58 PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt) 59 { 60 PetscErrorCode ierr; 61 MatMFFD j = (MatMFFD)J->data; 62 SNES snes = (SNES)j->funcctx; 63 64 PetscFunctionBegin; 65 ierr = MatAssemblyEnd_MFFD(J,mt);CHKERRQ(ierr); 66 67 ierr = SNESGetSolution(snes,&j->current_u);CHKERRQ(ierr); 68 ierr = SNESGetFunction(snes,&j->current_f,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 69 if (!j->w) { 70 ierr = VecDuplicate(j->current_u, &j->w);CHKERRQ(ierr); 71 } 72 PetscFunctionReturn(0); 73 } 74 75 EXTERN_C_BEGIN 76 extern PetscErrorCode PETSCMAT_DLLEXPORT MatMFFDSetBase_FD(Mat,Vec,Vec); 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 */ 81 #undef __FUNCT__ 82 #define __FUNCT__ "MatMFFDSetBase_SNESMF" 83 PetscErrorCode PETSCMAT_DLLEXPORT MatMFFDSetBase_SNESMF(Mat J,Vec U,Vec F) 84 { 85 PetscErrorCode ierr; 86 87 PetscFunctionBegin; 88 ierr = MatMFFDSetBase_FD(J,U,F);CHKERRQ(ierr); 89 J->ops->assemblyend = MatAssemblyEnd_MFFD; 90 PetscFunctionReturn(0); 91 } 92 EXTERN_C_END 93 94 #undef __FUNCT__ 95 #define __FUNCT__ "MatCreateSNESMF" 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. 101 102 Collective on SNES and Vec 103 104 Input Parameters: 105 . snes - the SNES context 106 107 Output Parameter: 108 . J - the matrix-free matrix 109 110 Level: advanced 111 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. 116 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(). 120 121 .seealso: MatDestroy(), MatMFFDSetFunctionError(), MatMFFDDefaultSetUmin() 122 MatMFFDSetHHistory(), MatMFFDResetHHistory(), MatCreateMFFD(), 123 MatMFFDGetH(),MatMFFDKSPMonitor(), MatMFFDRegisterDynamic), MatMFFDComputeJacobian() 124 125 @*/ 126 PetscErrorCode PETSCSNES_DLLEXPORT MatCreateSNESMF(SNES snes,Mat *J) 127 { 128 PetscErrorCode ierr; 129 PetscInt n,N; 130 131 PetscFunctionBegin; 132 if (!snes->vec_func) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 133 134 ierr = VecGetLocalSize(snes->vec_func,&n);CHKERRQ(ierr); 135 ierr = VecGetSize(snes->vec_func,&N);CHKERRQ(ierr); 136 ierr = MatCreateMFFD(((PetscObject)snes)->comm,n,n,N,N,J);CHKERRQ(ierr); 137 ierr = MatMFFDSetFunction(*J,(PetscErrorCode (*)(void*,Vec,Vec))SNESComputeFunction,snes);CHKERRQ(ierr); 138 (*J)->ops->assemblyend = MatAssemblyEnd_SNESMF; 139 ierr = PetscObjectComposeFunctionDynamic((PetscObject)*J,"MatMFFDSetBase_C","MatMFFDSetBase_SNESMF",MatMFFDSetBase_SNESMF);CHKERRQ(ierr); 140 PetscFunctionReturn(0); 141 } 142 143 144 145 146 147 148