1*be1d678aSKris Buschelman #define PETSCMAT_DLL 2*be1d678aSKris Buschelman 3e51e0e81SBarry Smith /* 420563c6bSBarry Smith This provides a simple shell for Fortran (and C programmers) to 520563c6bSBarry Smith create a very simple matrix class for use with KSP without coding 6ed3cc1f0SBarry Smith much of anything. 7e51e0e81SBarry Smith */ 8e51e0e81SBarry Smith 9e090d566SSatish Balay #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 103c94ec11SBarry Smith #include "vecimpl.h" 11e51e0e81SBarry Smith 1220563c6bSBarry Smith typedef struct { 136849ba73SBarry Smith PetscErrorCode (*destroy)(Mat); 146849ba73SBarry Smith PetscErrorCode (*mult)(Mat,Vec,Vec); 15ef66eb69SBarry Smith PetscTruth scale,shift; 16ef66eb69SBarry Smith PetscScalar vscale,vshift; 1720563c6bSBarry Smith void *ctx; 1888cf3e7dSBarry Smith } Mat_Shell; 19e51e0e81SBarry Smith 20711e205bSSatish Balay #undef __FUNCT__ 21711e205bSSatish Balay #define __FUNCT__ "MatShellGetContext" 22b4fd4287SBarry Smith /*@ 23a62d957aSLois Curfman McInnes MatShellGetContext - Returns the user-provided context associated with a shell matrix. 24b4fd4287SBarry Smith 25c7fcc2eaSBarry Smith Not Collective 26c7fcc2eaSBarry Smith 27b4fd4287SBarry Smith Input Parameter: 28b4fd4287SBarry Smith . mat - the matrix, should have been created with MatCreateShell() 29b4fd4287SBarry Smith 30b4fd4287SBarry Smith Output Parameter: 31b4fd4287SBarry Smith . ctx - the user provided context 32b4fd4287SBarry Smith 3315091d37SBarry Smith Level: advanced 3415091d37SBarry Smith 35a62d957aSLois Curfman McInnes Notes: 36a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 37a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 38a62d957aSLois Curfman McInnes 39a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 40a62d957aSLois Curfman McInnes 41ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellSetOperation(), MatShellSetContext() 42b4fd4287SBarry Smith @*/ 43*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellGetContext(Mat mat,void **ctx) 44b4fd4287SBarry Smith { 45dfbe8321SBarry Smith PetscErrorCode ierr; 46273d9f13SBarry Smith PetscTruth flg; 47273d9f13SBarry Smith 483a40ed3dSBarry Smith PetscFunctionBegin; 494482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 504482741eSBarry Smith PetscValidPointer(ctx,2); 51273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 52273d9f13SBarry Smith if (!flg) *ctx = 0; 53b4fd4287SBarry Smith else *ctx = ((Mat_Shell*)(mat->data))->ctx; 543a40ed3dSBarry Smith PetscFunctionReturn(0); 55b4fd4287SBarry Smith } 56b4fd4287SBarry Smith 57711e205bSSatish Balay #undef __FUNCT__ 58711e205bSSatish Balay #define __FUNCT__ "MatDestroy_Shell" 59dfbe8321SBarry Smith PetscErrorCode MatDestroy_Shell(Mat mat) 60e51e0e81SBarry Smith { 61dfbe8321SBarry Smith PetscErrorCode ierr; 6288cf3e7dSBarry Smith Mat_Shell *shell; 63ed3cc1f0SBarry Smith 643a40ed3dSBarry Smith PetscFunctionBegin; 6588cf3e7dSBarry Smith shell = (Mat_Shell*)mat->data; 663a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 67606d414cSSatish Balay ierr = PetscFree(shell);CHKERRQ(ierr); 683a40ed3dSBarry Smith PetscFunctionReturn(0); 69e51e0e81SBarry Smith } 70e51e0e81SBarry Smith 71711e205bSSatish Balay #undef __FUNCT__ 72ef66eb69SBarry Smith #define __FUNCT__ "MatMult_Shell" 73dfbe8321SBarry Smith PetscErrorCode MatMult_Shell(Mat A,Vec x,Vec y) 74ef66eb69SBarry Smith { 75ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)A->data; 76dfbe8321SBarry Smith PetscErrorCode ierr; 77ef66eb69SBarry Smith 78ef66eb69SBarry Smith PetscFunctionBegin; 79ef66eb69SBarry Smith ierr = (*shell->mult)(A,x,y);CHKERRQ(ierr); 80ef66eb69SBarry Smith if (shell->shift && shell->scale) { 81ef66eb69SBarry Smith ierr = VecAXPBY(&shell->vshift,&shell->vscale,x,y);CHKERRQ(ierr); 82ef66eb69SBarry Smith } else if (shell->scale) { 83ef66eb69SBarry Smith ierr = VecScale(&shell->vscale,y);CHKERRQ(ierr); 84ef66eb69SBarry Smith } else { 85ef66eb69SBarry Smith ierr = VecAXPY(&shell->vshift,x,y);CHKERRQ(ierr); 86ef66eb69SBarry Smith } 87ef66eb69SBarry Smith PetscFunctionReturn(0); 88ef66eb69SBarry Smith } 89ef66eb69SBarry Smith 90ef66eb69SBarry Smith #undef __FUNCT__ 91ef66eb69SBarry Smith #define __FUNCT__ "MatShift_Shell" 92dfbe8321SBarry Smith PetscErrorCode MatShift_Shell(const PetscScalar *a,Mat Y) 93ef66eb69SBarry Smith { 94ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 95b24ad042SBarry Smith 96ef66eb69SBarry Smith PetscFunctionBegin; 97ef66eb69SBarry Smith if (shell->scale || shell->shift) { 98ef66eb69SBarry Smith shell->vshift += *a; 99ef66eb69SBarry Smith } else { 100ef66eb69SBarry Smith shell->mult = Y->ops->mult; 101ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 102ef66eb69SBarry Smith shell->vshift = *a; 103ef66eb69SBarry Smith } 104ef66eb69SBarry Smith shell->shift = PETSC_TRUE; 105ef66eb69SBarry Smith PetscFunctionReturn(0); 106ef66eb69SBarry Smith } 107ef66eb69SBarry Smith 108ef66eb69SBarry Smith #undef __FUNCT__ 109ef66eb69SBarry Smith #define __FUNCT__ "MatScale_Shell" 110dfbe8321SBarry Smith PetscErrorCode MatScale_Shell(const PetscScalar *a,Mat Y) 111ef66eb69SBarry Smith { 112ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 113b24ad042SBarry Smith 114ef66eb69SBarry Smith PetscFunctionBegin; 115ef66eb69SBarry Smith if (shell->scale || shell->shift) { 116ef66eb69SBarry Smith shell->vscale *= *a; 117ef66eb69SBarry Smith } else { 118ef66eb69SBarry Smith shell->mult = Y->ops->mult; 119ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 120ef66eb69SBarry Smith shell->vscale = *a; 121ef66eb69SBarry Smith } 122ef66eb69SBarry Smith shell->scale = PETSC_TRUE; 123ef66eb69SBarry Smith PetscFunctionReturn(0); 124ef66eb69SBarry Smith } 125ef66eb69SBarry Smith 126ef66eb69SBarry Smith #undef __FUNCT__ 127ef66eb69SBarry Smith #define __FUNCT__ "MatAssemblyEnd_Shell" 128dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Shell(Mat Y,MatAssemblyType t) 129ef66eb69SBarry Smith { 130ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 131ef66eb69SBarry Smith 132ef66eb69SBarry Smith PetscFunctionBegin; 133ef66eb69SBarry Smith if ((shell->shift || shell->scale) && t == MAT_FINAL_ASSEMBLY) { 134ef66eb69SBarry Smith shell->scale = PETSC_FALSE; 135ef66eb69SBarry Smith shell->shift = PETSC_FALSE; 136ef66eb69SBarry Smith shell->vshift = 0.0; 137ef66eb69SBarry Smith shell->vscale = 1.0; 138ef66eb69SBarry Smith Y->ops->mult = shell->mult; 139ef66eb69SBarry Smith } 140ef66eb69SBarry Smith PetscFunctionReturn(0); 141ef66eb69SBarry Smith } 142ef66eb69SBarry Smith 143ceb03754SKris Buschelman EXTERN PetscErrorCode MatConvert_Shell(Mat,const MatType,MatReuse,Mat*); 144b951964fSBarry Smith 145521d7252SBarry Smith #undef __FUNCT__ 146521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_Shell" 147521d7252SBarry Smith PetscErrorCode MatSetBlockSize_Shell(Mat A,PetscInt bs) 148521d7252SBarry Smith { 149521d7252SBarry Smith PetscFunctionBegin; 150521d7252SBarry Smith PetscFunctionReturn(0); 151521d7252SBarry Smith } 152521d7252SBarry Smith 15309dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 15420563c6bSBarry Smith 0, 15520563c6bSBarry Smith 0, 15620563c6bSBarry Smith 0, 15797304618SKris Buschelman /* 4*/ 0, 15820563c6bSBarry Smith 0, 159b951964fSBarry Smith 0, 160b951964fSBarry Smith 0, 161b951964fSBarry Smith 0, 162b951964fSBarry Smith 0, 16397304618SKris Buschelman /*10*/ 0, 164b951964fSBarry Smith 0, 165b951964fSBarry Smith 0, 166b951964fSBarry Smith 0, 167b951964fSBarry Smith 0, 16897304618SKris Buschelman /*15*/ 0, 169b951964fSBarry Smith 0, 170b951964fSBarry Smith 0, 171b951964fSBarry Smith 0, 172b951964fSBarry Smith 0, 17397304618SKris Buschelman /*20*/ 0, 174ef66eb69SBarry Smith MatAssemblyEnd_Shell, 175b951964fSBarry Smith 0, 176b951964fSBarry Smith 0, 177b951964fSBarry Smith 0, 17897304618SKris Buschelman /*25*/ 0, 179b951964fSBarry Smith 0, 180b951964fSBarry Smith 0, 181b951964fSBarry Smith 0, 182b951964fSBarry Smith 0, 18397304618SKris Buschelman /*30*/ 0, 184b951964fSBarry Smith 0, 185273d9f13SBarry Smith 0, 186b951964fSBarry Smith 0, 187b951964fSBarry Smith 0, 18897304618SKris Buschelman /*35*/ 0, 189b951964fSBarry Smith 0, 190b951964fSBarry Smith 0, 19109dc0095SBarry Smith 0, 19209dc0095SBarry Smith 0, 19397304618SKris Buschelman /*40*/ 0, 19409dc0095SBarry Smith 0, 19509dc0095SBarry Smith 0, 19609dc0095SBarry Smith 0, 19709dc0095SBarry Smith 0, 19897304618SKris Buschelman /*45*/ 0, 199ef66eb69SBarry Smith MatScale_Shell, 200ef66eb69SBarry Smith MatShift_Shell, 20109dc0095SBarry Smith 0, 20209dc0095SBarry Smith 0, 203521d7252SBarry Smith /*50*/ MatSetBlockSize_Shell, 20409dc0095SBarry Smith 0, 20509dc0095SBarry Smith 0, 20609dc0095SBarry Smith 0, 20709dc0095SBarry Smith 0, 20897304618SKris Buschelman /*55*/ 0, 20909dc0095SBarry Smith 0, 21009dc0095SBarry Smith 0, 21109dc0095SBarry Smith 0, 21209dc0095SBarry Smith 0, 21397304618SKris Buschelman /*60*/ 0, 214b9b97703SBarry Smith MatDestroy_Shell, 21509dc0095SBarry Smith 0, 2168a124369SBarry Smith MatGetPetscMaps_Petsc, 217273d9f13SBarry Smith 0, 21897304618SKris Buschelman /*65*/ 0, 219273d9f13SBarry Smith 0, 220273d9f13SBarry Smith 0, 221273d9f13SBarry Smith 0, 222273d9f13SBarry Smith 0, 22397304618SKris Buschelman /*70*/ 0, 22497304618SKris Buschelman MatConvert_Shell, 225273d9f13SBarry Smith 0, 226273d9f13SBarry Smith 0, 22797304618SKris Buschelman 0, 22897304618SKris Buschelman /*75*/ 0, 22997304618SKris Buschelman 0, 23097304618SKris Buschelman 0, 23197304618SKris Buschelman 0, 23297304618SKris Buschelman 0, 23397304618SKris Buschelman /*80*/ 0, 23497304618SKris Buschelman 0, 23597304618SKris Buschelman 0, 23697304618SKris Buschelman 0, 237865e5f61SKris Buschelman 0, 238865e5f61SKris Buschelman /*85*/ 0, 239865e5f61SKris Buschelman 0, 240865e5f61SKris Buschelman 0, 241865e5f61SKris Buschelman 0, 242865e5f61SKris Buschelman 0, 243865e5f61SKris Buschelman /*90*/ 0, 244865e5f61SKris Buschelman 0, 245865e5f61SKris Buschelman 0, 246865e5f61SKris Buschelman 0, 247865e5f61SKris Buschelman 0, 248865e5f61SKris Buschelman /*95*/ 0, 249865e5f61SKris Buschelman 0, 250865e5f61SKris Buschelman 0, 251865e5f61SKris Buschelman 0}; 252273d9f13SBarry Smith 2530bad9183SKris Buschelman /*MC 254fafad747SKris Buschelman MATSHELL - MATSHELL = "shell" - A matrix type to be used to define your own matrix type -- perhaps matrix free. 2550bad9183SKris Buschelman 2560bad9183SKris Buschelman Level: advanced 2570bad9183SKris Buschelman 2580bad9183SKris Buschelman .seealso: MatCreateShell 2590bad9183SKris Buschelman M*/ 2600bad9183SKris Buschelman 261273d9f13SBarry Smith EXTERN_C_BEGIN 262711e205bSSatish Balay #undef __FUNCT__ 263711e205bSSatish Balay #define __FUNCT__ "MatCreate_Shell" 264*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Shell(Mat A) 265273d9f13SBarry Smith { 266273d9f13SBarry Smith Mat_Shell *b; 267dfbe8321SBarry Smith PetscErrorCode ierr; 268273d9f13SBarry Smith 269273d9f13SBarry Smith PetscFunctionBegin; 270273d9f13SBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 271273d9f13SBarry Smith 272b0a32e0cSBarry Smith ierr = PetscNew(Mat_Shell,&b);CHKERRQ(ierr); 27352e6d16bSBarry Smith ierr = PetscLogObjectMemory(A,sizeof(struct _p_Mat)+sizeof(Mat_Shell));CHKERRQ(ierr); 274273d9f13SBarry Smith A->data = (void*)b; 275273d9f13SBarry Smith 276273d9f13SBarry Smith if (A->m == PETSC_DECIDE || A->n == PETSC_DECIDE) { 277e005ede5SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Must give local row and column count for matrix"); 278273d9f13SBarry Smith } 279273d9f13SBarry Smith 280273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->m,&A->M);CHKERRQ(ierr); 281273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->n,&A->N);CHKERRQ(ierr); 282273d9f13SBarry Smith 2838a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->m,A->M,&A->rmap);CHKERRQ(ierr); 2848a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->n,A->N,&A->cmap);CHKERRQ(ierr); 285273d9f13SBarry Smith 286273d9f13SBarry Smith b->ctx = 0; 287ef66eb69SBarry Smith b->scale = PETSC_FALSE; 288ef66eb69SBarry Smith b->shift = PETSC_FALSE; 289ef66eb69SBarry Smith b->vshift = 0.0; 290ef66eb69SBarry Smith b->vscale = 1.0; 291ef66eb69SBarry Smith b->mult = 0; 292273d9f13SBarry Smith A->assembled = PETSC_TRUE; 293273d9f13SBarry Smith A->preallocated = PETSC_TRUE; 294273d9f13SBarry Smith PetscFunctionReturn(0); 295273d9f13SBarry Smith } 296273d9f13SBarry Smith EXTERN_C_END 297e51e0e81SBarry Smith 298711e205bSSatish Balay #undef __FUNCT__ 299711e205bSSatish Balay #define __FUNCT__ "MatCreateShell" 3004b828684SBarry Smith /*@C 301052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 302ff756334SLois Curfman McInnes private data storage format. 303e51e0e81SBarry Smith 304c7fcc2eaSBarry Smith Collective on MPI_Comm 305c7fcc2eaSBarry Smith 306e51e0e81SBarry Smith Input Parameters: 307c7fcc2eaSBarry Smith + comm - MPI communicator 308c7fcc2eaSBarry Smith . m - number of local rows (must be given) 309c7fcc2eaSBarry Smith . n - number of local columns (must be given) 310c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 311c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 312c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 313e51e0e81SBarry Smith 314ff756334SLois Curfman McInnes Output Parameter: 31544cd7ae7SLois Curfman McInnes . A - the matrix 316e51e0e81SBarry Smith 317ff2fd236SBarry Smith Level: advanced 318ff2fd236SBarry Smith 319f39d1f56SLois Curfman McInnes Usage: 3207b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 321f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 322c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 323f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 324f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 325f39d1f56SLois Curfman McInnes 326ff756334SLois Curfman McInnes Notes: 327ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 328ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 329ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 330e51e0e81SBarry Smith 331f38a8d56SBarry Smith Fortran Notes: The context can only be an integer or a PetscObject 332f38a8d56SBarry Smith unfortunately it cannot be a Fortran array or derived type. 333f38a8d56SBarry Smith 334f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 335f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 336645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 337645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 338645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 339645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 340645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 341645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 342645985a0SLois Curfman McInnes For example, 343f39d1f56SLois Curfman McInnes 344f39d1f56SLois Curfman McInnes $ 345f39d1f56SLois Curfman McInnes $ Vec x, y 3467b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 347645985a0SLois Curfman McInnes $ Mat A 348f39d1f56SLois Curfman McInnes $ 349c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 350c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 351f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 352c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 353c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 354c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 355645985a0SLois Curfman McInnes $ MatMult(A,x,y); 356645985a0SLois Curfman McInnes $ MatDestroy(A); 357f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 358645985a0SLois Curfman McInnes $ 359e51e0e81SBarry Smith 3600b627109SLois Curfman McInnes .keywords: matrix, shell, create 3610b627109SLois Curfman McInnes 362ab50ec6bSBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext(), MatShellSetContext() 363e51e0e81SBarry Smith @*/ 364*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateShell(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,void *ctx,Mat *A) 365e51e0e81SBarry Smith { 366dfbe8321SBarry Smith PetscErrorCode ierr; 367ed3cc1f0SBarry Smith 3683a40ed3dSBarry Smith PetscFunctionBegin; 369273d9f13SBarry Smith ierr = MatCreate(comm,m,n,M,N,A);CHKERRQ(ierr); 370273d9f13SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 371273d9f13SBarry Smith ierr = MatShellSetContext(*A,ctx);CHKERRQ(ierr); 372273d9f13SBarry Smith PetscFunctionReturn(0); 373c7fcc2eaSBarry Smith } 374c7fcc2eaSBarry Smith 375711e205bSSatish Balay #undef __FUNCT__ 376711e205bSSatish Balay #define __FUNCT__ "MatShellSetContext" 377273d9f13SBarry Smith /*@C 378273d9f13SBarry Smith MatShellSetContext - sets the context for a shell matrix 379c7fcc2eaSBarry Smith 380273d9f13SBarry Smith Collective on Mat 381c7fcc2eaSBarry Smith 382273d9f13SBarry Smith Input Parameters: 383273d9f13SBarry Smith + mat - the shell matrix 384273d9f13SBarry Smith - ctx - the context 385273d9f13SBarry Smith 386273d9f13SBarry Smith Level: advanced 387273d9f13SBarry Smith 388f38a8d56SBarry Smith Fortran Notes: The context can only be an integer or a PetscObject 389f38a8d56SBarry Smith unfortunately it cannot be a Fortran array or derived type. 390273d9f13SBarry Smith 391273d9f13SBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 392273d9f13SBarry Smith @*/ 393*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellSetContext(Mat mat,void *ctx) 394273d9f13SBarry Smith { 395273d9f13SBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 396dfbe8321SBarry Smith PetscErrorCode ierr; 397273d9f13SBarry Smith PetscTruth flg; 398273d9f13SBarry Smith 399273d9f13SBarry Smith PetscFunctionBegin; 4004482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 401273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 402273d9f13SBarry Smith if (flg) { 403273d9f13SBarry Smith shell->ctx = ctx; 404273d9f13SBarry Smith } 4053a40ed3dSBarry Smith PetscFunctionReturn(0); 406e51e0e81SBarry Smith } 407e51e0e81SBarry Smith 408711e205bSSatish Balay #undef __FUNCT__ 409711e205bSSatish Balay #define __FUNCT__ "MatShellSetOperation" 410c16cb8f2SBarry Smith /*@C 4113a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 4123a3eedf2SBarry Smith a shell matrix. 413e51e0e81SBarry Smith 414fee21e36SBarry Smith Collective on Mat 415fee21e36SBarry Smith 416c7fcc2eaSBarry Smith Input Parameters: 417c7fcc2eaSBarry Smith + mat - the shell matrix 418c7fcc2eaSBarry Smith . op - the name of the operation 419c7fcc2eaSBarry Smith - f - the function that provides the operation. 420c7fcc2eaSBarry Smith 42115091d37SBarry Smith Level: advanced 42215091d37SBarry Smith 423fae171e0SBarry Smith Usage: 424a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 425f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 426c134de8dSSatish Balay $ ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 4270b627109SLois Curfman McInnes 428a62d957aSLois Curfman McInnes Notes: 429e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 4301c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 431a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 4321c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 433a62d957aSLois Curfman McInnes 434a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 435deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 436deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 437deebb3c3SLois Curfman McInnes routines, e.g., 438a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 439a62d957aSLois Curfman McInnes 440a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 441a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 442a62d957aSLois Curfman McInnes set by MatCreateShell(). 443a62d957aSLois Curfman McInnes 444a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 445a62d957aSLois Curfman McInnes 446ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellSetContext() 447e51e0e81SBarry Smith @*/ 448*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellSetOperation(Mat mat,MatOperation op,void (*f)(void)) 449e51e0e81SBarry Smith { 450dfbe8321SBarry Smith PetscErrorCode ierr; 451273d9f13SBarry Smith PetscTruth flg; 452273d9f13SBarry Smith 4533a40ed3dSBarry Smith PetscFunctionBegin; 4544482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 4551c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 456273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 457273d9f13SBarry Smith if (flg) { 458a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 4596849ba73SBarry Smith shell->destroy = (PetscErrorCode (*)(Mat)) f; 4606849ba73SBarry Smith } else mat->ops->destroy = (PetscErrorCode (*)(Mat)) f; 461a62d957aSLois Curfman McInnes } 4626849ba73SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (PetscErrorCode (*)(Mat,PetscViewer)) f; 463c134de8dSSatish Balay else (((void(**)(void))mat->ops)[op]) = f; 464a62d957aSLois Curfman McInnes 4653a40ed3dSBarry Smith PetscFunctionReturn(0); 466e51e0e81SBarry Smith } 467f0479e8cSBarry Smith 468711e205bSSatish Balay #undef __FUNCT__ 469711e205bSSatish Balay #define __FUNCT__ "MatShellGetOperation" 470d4bb536fSBarry Smith /*@C 471d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 472d4bb536fSBarry Smith 473c7fcc2eaSBarry Smith Not Collective 474c7fcc2eaSBarry Smith 475d4bb536fSBarry Smith Input Parameters: 476c7fcc2eaSBarry Smith + mat - the shell matrix 477c7fcc2eaSBarry Smith - op - the name of the operation 478d4bb536fSBarry Smith 479d4bb536fSBarry Smith Output Parameter: 480d4bb536fSBarry Smith . f - the function that provides the operation. 481d4bb536fSBarry Smith 48215091d37SBarry Smith Level: advanced 48315091d37SBarry Smith 484d4bb536fSBarry Smith Notes: 485e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 486d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 487d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 488d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 489d4bb536fSBarry Smith 490d4bb536fSBarry Smith All user-provided functions have the same calling 491d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 492d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 493d4bb536fSBarry Smith routines, e.g., 494d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 495d4bb536fSBarry Smith 496d4bb536fSBarry Smith Within each user-defined routine, the user should call 497d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 498d4bb536fSBarry Smith set by MatCreateShell(). 499d4bb536fSBarry Smith 500d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 501d4bb536fSBarry Smith 502ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation(), MatShellSetContext() 503d4bb536fSBarry Smith @*/ 504*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellGetOperation(Mat mat,MatOperation op,void(**f)(void)) 505d4bb536fSBarry Smith { 506dfbe8321SBarry Smith PetscErrorCode ierr; 507273d9f13SBarry Smith PetscTruth flg; 508273d9f13SBarry Smith 5093a40ed3dSBarry Smith PetscFunctionBegin; 5104482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 511d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 512273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 513273d9f13SBarry Smith if (flg) { 514d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 515c134de8dSSatish Balay *f = (void(*)(void))shell->destroy; 516c7fcc2eaSBarry Smith } else { 517c134de8dSSatish Balay *f = (void(*)(void))mat->ops->destroy; 518d4bb536fSBarry Smith } 519c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 520c134de8dSSatish Balay *f = (void(*)(void))mat->ops->view; 521c7fcc2eaSBarry Smith } else { 522c134de8dSSatish Balay *f = (((void(**)(void))mat->ops)[op]); 523d4bb536fSBarry Smith } 524d4bb536fSBarry Smith 5253a40ed3dSBarry Smith PetscFunctionReturn(0); 526d4bb536fSBarry Smith } 527d4bb536fSBarry Smith 528