1*711e205bSSatish Balay /*$Id: shell.c,v 1.84 2001/01/15 21:45:41 bsmith Exp balay $*/ 2e51e0e81SBarry Smith 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*/ 10f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 11e51e0e81SBarry Smith 1220563c6bSBarry Smith typedef struct { 133a3eedf2SBarry Smith int (*destroy)(Mat); 1420563c6bSBarry Smith void *ctx; 1588cf3e7dSBarry Smith } Mat_Shell; 16e51e0e81SBarry Smith 17*711e205bSSatish Balay #undef __FUNCT__ 18*711e205bSSatish Balay #define __FUNCT__ "MatShellGetContext" 19b4fd4287SBarry Smith /*@ 20a62d957aSLois Curfman McInnes MatShellGetContext - Returns the user-provided context associated with a shell matrix. 21b4fd4287SBarry Smith 22c7fcc2eaSBarry Smith Not Collective 23c7fcc2eaSBarry Smith 24b4fd4287SBarry Smith Input Parameter: 25b4fd4287SBarry Smith . mat - the matrix, should have been created with MatCreateShell() 26b4fd4287SBarry Smith 27b4fd4287SBarry Smith Output Parameter: 28b4fd4287SBarry Smith . ctx - the user provided context 29b4fd4287SBarry Smith 3015091d37SBarry Smith Level: advanced 3115091d37SBarry Smith 32a62d957aSLois Curfman McInnes Notes: 33a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 34a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 35a62d957aSLois Curfman McInnes 36a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 37a62d957aSLois Curfman McInnes 38a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellSetOperation() 39b4fd4287SBarry Smith @*/ 40b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx) 41b4fd4287SBarry Smith { 42273d9f13SBarry Smith int ierr; 43273d9f13SBarry Smith PetscTruth flg; 44273d9f13SBarry Smith 453a40ed3dSBarry Smith PetscFunctionBegin; 4677c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 47273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 48273d9f13SBarry Smith if (!flg) *ctx = 0; 49b4fd4287SBarry Smith else *ctx = ((Mat_Shell*)(mat->data))->ctx; 503a40ed3dSBarry Smith PetscFunctionReturn(0); 51b4fd4287SBarry Smith } 52b4fd4287SBarry Smith 53*711e205bSSatish Balay #undef __FUNCT__ 54*711e205bSSatish Balay #define __FUNCT__ "MatDestroy_Shell" 55e1311b90SBarry Smith int MatDestroy_Shell(Mat mat) 56e51e0e81SBarry Smith { 57b9fa9cd0SBarry Smith int ierr; 5888cf3e7dSBarry Smith Mat_Shell *shell; 59ed3cc1f0SBarry Smith 603a40ed3dSBarry Smith PetscFunctionBegin; 6188cf3e7dSBarry Smith shell = (Mat_Shell*)mat->data; 623a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 63606d414cSSatish Balay ierr = PetscFree(shell);CHKERRQ(ierr); 643a40ed3dSBarry Smith PetscFunctionReturn(0); 65e51e0e81SBarry Smith } 66e51e0e81SBarry Smith 67*711e205bSSatish Balay #undef __FUNCT__ 68*711e205bSSatish Balay #define __FUNCT__ "MatGetOwnershipRange_Shell" 698f6be9afSLois Curfman McInnes int MatGetOwnershipRange_Shell(Mat mat,int *rstart,int *rend) 70b951964fSBarry Smith { 714c49b128SBarry Smith int ierr,tmp; 72ca161407SBarry Smith 73ca161407SBarry Smith PetscFunctionBegin; 744c49b128SBarry Smith ierr = MPI_Scan(&mat->m,&tmp,1,MPI_INT,MPI_SUM,mat->comm);CHKERRQ(ierr); 754c49b128SBarry Smith if (rstart) *rstart = tmp - mat->m; 764c49b128SBarry Smith if (rend) *rend = tmp; 773a40ed3dSBarry Smith PetscFunctionReturn(0); 78b951964fSBarry Smith } 79273d9f13SBarry Smith extern int MatConvert_Shell(Mat,MatType,Mat*); 80b951964fSBarry Smith 8109dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 8220563c6bSBarry Smith 0, 8320563c6bSBarry Smith 0, 8420563c6bSBarry Smith 0, 8520563c6bSBarry Smith 0, 86b951964fSBarry Smith 0, 87b951964fSBarry Smith 0, 88b951964fSBarry Smith 0, 89b951964fSBarry Smith 0, 90b951964fSBarry Smith 0, 91b951964fSBarry Smith 0, 92b951964fSBarry Smith 0, 93b951964fSBarry Smith 0, 94b951964fSBarry Smith 0, 95b951964fSBarry Smith 0, 96b951964fSBarry Smith 0, 97b951964fSBarry Smith 0, 98b951964fSBarry Smith 0, 99b951964fSBarry Smith 0, 100b951964fSBarry Smith 0, 101b951964fSBarry Smith 0, 102b951964fSBarry Smith 0, 103b951964fSBarry Smith 0, 104b951964fSBarry Smith 0, 105b951964fSBarry Smith 0, 106b951964fSBarry Smith 0, 107b951964fSBarry Smith 0, 108b951964fSBarry Smith 0, 109b951964fSBarry Smith 0, 110b951964fSBarry Smith 0, 111273d9f13SBarry Smith 0, 112b951964fSBarry Smith MatGetOwnershipRange_Shell, 113b951964fSBarry Smith 0, 114b951964fSBarry Smith 0, 115b951964fSBarry Smith 0, 116b951964fSBarry Smith 0, 11709dc0095SBarry Smith 0, 11809dc0095SBarry Smith 0, 11909dc0095SBarry Smith 0, 12009dc0095SBarry Smith 0, 12109dc0095SBarry Smith 0, 12209dc0095SBarry Smith 0, 12309dc0095SBarry Smith 0, 12409dc0095SBarry Smith 0, 12509dc0095SBarry Smith 0, 12609dc0095SBarry Smith 0, 12709dc0095SBarry Smith 0, 12809dc0095SBarry Smith 0, 12909dc0095SBarry Smith 0, 13009dc0095SBarry Smith 0, 13109dc0095SBarry Smith 0, 13209dc0095SBarry Smith 0, 13309dc0095SBarry Smith 0, 13409dc0095SBarry Smith 0, 13509dc0095SBarry Smith 0, 13609dc0095SBarry Smith 0, 13709dc0095SBarry Smith 0, 13809dc0095SBarry Smith 0, 13909dc0095SBarry Smith 0, 14009dc0095SBarry Smith 0, 14109dc0095SBarry Smith 0, 14209dc0095SBarry Smith 0, 143273d9f13SBarry Smith 0, 144b9b97703SBarry Smith MatDestroy_Shell, 14509dc0095SBarry Smith 0, 146273d9f13SBarry Smith MatGetMaps_Petsc, 147273d9f13SBarry Smith 0, 148273d9f13SBarry Smith 0, 149273d9f13SBarry Smith 0, 150273d9f13SBarry Smith 0, 151273d9f13SBarry Smith 0, 152273d9f13SBarry Smith 0, 153273d9f13SBarry Smith 0, 154273d9f13SBarry Smith MatConvert_Shell}; 155273d9f13SBarry Smith 156273d9f13SBarry Smith EXTERN_C_BEGIN 157*711e205bSSatish Balay #undef __FUNCT__ 158*711e205bSSatish Balay #define __FUNCT__ "MatCreate_Shell" 159273d9f13SBarry Smith int MatCreate_Shell(Mat A) 160273d9f13SBarry Smith { 161273d9f13SBarry Smith Mat_Shell *b; 162273d9f13SBarry Smith int ierr; 163273d9f13SBarry Smith 164273d9f13SBarry Smith PetscFunctionBegin; 165273d9f13SBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 166273d9f13SBarry Smith 167b0a32e0cSBarry Smith ierr = PetscNew(Mat_Shell,&b);CHKERRQ(ierr); 168b0a32e0cSBarry Smith PetscLogObjectMemory(A,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 169273d9f13SBarry Smith ierr = PetscMemzero(b,sizeof(Mat_Shell));CHKERRQ(ierr); 170273d9f13SBarry Smith A->data = (void*)b; 171273d9f13SBarry Smith 172273d9f13SBarry Smith if (A->m == PETSC_DECIDE || A->n == PETSC_DECIDE) { 173273d9f13SBarry Smith SETERRQ(1,"Must give local row and column count for matrix"); 174273d9f13SBarry Smith } 175273d9f13SBarry Smith 176273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->m,&A->M);CHKERRQ(ierr); 177273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->n,&A->N);CHKERRQ(ierr); 178273d9f13SBarry Smith 179273d9f13SBarry Smith ierr = MapCreateMPI(A->comm,A->m,A->M,&A->rmap);CHKERRQ(ierr); 180273d9f13SBarry Smith ierr = MapCreateMPI(A->comm,A->n,A->N,&A->cmap);CHKERRQ(ierr); 181273d9f13SBarry Smith 182273d9f13SBarry Smith b->ctx = 0; 183273d9f13SBarry Smith A->assembled = PETSC_TRUE; 184273d9f13SBarry Smith A->preallocated = PETSC_TRUE; 185273d9f13SBarry Smith PetscFunctionReturn(0); 186273d9f13SBarry Smith } 187273d9f13SBarry Smith EXTERN_C_END 188e51e0e81SBarry Smith 189*711e205bSSatish Balay #undef __FUNCT__ 190*711e205bSSatish Balay #define __FUNCT__ "MatCreateShell" 1914b828684SBarry Smith /*@C 192052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 193ff756334SLois Curfman McInnes private data storage format. 194e51e0e81SBarry Smith 195c7fcc2eaSBarry Smith Collective on MPI_Comm 196c7fcc2eaSBarry Smith 197e51e0e81SBarry Smith Input Parameters: 198c7fcc2eaSBarry Smith + comm - MPI communicator 199c7fcc2eaSBarry Smith . m - number of local rows (must be given) 200c7fcc2eaSBarry Smith . n - number of local columns (must be given) 201c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 202c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 203c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 204e51e0e81SBarry Smith 205ff756334SLois Curfman McInnes Output Parameter: 20644cd7ae7SLois Curfman McInnes . A - the matrix 207e51e0e81SBarry Smith 208ff2fd236SBarry Smith Level: advanced 209ff2fd236SBarry Smith 210f39d1f56SLois Curfman McInnes Usage: 2117b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 212f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 2137b2a1423SBarry Smith $ MatShellSetOperation(mat,MATOP_MULT,(void *)mult); 214f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 215f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 216f39d1f56SLois Curfman McInnes 217ff756334SLois Curfman McInnes Notes: 218ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 219ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 220ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 221e51e0e81SBarry Smith 222f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 223f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 224645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 225645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 226645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 227645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 228645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 229645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 230645985a0SLois Curfman McInnes For example, 231f39d1f56SLois Curfman McInnes 232f39d1f56SLois Curfman McInnes $ 233f39d1f56SLois Curfman McInnes $ Vec x, y 2347b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 235645985a0SLois Curfman McInnes $ Mat A 236f39d1f56SLois Curfman McInnes $ 237c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 238c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 239f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 240c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 241c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 2427b2a1423SBarry Smith $ MatShellSetOperation(mat,MATOP_MULT,(void *)mult); 243645985a0SLois Curfman McInnes $ MatMult(A,x,y); 244645985a0SLois Curfman McInnes $ MatDestroy(A); 245f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 246645985a0SLois Curfman McInnes $ 247e51e0e81SBarry Smith 2480b627109SLois Curfman McInnes .keywords: matrix, shell, create 2490b627109SLois Curfman McInnes 2503a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext() 251e51e0e81SBarry Smith @*/ 252f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A) 253e51e0e81SBarry Smith { 254c7fcc2eaSBarry Smith int ierr; 255ed3cc1f0SBarry Smith 2563a40ed3dSBarry Smith PetscFunctionBegin; 257273d9f13SBarry Smith ierr = MatCreate(comm,m,n,M,N,A);CHKERRQ(ierr); 258273d9f13SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 259273d9f13SBarry Smith ierr = MatShellSetContext(*A,ctx);CHKERRQ(ierr); 260273d9f13SBarry Smith PetscFunctionReturn(0); 261c7fcc2eaSBarry Smith } 262c7fcc2eaSBarry Smith 263*711e205bSSatish Balay #undef __FUNCT__ 264*711e205bSSatish Balay #define __FUNCT__ "MatShellSetContext" 265273d9f13SBarry Smith /*@C 266273d9f13SBarry Smith MatShellSetContext - sets the context for a shell matrix 267c7fcc2eaSBarry Smith 268273d9f13SBarry Smith Collective on Mat 269c7fcc2eaSBarry Smith 270273d9f13SBarry Smith Input Parameters: 271273d9f13SBarry Smith + mat - the shell matrix 272273d9f13SBarry Smith - ctx - the context 273273d9f13SBarry Smith 274273d9f13SBarry Smith Level: advanced 275273d9f13SBarry Smith 276273d9f13SBarry Smith 277273d9f13SBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 278273d9f13SBarry Smith @*/ 279273d9f13SBarry Smith int MatShellSetContext(Mat mat,void *ctx) 280273d9f13SBarry Smith { 281273d9f13SBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 282273d9f13SBarry Smith int ierr; 283273d9f13SBarry Smith PetscTruth flg; 284273d9f13SBarry Smith 285273d9f13SBarry Smith PetscFunctionBegin; 286273d9f13SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 287273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 288273d9f13SBarry Smith if (flg) { 289273d9f13SBarry Smith shell->ctx = ctx; 290273d9f13SBarry Smith } 2913a40ed3dSBarry Smith PetscFunctionReturn(0); 292e51e0e81SBarry Smith } 293e51e0e81SBarry Smith 294*711e205bSSatish Balay #undef __FUNCT__ 295*711e205bSSatish Balay #define __FUNCT__ "MatShellSetOperation" 296c16cb8f2SBarry Smith /*@C 2973a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 2983a3eedf2SBarry Smith a shell matrix. 299e51e0e81SBarry Smith 300fee21e36SBarry Smith Collective on Mat 301fee21e36SBarry Smith 302c7fcc2eaSBarry Smith Input Parameters: 303c7fcc2eaSBarry Smith + mat - the shell matrix 304c7fcc2eaSBarry Smith . op - the name of the operation 305c7fcc2eaSBarry Smith - f - the function that provides the operation. 306c7fcc2eaSBarry Smith 30715091d37SBarry Smith Level: advanced 30815091d37SBarry Smith 309fae171e0SBarry Smith Usage: 310a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 311f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 312c94f878dSBarry Smith $ ierr = MatShellSetOperation(A,MATOP_MULT,(void*) usermult); 3130b627109SLois Curfman McInnes 314a62d957aSLois Curfman McInnes Notes: 315e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 3161c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 317a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 3181c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 319a62d957aSLois Curfman McInnes 320a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 321deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 322deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 323deebb3c3SLois Curfman McInnes routines, e.g., 324a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 325a62d957aSLois Curfman McInnes 326a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 327a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 328a62d957aSLois Curfman McInnes set by MatCreateShell(). 329a62d957aSLois Curfman McInnes 330a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 331a62d957aSLois Curfman McInnes 332d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 333e51e0e81SBarry Smith @*/ 334fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op,void *f) 335e51e0e81SBarry Smith { 336273d9f13SBarry Smith int ierr; 337273d9f13SBarry Smith PetscTruth flg; 338273d9f13SBarry Smith 3393a40ed3dSBarry Smith PetscFunctionBegin; 34077c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 3411c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 342273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 343273d9f13SBarry Smith if (flg) { 344a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 3453a3eedf2SBarry Smith shell->destroy = (int (*)(Mat)) f; 3460c0c84c0SBarry Smith } else mat->ops->destroy = (int (*)(Mat)) f; 347a62d957aSLois Curfman McInnes } 348b0a32e0cSBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (int (*)(Mat,PetscViewer)) f; 349f830108cSBarry Smith else (((void**)mat->ops)[op]) = f; 350a62d957aSLois Curfman McInnes 3513a40ed3dSBarry Smith PetscFunctionReturn(0); 352e51e0e81SBarry Smith } 353f0479e8cSBarry Smith 354*711e205bSSatish Balay #undef __FUNCT__ 355*711e205bSSatish Balay #define __FUNCT__ "MatShellGetOperation" 356d4bb536fSBarry Smith /*@C 357d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 358d4bb536fSBarry Smith 359c7fcc2eaSBarry Smith Not Collective 360c7fcc2eaSBarry Smith 361d4bb536fSBarry Smith Input Parameters: 362c7fcc2eaSBarry Smith + mat - the shell matrix 363c7fcc2eaSBarry Smith - op - the name of the operation 364d4bb536fSBarry Smith 365d4bb536fSBarry Smith Output Parameter: 366d4bb536fSBarry Smith . f - the function that provides the operation. 367d4bb536fSBarry Smith 36815091d37SBarry Smith Level: advanced 36915091d37SBarry Smith 370d4bb536fSBarry Smith Notes: 371e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 372d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 373d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 374d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 375d4bb536fSBarry Smith 376d4bb536fSBarry Smith All user-provided functions have the same calling 377d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 378d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 379d4bb536fSBarry Smith routines, e.g., 380d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 381d4bb536fSBarry Smith 382d4bb536fSBarry Smith Within each user-defined routine, the user should call 383d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 384d4bb536fSBarry Smith set by MatCreateShell(). 385d4bb536fSBarry Smith 386d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 387d4bb536fSBarry Smith 388d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation() 389d4bb536fSBarry Smith @*/ 390d4bb536fSBarry Smith int MatShellGetOperation(Mat mat,MatOperation op,void **f) 391d4bb536fSBarry Smith { 392273d9f13SBarry Smith int ierr; 393273d9f13SBarry Smith PetscTruth flg; 394273d9f13SBarry Smith 3953a40ed3dSBarry Smith PetscFunctionBegin; 396d4bb536fSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 397d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 398273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 399273d9f13SBarry Smith if (flg) { 400d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 401d4bb536fSBarry Smith *f = (void*)shell->destroy; 402c7fcc2eaSBarry Smith } else { 403c7fcc2eaSBarry Smith *f = (void*)mat->ops->destroy; 404d4bb536fSBarry Smith } 405c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 406c7fcc2eaSBarry Smith *f = (void*)mat->ops->view; 407c7fcc2eaSBarry Smith } else { 40841328d39SSatish Balay *f = (((void**)mat->ops)[op]); 409d4bb536fSBarry Smith } 410d4bb536fSBarry Smith 4113a40ed3dSBarry Smith PetscFunctionReturn(0); 412d4bb536fSBarry Smith } 413d4bb536fSBarry Smith 414