181e6777dSBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 3c6db04a5SJed Brown #include <../src/mat/impls/mffd/mffdimpl.h> 4b45d2f2cSJed Brown #include <petsc-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: 31ecaffddaSVictor Eijkhout This can be passed into SNESSetJacobian() as the Jacobian evaluation function argument 32ecaffddaSVictor Eijkhout when using a completely matrix-free solver, 33e884886fSBarry Smith that is the B matrix is also the same matrix operator. This is used when you select 345fe378a3SBarry Smith -snes_mf but rarely used directly by users. (All this routine does is call MatAssemblyBegin/End() on 355fe378a3SBarry Smith the Mat jac. 365fe378a3SBarry Smith 370decc0a3SBarry Smith .seealso: MatMFFDGetH(), MatCreateSNESMF(), MatCreateMFFD(), MATMFFD, 381d0fab5eSBarry Smith MatMFFDSetHHistory(), MatMFFDSetFunctionError(), MatCreateMFFD(), SNESSetJacobian() 39e884886fSBarry Smith 40e884886fSBarry Smith @*/ 417087cfbeSBarry Smith PetscErrorCode MatMFFDComputeJacobian(SNES snes,Vec x,Mat *jac,Mat *B,MatStructure *flag,void *dummy) 42e884886fSBarry Smith { 43e884886fSBarry Smith PetscErrorCode ierr; 445fd66863SKarl Rupp 45e884886fSBarry Smith PetscFunctionBegin; 46e884886fSBarry Smith ierr = MatAssemblyBegin(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 47e884886fSBarry Smith ierr = MatAssemblyEnd(*jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 48e884886fSBarry Smith PetscFunctionReturn(0); 49e884886fSBarry Smith } 50e884886fSBarry Smith 513ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_MFFD(Mat,MatAssemblyType); 52563d23a3SJed Brown EXTERN_C_BEGIN 53a8248277SBarry Smith PetscErrorCode MatMFFDSetBase_MFFD(Mat,Vec,Vec); 54563d23a3SJed Brown EXTERN_C_END 55563d23a3SJed Brown 563ec795f1SBarry Smith #undef __FUNCT__ 573ec795f1SBarry Smith #define __FUNCT__ "MatAssemblyEnd_SNESMF" 583ec795f1SBarry Smith /* 593ec795f1SBarry Smith MatAssemblyEnd_SNESMF - Calls MatAssemblyEnd_MFFD() and then sets the 603ec795f1SBarry Smith base from the SNES context 613ec795f1SBarry Smith 623ec795f1SBarry Smith */ 633ec795f1SBarry Smith PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt) 643ec795f1SBarry Smith { 653ec795f1SBarry Smith PetscErrorCode ierr; 663ec795f1SBarry Smith MatMFFD j = (MatMFFD)J->data; 673ec795f1SBarry Smith SNES snes = (SNES)j->funcctx; 6809ffd372SDmitry Karpeev Vec u,f; 693ec795f1SBarry Smith 703ec795f1SBarry Smith PetscFunctionBegin; 713ec795f1SBarry Smith ierr = MatAssemblyEnd_MFFD(J,mt);CHKERRQ(ierr); 723ec795f1SBarry Smith 73be4711e3SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 740298fd71SBarry Smith ierr = SNESGetFunction(snes,&f,NULL,NULL);CHKERRQ(ierr); 7509ffd372SDmitry Karpeev ierr = MatMFFDSetBase_MFFD(J,u,f);CHKERRQ(ierr); 763ec795f1SBarry Smith PetscFunctionReturn(0); 773ec795f1SBarry Smith } 783ec795f1SBarry Smith 79174415d9SBarry Smith EXTERN_C_BEGIN 80174415d9SBarry Smith /* 81174415d9SBarry Smith This routine resets the MatAssemblyEnd() for the MatMFFD created from MatCreateSNESMF() so that it NO longer 82174415d9SBarry Smith uses the solution in the SNES object to update the base. See the warning in MatCreateSNESMF(). 83174415d9SBarry Smith */ 84174415d9SBarry Smith #undef __FUNCT__ 85174415d9SBarry Smith #define __FUNCT__ "MatMFFDSetBase_SNESMF" 867087cfbeSBarry Smith PetscErrorCode MatMFFDSetBase_SNESMF(Mat J,Vec U,Vec F) 87174415d9SBarry Smith { 88174415d9SBarry Smith PetscErrorCode ierr; 89174415d9SBarry Smith 90174415d9SBarry Smith PetscFunctionBegin; 91885877adSHong Zhang ierr = MatMFFDSetBase_MFFD(J,U,F);CHKERRQ(ierr); 921aa26658SKarl Rupp 93174415d9SBarry Smith J->ops->assemblyend = MatAssemblyEnd_MFFD; 94174415d9SBarry Smith PetscFunctionReturn(0); 95174415d9SBarry Smith } 96174415d9SBarry Smith EXTERN_C_END 97174415d9SBarry Smith 98c5c390f1SBarry Smith #undef __FUNCT__ 994a2ae208SSatish Balay #define __FUNCT__ "MatCreateSNESMF" 10052baeb72SSatish Balay /*@ 10165f2ba5bSLois Curfman McInnes MatCreateSNESMF - Creates a matrix-free matrix context for use with 10265f2ba5bSLois Curfman McInnes a SNES solver. This matrix can be used as the Jacobian argument for 103174415d9SBarry Smith the routine SNESSetJacobian(). See MatCreateMFFD() for details on how 104174415d9SBarry Smith the finite difference computation is done. 105a4d4d686SBarry Smith 106a4d4d686SBarry Smith Collective on SNES and Vec 107a4d4d686SBarry Smith 108a4d4d686SBarry Smith Input Parameters: 109fef1beadSBarry Smith . snes - the SNES context 110a4d4d686SBarry Smith 111a4d4d686SBarry Smith Output Parameter: 112a4d4d686SBarry Smith . J - the matrix-free matrix 113a4d4d686SBarry Smith 11415091d37SBarry Smith Level: advanced 11515091d37SBarry Smith 116174415d9SBarry Smith Warning: 117174415d9SBarry Smith If MatMFFDSetBase() is ever called on jac then this routine will NO longer get 118174415d9SBarry Smith the x from the SNES object and MatMFFDSetBase() must from that point on be used to 119174415d9SBarry Smith change the base vector x. 1209a6cb015SBarry Smith 121174415d9SBarry Smith Notes: The difference between this routine and MatCreateMFFD() is that this matrix 122174415d9SBarry Smith automatically gets the current base vector from the SNES object and not from an 123174415d9SBarry Smith explicit call to MatMFFDSetBase(). 124a4d4d686SBarry Smith 1251d0fab5eSBarry Smith .seealso: MatDestroy(), MatMFFDSetFunctionError(), MatMFFDDSSetUmin() 126174415d9SBarry Smith MatMFFDSetHHistory(), MatMFFDResetHHistory(), MatCreateMFFD(), 1271d0fab5eSBarry Smith MatMFFDGetH(), MatMFFDRegisterDynamic), MatMFFDComputeJacobian() 128a4d4d686SBarry Smith 129a4d4d686SBarry Smith @*/ 1307087cfbeSBarry Smith PetscErrorCode MatCreateSNESMF(SNES snes,Mat *J) 131a4d4d686SBarry Smith { 132dfbe8321SBarry Smith PetscErrorCode ierr; 133fef1beadSBarry Smith PetscInt n,N; 1341d1367b7SBarry Smith 1351d1367b7SBarry Smith PetscFunctionBegin; 136a8248277SBarry Smith if (snes->vec_func) { 137fef1beadSBarry Smith ierr = VecGetLocalSize(snes->vec_func,&n);CHKERRQ(ierr); 138fef1beadSBarry Smith ierr = VecGetSize(snes->vec_func,&N);CHKERRQ(ierr); 139a8248277SBarry Smith } else if (snes->dm) { 140a8248277SBarry Smith Vec tmp; 141a8248277SBarry Smith ierr = DMGetGlobalVector(snes->dm,&tmp);CHKERRQ(ierr); 142a8248277SBarry Smith ierr = VecGetLocalSize(tmp,&n);CHKERRQ(ierr); 143a8248277SBarry Smith ierr = VecGetSize(tmp,&N);CHKERRQ(ierr); 144a8248277SBarry Smith ierr = DMRestoreGlobalVector(snes->dm,&tmp);CHKERRQ(ierr); 145*ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first"); 146*ce94432eSBarry Smith ierr = MatCreateMFFD(PetscObjectComm((PetscObject)snes),n,n,N,N,J);CHKERRQ(ierr); 147ece7ea46SSatish Balay ierr = MatMFFDSetFunction(*J,(PetscErrorCode (*)(void*,Vec,Vec))SNESComputeFunction,snes);CHKERRQ(ierr); 1481aa26658SKarl Rupp 1493ec795f1SBarry Smith (*J)->ops->assemblyend = MatAssemblyEnd_SNESMF; 1501aa26658SKarl Rupp 151174415d9SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)*J,"MatMFFDSetBase_C","MatMFFDSetBase_SNESMF",MatMFFDSetBase_SNESMF);CHKERRQ(ierr); 1521d1367b7SBarry Smith PetscFunctionReturn(0); 1531d1367b7SBarry Smith } 1541d1367b7SBarry Smith 155cf57b110SBarry Smith 156cf57b110SBarry Smith 157cf57b110SBarry Smith 158cf57b110SBarry Smith 159cf57b110SBarry Smith 160