181e6777dSBarry Smith 2*c6db04a5SJed Brown #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 3*c6db04a5SJed Brown #include <../src/mat/impls/mffd/mffdimpl.h> 4*c6db04a5SJed Brown #include <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: 31e884886fSBarry Smith This can be passed into SNESSetJacobian() when using a completely matrix-free solver, 32e884886fSBarry Smith that is the B matrix is also the same matrix operator. This is used when you select 335fe378a3SBarry Smith -snes_mf but rarely used directly by users. (All this routine does is call MatAssemblyBegin/End() on 345fe378a3SBarry Smith the Mat jac. 355fe378a3SBarry Smith 360decc0a3SBarry Smith .seealso: MatMFFDGetH(), MatCreateSNESMF(), MatCreateMFFD(), MATMFFD, 371d0fab5eSBarry Smith MatMFFDSetHHistory(), MatMFFDSetFunctionError(), MatCreateMFFD(), SNESSetJacobian() 38e884886fSBarry Smith 39e884886fSBarry Smith @*/ 407087cfbeSBarry Smith PetscErrorCode MatMFFDComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy) 41e884886fSBarry Smith { 42e884886fSBarry Smith PetscErrorCode ierr; 43e884886fSBarry Smith PetscFunctionBegin; 44e884886fSBarry Smith ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 45e884886fSBarry Smith ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46e884886fSBarry Smith PetscFunctionReturn(0); 47e884886fSBarry Smith } 48e884886fSBarry Smith 493ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_MFFD(Mat,MatAssemblyType); 503ec795f1SBarry Smith #undef __FUNCT__ 513ec795f1SBarry Smith #define __FUNCT__ "MatAssemblyEnd_SNESMF" 523ec795f1SBarry Smith /* 533ec795f1SBarry Smith MatAssemblyEnd_SNESMF - Calls MatAssemblyEnd_MFFD() and then sets the 543ec795f1SBarry Smith base from the SNES context 553ec795f1SBarry Smith 563ec795f1SBarry Smith */ 573ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt) 583ec795f1SBarry Smith { 593ec795f1SBarry Smith PetscErrorCode ierr; 603ec795f1SBarry Smith MatMFFD j = (MatMFFD)J->data; 613ec795f1SBarry Smith SNES snes = (SNES)j->funcctx; 62be4711e3SBarry Smith Vec u,f; 633ec795f1SBarry Smith 643ec795f1SBarry Smith PetscFunctionBegin; 653ec795f1SBarry Smith ierr = MatAssemblyEnd_MFFD(J,mt);CHKERRQ(ierr); 663ec795f1SBarry Smith 67be4711e3SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 68be4711e3SBarry Smith ierr = SNESGetFunction(snes,&f,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 69be4711e3SBarry Smith ierr = MatMFFDSetBase(J,u,f);CHKERRQ(ierr); 703ec795f1SBarry Smith PetscFunctionReturn(0); 713ec795f1SBarry Smith } 723ec795f1SBarry Smith 73174415d9SBarry Smith EXTERN_C_BEGIN 747087cfbeSBarry Smith extern PetscErrorCode MatMFFDSetBase_MFFD(Mat,Vec,Vec); 75174415d9SBarry Smith /* 76174415d9SBarry Smith This routine resets the MatAssemblyEnd() for the MatMFFD created from MatCreateSNESMF() so that it NO longer 77174415d9SBarry Smith uses the solution in the SNES object to update the base. See the warning in MatCreateSNESMF(). 78174415d9SBarry Smith */ 79174415d9SBarry Smith #undef __FUNCT__ 80174415d9SBarry Smith #define __FUNCT__ "MatMFFDSetBase_SNESMF" 817087cfbeSBarry Smith PetscErrorCode MatMFFDSetBase_SNESMF(Mat J,Vec U,Vec F) 82174415d9SBarry Smith { 83174415d9SBarry Smith PetscErrorCode ierr; 84174415d9SBarry Smith 85174415d9SBarry Smith PetscFunctionBegin; 86885877adSHong Zhang ierr = MatMFFDSetBase_MFFD(J,U,F);CHKERRQ(ierr); 87174415d9SBarry Smith J->ops->assemblyend = MatAssemblyEnd_MFFD; 88174415d9SBarry Smith PetscFunctionReturn(0); 89174415d9SBarry Smith } 90174415d9SBarry Smith EXTERN_C_END 91174415d9SBarry Smith 92c5c390f1SBarry Smith #undef __FUNCT__ 934a2ae208SSatish Balay #define __FUNCT__ "MatCreateSNESMF" 9452baeb72SSatish Balay /*@ 9565f2ba5bSLois Curfman McInnes MatCreateSNESMF - Creates a matrix-free matrix context for use with 9665f2ba5bSLois Curfman McInnes a SNES solver. This matrix can be used as the Jacobian argument for 97174415d9SBarry Smith the routine SNESSetJacobian(). See MatCreateMFFD() for details on how 98174415d9SBarry Smith the finite difference computation is done. 99a4d4d686SBarry Smith 100a4d4d686SBarry Smith Collective on SNES and Vec 101a4d4d686SBarry Smith 102a4d4d686SBarry Smith Input Parameters: 103fef1beadSBarry Smith . snes - the SNES context 104a4d4d686SBarry Smith 105a4d4d686SBarry Smith Output Parameter: 106a4d4d686SBarry Smith . J - the matrix-free matrix 107a4d4d686SBarry Smith 10815091d37SBarry Smith Level: advanced 10915091d37SBarry Smith 110174415d9SBarry Smith Warning: 111174415d9SBarry Smith If MatMFFDSetBase() is ever called on jac then this routine will NO longer get 112174415d9SBarry Smith the x from the SNES object and MatMFFDSetBase() must from that point on be used to 113174415d9SBarry Smith change the base vector x. 1149a6cb015SBarry Smith 115174415d9SBarry Smith Notes: The difference between this routine and MatCreateMFFD() is that this matrix 116174415d9SBarry Smith automatically gets the current base vector from the SNES object and not from an 117174415d9SBarry Smith explicit call to MatMFFDSetBase(). 118a4d4d686SBarry Smith 1191d0fab5eSBarry Smith .seealso: MatDestroy(), MatMFFDSetFunctionError(), MatMFFDDSSetUmin() 120174415d9SBarry Smith MatMFFDSetHHistory(), MatMFFDResetHHistory(), MatCreateMFFD(), 1211d0fab5eSBarry Smith MatMFFDGetH(), MatMFFDRegisterDynamic), MatMFFDComputeJacobian() 122a4d4d686SBarry Smith 123a4d4d686SBarry Smith @*/ 1247087cfbeSBarry Smith PetscErrorCode MatCreateSNESMF(SNES snes,Mat *J) 125a4d4d686SBarry Smith { 126dfbe8321SBarry Smith PetscErrorCode ierr; 127fef1beadSBarry Smith PetscInt n,N; 1281d1367b7SBarry Smith 1291d1367b7SBarry Smith PetscFunctionBegin; 130e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 131fef1beadSBarry Smith 132fef1beadSBarry Smith ierr = VecGetLocalSize(snes->vec_func,&n);CHKERRQ(ierr); 133fef1beadSBarry Smith ierr = VecGetSize(snes->vec_func,&N);CHKERRQ(ierr); 1347adad957SLisandro Dalcin ierr = MatCreateMFFD(((PetscObject)snes)->comm,n,n,N,N,J);CHKERRQ(ierr); 135ece7ea46SSatish Balay ierr = MatMFFDSetFunction(*J,(PetscErrorCode (*)(void*,Vec,Vec))SNESComputeFunction,snes);CHKERRQ(ierr); 1363ec795f1SBarry Smith (*J)->ops->assemblyend = MatAssemblyEnd_SNESMF; 137174415d9SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)*J,"MatMFFDSetBase_C","MatMFFDSetBase_SNESMF",MatMFFDSetBase_SNESMF);CHKERRQ(ierr); 1381d1367b7SBarry Smith PetscFunctionReturn(0); 1391d1367b7SBarry Smith } 1401d1367b7SBarry Smith 141cf57b110SBarry Smith 142cf57b110SBarry Smith 143cf57b110SBarry Smith 144cf57b110SBarry Smith 145cf57b110SBarry Smith 146