1e51e0e81SBarry Smith /* 220563c6bSBarry Smith This provides a simple shell for Fortran (and C programmers) to 320563c6bSBarry Smith create a very simple matrix class for use with KSP without coding 4ed3cc1f0SBarry Smith much of anything. 5e51e0e81SBarry Smith */ 6e51e0e81SBarry Smith 7e090d566SSatish Balay #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 83c94ec11SBarry Smith #include "vecimpl.h" 9e51e0e81SBarry Smith 1020563c6bSBarry Smith typedef struct { 116849ba73SBarry Smith PetscErrorCode (*destroy)(Mat); 126849ba73SBarry Smith PetscErrorCode (*mult)(Mat,Vec,Vec); 13ef66eb69SBarry Smith PetscTruth scale,shift; 14ef66eb69SBarry Smith PetscScalar vscale,vshift; 1520563c6bSBarry Smith void *ctx; 1688cf3e7dSBarry Smith } Mat_Shell; 17e51e0e81SBarry Smith 18711e205bSSatish Balay #undef __FUNCT__ 19711e205bSSatish Balay #define __FUNCT__ "MatShellGetContext" 20b4fd4287SBarry Smith /*@ 21a62d957aSLois Curfman McInnes MatShellGetContext - Returns the user-provided context associated with a shell matrix. 22b4fd4287SBarry Smith 23c7fcc2eaSBarry Smith Not Collective 24c7fcc2eaSBarry Smith 25b4fd4287SBarry Smith Input Parameter: 26b4fd4287SBarry Smith . mat - the matrix, should have been created with MatCreateShell() 27b4fd4287SBarry Smith 28b4fd4287SBarry Smith Output Parameter: 29b4fd4287SBarry Smith . ctx - the user provided context 30b4fd4287SBarry Smith 3115091d37SBarry Smith Level: advanced 3215091d37SBarry Smith 33a62d957aSLois Curfman McInnes Notes: 34a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 35a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 36a62d957aSLois Curfman McInnes 37a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 38a62d957aSLois Curfman McInnes 39ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellSetOperation(), MatShellSetContext() 40b4fd4287SBarry Smith @*/ 41dfbe8321SBarry Smith PetscErrorCode MatShellGetContext(Mat mat,void **ctx) 42b4fd4287SBarry Smith { 43dfbe8321SBarry Smith PetscErrorCode ierr; 44273d9f13SBarry Smith PetscTruth flg; 45273d9f13SBarry Smith 463a40ed3dSBarry Smith PetscFunctionBegin; 474482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 484482741eSBarry Smith PetscValidPointer(ctx,2); 49273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 50273d9f13SBarry Smith if (!flg) *ctx = 0; 51b4fd4287SBarry Smith else *ctx = ((Mat_Shell*)(mat->data))->ctx; 523a40ed3dSBarry Smith PetscFunctionReturn(0); 53b4fd4287SBarry Smith } 54b4fd4287SBarry Smith 55711e205bSSatish Balay #undef __FUNCT__ 56711e205bSSatish Balay #define __FUNCT__ "MatDestroy_Shell" 57dfbe8321SBarry Smith PetscErrorCode MatDestroy_Shell(Mat mat) 58e51e0e81SBarry Smith { 59dfbe8321SBarry Smith PetscErrorCode ierr; 6088cf3e7dSBarry Smith Mat_Shell *shell; 61ed3cc1f0SBarry Smith 623a40ed3dSBarry Smith PetscFunctionBegin; 6388cf3e7dSBarry Smith shell = (Mat_Shell*)mat->data; 643a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 65606d414cSSatish Balay ierr = PetscFree(shell);CHKERRQ(ierr); 663a40ed3dSBarry Smith PetscFunctionReturn(0); 67e51e0e81SBarry Smith } 68e51e0e81SBarry Smith 69711e205bSSatish Balay #undef __FUNCT__ 70ef66eb69SBarry Smith #define __FUNCT__ "MatMult_Shell" 71dfbe8321SBarry Smith PetscErrorCode MatMult_Shell(Mat A,Vec x,Vec y) 72ef66eb69SBarry Smith { 73ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)A->data; 74dfbe8321SBarry Smith PetscErrorCode ierr; 75ef66eb69SBarry Smith 76ef66eb69SBarry Smith PetscFunctionBegin; 77ef66eb69SBarry Smith ierr = (*shell->mult)(A,x,y);CHKERRQ(ierr); 78ef66eb69SBarry Smith if (shell->shift && shell->scale) { 79ef66eb69SBarry Smith ierr = VecAXPBY(&shell->vshift,&shell->vscale,x,y);CHKERRQ(ierr); 80ef66eb69SBarry Smith } else if (shell->scale) { 81ef66eb69SBarry Smith ierr = VecScale(&shell->vscale,y);CHKERRQ(ierr); 82ef66eb69SBarry Smith } else { 83ef66eb69SBarry Smith ierr = VecAXPY(&shell->vshift,x,y);CHKERRQ(ierr); 84ef66eb69SBarry Smith } 85ef66eb69SBarry Smith PetscFunctionReturn(0); 86ef66eb69SBarry Smith } 87ef66eb69SBarry Smith 88ef66eb69SBarry Smith #undef __FUNCT__ 89ef66eb69SBarry Smith #define __FUNCT__ "MatShift_Shell" 90dfbe8321SBarry Smith PetscErrorCode MatShift_Shell(const PetscScalar *a,Mat Y) 91ef66eb69SBarry Smith { 92ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 93b24ad042SBarry Smith 94ef66eb69SBarry Smith PetscFunctionBegin; 95ef66eb69SBarry Smith if (shell->scale || shell->shift) { 96ef66eb69SBarry Smith shell->vshift += *a; 97ef66eb69SBarry Smith } else { 98ef66eb69SBarry Smith shell->mult = Y->ops->mult; 99ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 100ef66eb69SBarry Smith shell->vshift = *a; 101ef66eb69SBarry Smith } 102ef66eb69SBarry Smith shell->shift = PETSC_TRUE; 103ef66eb69SBarry Smith PetscFunctionReturn(0); 104ef66eb69SBarry Smith } 105ef66eb69SBarry Smith 106ef66eb69SBarry Smith #undef __FUNCT__ 107ef66eb69SBarry Smith #define __FUNCT__ "MatScale_Shell" 108dfbe8321SBarry Smith PetscErrorCode MatScale_Shell(const PetscScalar *a,Mat Y) 109ef66eb69SBarry Smith { 110ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 111b24ad042SBarry Smith 112ef66eb69SBarry Smith PetscFunctionBegin; 113ef66eb69SBarry Smith if (shell->scale || shell->shift) { 114ef66eb69SBarry Smith shell->vscale *= *a; 115ef66eb69SBarry Smith } else { 116ef66eb69SBarry Smith shell->mult = Y->ops->mult; 117ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 118ef66eb69SBarry Smith shell->vscale = *a; 119ef66eb69SBarry Smith } 120ef66eb69SBarry Smith shell->scale = PETSC_TRUE; 121ef66eb69SBarry Smith PetscFunctionReturn(0); 122ef66eb69SBarry Smith } 123ef66eb69SBarry Smith 124ef66eb69SBarry Smith #undef __FUNCT__ 125ef66eb69SBarry Smith #define __FUNCT__ "MatAssemblyEnd_Shell" 126dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Shell(Mat Y,MatAssemblyType t) 127ef66eb69SBarry Smith { 128ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 129ef66eb69SBarry Smith 130ef66eb69SBarry Smith PetscFunctionBegin; 131ef66eb69SBarry Smith if ((shell->shift || shell->scale) && t == MAT_FINAL_ASSEMBLY) { 132ef66eb69SBarry Smith shell->scale = PETSC_FALSE; 133ef66eb69SBarry Smith shell->shift = PETSC_FALSE; 134ef66eb69SBarry Smith shell->vshift = 0.0; 135ef66eb69SBarry Smith shell->vscale = 1.0; 136ef66eb69SBarry Smith Y->ops->mult = shell->mult; 137ef66eb69SBarry Smith } 138ef66eb69SBarry Smith PetscFunctionReturn(0); 139ef66eb69SBarry Smith } 140ef66eb69SBarry Smith 141dfbe8321SBarry Smith EXTERN PetscErrorCode MatConvert_Shell(Mat,const MatType,Mat*); 142b951964fSBarry Smith 143*521d7252SBarry Smith #undef __FUNCT__ 144*521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_Shell" 145*521d7252SBarry Smith PetscErrorCode MatSetBlockSize_Shell(Mat A,PetscInt bs) 146*521d7252SBarry Smith { 147*521d7252SBarry Smith PetscFunctionBegin; 148*521d7252SBarry Smith PetscFunctionReturn(0); 149*521d7252SBarry Smith } 150*521d7252SBarry Smith 15109dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 15220563c6bSBarry Smith 0, 15320563c6bSBarry Smith 0, 15420563c6bSBarry Smith 0, 15597304618SKris Buschelman /* 4*/ 0, 15620563c6bSBarry Smith 0, 157b951964fSBarry Smith 0, 158b951964fSBarry Smith 0, 159b951964fSBarry Smith 0, 160b951964fSBarry Smith 0, 16197304618SKris Buschelman /*10*/ 0, 162b951964fSBarry Smith 0, 163b951964fSBarry Smith 0, 164b951964fSBarry Smith 0, 165b951964fSBarry Smith 0, 16697304618SKris Buschelman /*15*/ 0, 167b951964fSBarry Smith 0, 168b951964fSBarry Smith 0, 169b951964fSBarry Smith 0, 170b951964fSBarry Smith 0, 17197304618SKris Buschelman /*20*/ 0, 172ef66eb69SBarry Smith MatAssemblyEnd_Shell, 173b951964fSBarry Smith 0, 174b951964fSBarry Smith 0, 175b951964fSBarry Smith 0, 17697304618SKris Buschelman /*25*/ 0, 177b951964fSBarry Smith 0, 178b951964fSBarry Smith 0, 179b951964fSBarry Smith 0, 180b951964fSBarry Smith 0, 18197304618SKris Buschelman /*30*/ 0, 182b951964fSBarry Smith 0, 183273d9f13SBarry Smith 0, 184b951964fSBarry Smith 0, 185b951964fSBarry Smith 0, 18697304618SKris Buschelman /*35*/ 0, 187b951964fSBarry Smith 0, 188b951964fSBarry Smith 0, 18909dc0095SBarry Smith 0, 19009dc0095SBarry Smith 0, 19197304618SKris Buschelman /*40*/ 0, 19209dc0095SBarry Smith 0, 19309dc0095SBarry Smith 0, 19409dc0095SBarry Smith 0, 19509dc0095SBarry Smith 0, 19697304618SKris Buschelman /*45*/ 0, 197ef66eb69SBarry Smith MatScale_Shell, 198ef66eb69SBarry Smith MatShift_Shell, 19909dc0095SBarry Smith 0, 20009dc0095SBarry Smith 0, 201*521d7252SBarry Smith /*50*/ MatSetBlockSize_Shell, 20209dc0095SBarry Smith 0, 20309dc0095SBarry Smith 0, 20409dc0095SBarry Smith 0, 20509dc0095SBarry Smith 0, 20697304618SKris Buschelman /*55*/ 0, 20709dc0095SBarry Smith 0, 20809dc0095SBarry Smith 0, 20909dc0095SBarry Smith 0, 21009dc0095SBarry Smith 0, 21197304618SKris Buschelman /*60*/ 0, 212b9b97703SBarry Smith MatDestroy_Shell, 21309dc0095SBarry Smith 0, 2148a124369SBarry Smith MatGetPetscMaps_Petsc, 215273d9f13SBarry Smith 0, 21697304618SKris Buschelman /*65*/ 0, 217273d9f13SBarry Smith 0, 218273d9f13SBarry Smith 0, 219273d9f13SBarry Smith 0, 220273d9f13SBarry Smith 0, 22197304618SKris Buschelman /*70*/ 0, 22297304618SKris Buschelman MatConvert_Shell, 223273d9f13SBarry Smith 0, 224273d9f13SBarry Smith 0, 22597304618SKris Buschelman 0, 22697304618SKris Buschelman /*75*/ 0, 22797304618SKris Buschelman 0, 22897304618SKris Buschelman 0, 22997304618SKris Buschelman 0, 23097304618SKris Buschelman 0, 23197304618SKris Buschelman /*80*/ 0, 23297304618SKris Buschelman 0, 23397304618SKris Buschelman 0, 23497304618SKris Buschelman 0, 235865e5f61SKris Buschelman 0, 236865e5f61SKris Buschelman /*85*/ 0, 237865e5f61SKris Buschelman 0, 238865e5f61SKris Buschelman 0, 239865e5f61SKris Buschelman 0, 240865e5f61SKris Buschelman 0, 241865e5f61SKris Buschelman /*90*/ 0, 242865e5f61SKris Buschelman 0, 243865e5f61SKris Buschelman 0, 244865e5f61SKris Buschelman 0, 245865e5f61SKris Buschelman 0, 246865e5f61SKris Buschelman /*95*/ 0, 247865e5f61SKris Buschelman 0, 248865e5f61SKris Buschelman 0, 249865e5f61SKris Buschelman 0}; 250273d9f13SBarry Smith 2510bad9183SKris Buschelman /*MC 252fafad747SKris Buschelman MATSHELL - MATSHELL = "shell" - A matrix type to be used to define your own matrix type -- perhaps matrix free. 2530bad9183SKris Buschelman 2540bad9183SKris Buschelman Level: advanced 2550bad9183SKris Buschelman 2560bad9183SKris Buschelman .seealso: MatCreateShell 2570bad9183SKris Buschelman M*/ 2580bad9183SKris Buschelman 259273d9f13SBarry Smith EXTERN_C_BEGIN 260711e205bSSatish Balay #undef __FUNCT__ 261711e205bSSatish Balay #define __FUNCT__ "MatCreate_Shell" 262dfbe8321SBarry Smith PetscErrorCode MatCreate_Shell(Mat A) 263273d9f13SBarry Smith { 264273d9f13SBarry Smith Mat_Shell *b; 265dfbe8321SBarry Smith PetscErrorCode ierr; 266273d9f13SBarry Smith 267273d9f13SBarry Smith PetscFunctionBegin; 268273d9f13SBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 269273d9f13SBarry Smith 270b0a32e0cSBarry Smith ierr = PetscNew(Mat_Shell,&b);CHKERRQ(ierr); 271b0a32e0cSBarry Smith PetscLogObjectMemory(A,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 272273d9f13SBarry Smith ierr = PetscMemzero(b,sizeof(Mat_Shell));CHKERRQ(ierr); 273273d9f13SBarry Smith A->data = (void*)b; 274273d9f13SBarry Smith 275273d9f13SBarry Smith if (A->m == PETSC_DECIDE || A->n == PETSC_DECIDE) { 276e005ede5SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Must give local row and column count for matrix"); 277273d9f13SBarry Smith } 278273d9f13SBarry Smith 279273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->m,&A->M);CHKERRQ(ierr); 280273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->n,&A->N);CHKERRQ(ierr); 281273d9f13SBarry Smith 2828a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->m,A->M,&A->rmap);CHKERRQ(ierr); 2838a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->n,A->N,&A->cmap);CHKERRQ(ierr); 284273d9f13SBarry Smith 285273d9f13SBarry Smith b->ctx = 0; 286ef66eb69SBarry Smith b->scale = PETSC_FALSE; 287ef66eb69SBarry Smith b->shift = PETSC_FALSE; 288ef66eb69SBarry Smith b->vshift = 0.0; 289ef66eb69SBarry Smith b->vscale = 1.0; 290ef66eb69SBarry Smith b->mult = 0; 291273d9f13SBarry Smith A->assembled = PETSC_TRUE; 292273d9f13SBarry Smith A->preallocated = PETSC_TRUE; 293273d9f13SBarry Smith PetscFunctionReturn(0); 294273d9f13SBarry Smith } 295273d9f13SBarry Smith EXTERN_C_END 296e51e0e81SBarry Smith 297711e205bSSatish Balay #undef __FUNCT__ 298711e205bSSatish Balay #define __FUNCT__ "MatCreateShell" 2994b828684SBarry Smith /*@C 300052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 301ff756334SLois Curfman McInnes private data storage format. 302e51e0e81SBarry Smith 303c7fcc2eaSBarry Smith Collective on MPI_Comm 304c7fcc2eaSBarry Smith 305e51e0e81SBarry Smith Input Parameters: 306c7fcc2eaSBarry Smith + comm - MPI communicator 307c7fcc2eaSBarry Smith . m - number of local rows (must be given) 308c7fcc2eaSBarry Smith . n - number of local columns (must be given) 309c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 310c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 311c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 312e51e0e81SBarry Smith 313ff756334SLois Curfman McInnes Output Parameter: 31444cd7ae7SLois Curfman McInnes . A - the matrix 315e51e0e81SBarry Smith 316ff2fd236SBarry Smith Level: advanced 317ff2fd236SBarry Smith 318f39d1f56SLois Curfman McInnes Usage: 3197b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 320f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 321c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 322f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 323f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 324f39d1f56SLois Curfman McInnes 325ff756334SLois Curfman McInnes Notes: 326ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 327ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 328ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 329e51e0e81SBarry Smith 330f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 331f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 332645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 333645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 334645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 335645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 336645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 337645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 338645985a0SLois Curfman McInnes For example, 339f39d1f56SLois Curfman McInnes 340f39d1f56SLois Curfman McInnes $ 341f39d1f56SLois Curfman McInnes $ Vec x, y 3427b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 343645985a0SLois Curfman McInnes $ Mat A 344f39d1f56SLois Curfman McInnes $ 345c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 346c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 347f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 348c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 349c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 350c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 351645985a0SLois Curfman McInnes $ MatMult(A,x,y); 352645985a0SLois Curfman McInnes $ MatDestroy(A); 353f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 354645985a0SLois Curfman McInnes $ 355e51e0e81SBarry Smith 3560b627109SLois Curfman McInnes .keywords: matrix, shell, create 3570b627109SLois Curfman McInnes 358ab50ec6bSBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext(), MatShellSetContext() 359e51e0e81SBarry Smith @*/ 360b24ad042SBarry Smith PetscErrorCode MatCreateShell(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,void *ctx,Mat *A) 361e51e0e81SBarry Smith { 362dfbe8321SBarry Smith PetscErrorCode ierr; 363ed3cc1f0SBarry Smith 3643a40ed3dSBarry Smith PetscFunctionBegin; 365273d9f13SBarry Smith ierr = MatCreate(comm,m,n,M,N,A);CHKERRQ(ierr); 366273d9f13SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 367273d9f13SBarry Smith ierr = MatShellSetContext(*A,ctx);CHKERRQ(ierr); 368273d9f13SBarry Smith PetscFunctionReturn(0); 369c7fcc2eaSBarry Smith } 370c7fcc2eaSBarry Smith 371711e205bSSatish Balay #undef __FUNCT__ 372711e205bSSatish Balay #define __FUNCT__ "MatShellSetContext" 373273d9f13SBarry Smith /*@C 374273d9f13SBarry Smith MatShellSetContext - sets the context for a shell matrix 375c7fcc2eaSBarry Smith 376273d9f13SBarry Smith Collective on Mat 377c7fcc2eaSBarry Smith 378273d9f13SBarry Smith Input Parameters: 379273d9f13SBarry Smith + mat - the shell matrix 380273d9f13SBarry Smith - ctx - the context 381273d9f13SBarry Smith 382273d9f13SBarry Smith Level: advanced 383273d9f13SBarry Smith 384273d9f13SBarry Smith 385273d9f13SBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 386273d9f13SBarry Smith @*/ 387dfbe8321SBarry Smith PetscErrorCode MatShellSetContext(Mat mat,void *ctx) 388273d9f13SBarry Smith { 389273d9f13SBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 390dfbe8321SBarry Smith PetscErrorCode ierr; 391273d9f13SBarry Smith PetscTruth flg; 392273d9f13SBarry Smith 393273d9f13SBarry Smith PetscFunctionBegin; 3944482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 395273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 396273d9f13SBarry Smith if (flg) { 397273d9f13SBarry Smith shell->ctx = ctx; 398273d9f13SBarry Smith } 3993a40ed3dSBarry Smith PetscFunctionReturn(0); 400e51e0e81SBarry Smith } 401e51e0e81SBarry Smith 402711e205bSSatish Balay #undef __FUNCT__ 403711e205bSSatish Balay #define __FUNCT__ "MatShellSetOperation" 404c16cb8f2SBarry Smith /*@C 4053a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 4063a3eedf2SBarry Smith a shell matrix. 407e51e0e81SBarry Smith 408fee21e36SBarry Smith Collective on Mat 409fee21e36SBarry Smith 410c7fcc2eaSBarry Smith Input Parameters: 411c7fcc2eaSBarry Smith + mat - the shell matrix 412c7fcc2eaSBarry Smith . op - the name of the operation 413c7fcc2eaSBarry Smith - f - the function that provides the operation. 414c7fcc2eaSBarry Smith 41515091d37SBarry Smith Level: advanced 41615091d37SBarry Smith 417fae171e0SBarry Smith Usage: 418a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 419f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 420c134de8dSSatish Balay $ ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 4210b627109SLois Curfman McInnes 422a62d957aSLois Curfman McInnes Notes: 423e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 4241c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 425a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 4261c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 427a62d957aSLois Curfman McInnes 428a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 429deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 430deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 431deebb3c3SLois Curfman McInnes routines, e.g., 432a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 433a62d957aSLois Curfman McInnes 434a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 435a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 436a62d957aSLois Curfman McInnes set by MatCreateShell(). 437a62d957aSLois Curfman McInnes 438a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 439a62d957aSLois Curfman McInnes 440ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellSetContext() 441e51e0e81SBarry Smith @*/ 442dfbe8321SBarry Smith PetscErrorCode MatShellSetOperation(Mat mat,MatOperation op,void (*f)(void)) 443e51e0e81SBarry Smith { 444dfbe8321SBarry Smith PetscErrorCode ierr; 445273d9f13SBarry Smith PetscTruth flg; 446273d9f13SBarry Smith 4473a40ed3dSBarry Smith PetscFunctionBegin; 4484482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 4491c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 450273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 451273d9f13SBarry Smith if (flg) { 452a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 4536849ba73SBarry Smith shell->destroy = (PetscErrorCode (*)(Mat)) f; 4546849ba73SBarry Smith } else mat->ops->destroy = (PetscErrorCode (*)(Mat)) f; 455a62d957aSLois Curfman McInnes } 4566849ba73SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (PetscErrorCode (*)(Mat,PetscViewer)) f; 457c134de8dSSatish Balay else (((void(**)(void))mat->ops)[op]) = f; 458a62d957aSLois Curfman McInnes 4593a40ed3dSBarry Smith PetscFunctionReturn(0); 460e51e0e81SBarry Smith } 461f0479e8cSBarry Smith 462711e205bSSatish Balay #undef __FUNCT__ 463711e205bSSatish Balay #define __FUNCT__ "MatShellGetOperation" 464d4bb536fSBarry Smith /*@C 465d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 466d4bb536fSBarry Smith 467c7fcc2eaSBarry Smith Not Collective 468c7fcc2eaSBarry Smith 469d4bb536fSBarry Smith Input Parameters: 470c7fcc2eaSBarry Smith + mat - the shell matrix 471c7fcc2eaSBarry Smith - op - the name of the operation 472d4bb536fSBarry Smith 473d4bb536fSBarry Smith Output Parameter: 474d4bb536fSBarry Smith . f - the function that provides the operation. 475d4bb536fSBarry Smith 47615091d37SBarry Smith Level: advanced 47715091d37SBarry Smith 478d4bb536fSBarry Smith Notes: 479e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 480d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 481d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 482d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 483d4bb536fSBarry Smith 484d4bb536fSBarry Smith All user-provided functions have the same calling 485d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 486d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 487d4bb536fSBarry Smith routines, e.g., 488d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 489d4bb536fSBarry Smith 490d4bb536fSBarry Smith Within each user-defined routine, the user should call 491d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 492d4bb536fSBarry Smith set by MatCreateShell(). 493d4bb536fSBarry Smith 494d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 495d4bb536fSBarry Smith 496ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation(), MatShellSetContext() 497d4bb536fSBarry Smith @*/ 498dfbe8321SBarry Smith PetscErrorCode MatShellGetOperation(Mat mat,MatOperation op,void(**f)(void)) 499d4bb536fSBarry Smith { 500dfbe8321SBarry Smith PetscErrorCode ierr; 501273d9f13SBarry Smith PetscTruth flg; 502273d9f13SBarry Smith 5033a40ed3dSBarry Smith PetscFunctionBegin; 5044482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 505d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 506273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 507273d9f13SBarry Smith if (flg) { 508d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 509c134de8dSSatish Balay *f = (void(*)(void))shell->destroy; 510c7fcc2eaSBarry Smith } else { 511c134de8dSSatish Balay *f = (void(*)(void))mat->ops->destroy; 512d4bb536fSBarry Smith } 513c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 514c134de8dSSatish Balay *f = (void(*)(void))mat->ops->view; 515c7fcc2eaSBarry Smith } else { 516c134de8dSSatish Balay *f = (((void(**)(void))mat->ops)[op]); 517d4bb536fSBarry Smith } 518d4bb536fSBarry Smith 5193a40ed3dSBarry Smith PetscFunctionReturn(0); 520d4bb536fSBarry Smith } 521d4bb536fSBarry Smith 522