1*b9b97703SBarry Smith /*$Id: shell.c,v 1.80 2000/05/05 22:15:48 balay Exp bsmith $*/ 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 { 13f39d1f56SLois Curfman McInnes int M,N; /* number of global rows, columns */ 14f39d1f56SLois Curfman McInnes int m,n; /* number of local rows, columns */ 153a3eedf2SBarry Smith int (*destroy)(Mat); 1620563c6bSBarry Smith void *ctx; 1788cf3e7dSBarry Smith } Mat_Shell; 18e51e0e81SBarry Smith 195615d1e5SSatish Balay #undef __FUNC__ 20b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatShellGetContext" 21b4fd4287SBarry Smith /*@ 22a62d957aSLois Curfman McInnes MatShellGetContext - Returns the user-provided context associated with a shell matrix. 23b4fd4287SBarry Smith 24c7fcc2eaSBarry Smith Not Collective 25c7fcc2eaSBarry Smith 26b4fd4287SBarry Smith Input Parameter: 27b4fd4287SBarry Smith . mat - the matrix, should have been created with MatCreateShell() 28b4fd4287SBarry Smith 29b4fd4287SBarry Smith Output Parameter: 30b4fd4287SBarry Smith . ctx - the user provided context 31b4fd4287SBarry Smith 3215091d37SBarry Smith Level: advanced 3315091d37SBarry Smith 34a62d957aSLois Curfman McInnes Notes: 35a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 36a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 37a62d957aSLois Curfman McInnes 38a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 39a62d957aSLois Curfman McInnes 40a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellSetOperation() 41b4fd4287SBarry Smith @*/ 42b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx) 43b4fd4287SBarry Smith { 443a40ed3dSBarry Smith PetscFunctionBegin; 4577c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 46b4fd4287SBarry Smith if (mat->type != MATSHELL) *ctx = 0; 47b4fd4287SBarry Smith else *ctx = ((Mat_Shell*)(mat->data))->ctx; 483a40ed3dSBarry Smith PetscFunctionReturn(0); 49b4fd4287SBarry Smith } 50b4fd4287SBarry Smith 515615d1e5SSatish Balay #undef __FUNC__ 52b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetSize_Shell" 538f6be9afSLois Curfman McInnes int MatGetSize_Shell(Mat mat,int *M,int *N) 5471b459e3SLois Curfman McInnes { 5571b459e3SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 563a40ed3dSBarry Smith 573a40ed3dSBarry Smith PetscFunctionBegin; 58f830108cSBarry Smith if (M) *M = shell->M; 59f830108cSBarry Smith if (N) *N = shell->N; 603a40ed3dSBarry Smith PetscFunctionReturn(0); 61f39d1f56SLois Curfman McInnes } 62f39d1f56SLois Curfman McInnes 635615d1e5SSatish Balay #undef __FUNC__ 64b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetLocalSize_Shell" 658f6be9afSLois Curfman McInnes int MatGetLocalSize_Shell(Mat mat,int *m,int *n) 66f39d1f56SLois Curfman McInnes { 67f39d1f56SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 683a40ed3dSBarry Smith 693a40ed3dSBarry Smith PetscFunctionBegin; 70f830108cSBarry Smith if (m) *m = shell->m; 71f830108cSBarry Smith if (n) *n = shell->n; 723a40ed3dSBarry Smith PetscFunctionReturn(0); 7371b459e3SLois Curfman McInnes } 7471b459e3SLois Curfman McInnes 755615d1e5SSatish Balay #undef __FUNC__ 76b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatDestroy_Shell" 77e1311b90SBarry Smith int MatDestroy_Shell(Mat mat) 78e51e0e81SBarry Smith { 79b9fa9cd0SBarry Smith int ierr; 8088cf3e7dSBarry Smith Mat_Shell *shell; 81ed3cc1f0SBarry Smith 823a40ed3dSBarry Smith PetscFunctionBegin; 8394d884c6SBarry Smith 8494d884c6SBarry Smith if (mat->mapping) { 8594d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->mapping);CHKERRQ(ierr); 8694d884c6SBarry Smith } 8794d884c6SBarry Smith if (mat->bmapping) { 8894d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->bmapping);CHKERRQ(ierr); 8994d884c6SBarry Smith } 9061b13de0SBarry Smith if (mat->rmap) { 9161b13de0SBarry Smith ierr = MapDestroy(mat->rmap);CHKERRQ(ierr); 9261b13de0SBarry Smith } 9361b13de0SBarry Smith if (mat->cmap) { 9461b13de0SBarry Smith ierr = MapDestroy(mat->cmap);CHKERRQ(ierr); 9561b13de0SBarry Smith } 9688cf3e7dSBarry Smith shell = (Mat_Shell*)mat->data; 973a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 98606d414cSSatish Balay ierr = PetscFree(shell);CHKERRQ(ierr); 993a3eedf2SBarry Smith PLogObjectDestroy(mat); 1003a3eedf2SBarry Smith PetscHeaderDestroy(mat); 1013a40ed3dSBarry Smith PetscFunctionReturn(0); 102e51e0e81SBarry Smith } 103e51e0e81SBarry Smith 104433994e6SBarry Smith #undef __FUNC__ 105b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetOwnershipRange_Shell" 1068f6be9afSLois Curfman McInnes int MatGetOwnershipRange_Shell(Mat mat,int *rstart,int *rend) 107b951964fSBarry Smith { 1084c49b128SBarry Smith int ierr,tmp; 109ca161407SBarry Smith 110ca161407SBarry Smith PetscFunctionBegin; 1114c49b128SBarry Smith ierr = MPI_Scan(&mat->m,&tmp,1,MPI_INT,MPI_SUM,mat->comm);CHKERRQ(ierr); 1124c49b128SBarry Smith if (rstart) *rstart = tmp - mat->m; 1134c49b128SBarry Smith if (rend) *rend = tmp; 1143a40ed3dSBarry Smith PetscFunctionReturn(0); 115b951964fSBarry Smith } 116b951964fSBarry Smith 11709dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 11820563c6bSBarry Smith 0, 11920563c6bSBarry Smith 0, 12020563c6bSBarry Smith 0, 12120563c6bSBarry Smith 0, 122b951964fSBarry Smith 0, 123b951964fSBarry Smith 0, 124b951964fSBarry Smith 0, 125b951964fSBarry Smith 0, 126b951964fSBarry Smith 0, 127b951964fSBarry Smith 0, 128b951964fSBarry Smith 0, 129b951964fSBarry Smith 0, 130b951964fSBarry Smith 0, 131b951964fSBarry Smith 0, 132b951964fSBarry Smith 0, 133b951964fSBarry Smith 0, 134b951964fSBarry Smith 0, 135b951964fSBarry Smith 0, 136b951964fSBarry Smith 0, 137b951964fSBarry Smith 0, 138b951964fSBarry Smith 0, 139b951964fSBarry Smith 0, 140b951964fSBarry Smith 0, 141b951964fSBarry Smith 0, 142b951964fSBarry Smith 0, 143b951964fSBarry Smith 0, 144b951964fSBarry Smith 0, 145b951964fSBarry Smith 0, 146b951964fSBarry Smith 0, 147b951964fSBarry Smith MatGetSize_Shell, 148b951964fSBarry Smith MatGetLocalSize_Shell, 149b951964fSBarry Smith MatGetOwnershipRange_Shell, 150b951964fSBarry Smith 0, 151b951964fSBarry Smith 0, 152b951964fSBarry Smith 0, 153b951964fSBarry Smith 0, 15409dc0095SBarry Smith 0, 15509dc0095SBarry Smith 0, 15609dc0095SBarry Smith 0, 15709dc0095SBarry Smith 0, 15809dc0095SBarry Smith 0, 15909dc0095SBarry Smith 0, 16009dc0095SBarry Smith 0, 16109dc0095SBarry Smith 0, 16209dc0095SBarry Smith 0, 16309dc0095SBarry Smith 0, 16409dc0095SBarry Smith 0, 16509dc0095SBarry Smith 0, 16609dc0095SBarry Smith 0, 16709dc0095SBarry Smith 0, 16809dc0095SBarry Smith 0, 16909dc0095SBarry Smith 0, 17009dc0095SBarry Smith 0, 17109dc0095SBarry Smith 0, 17209dc0095SBarry Smith 0, 17309dc0095SBarry Smith 0, 17409dc0095SBarry Smith 0, 17509dc0095SBarry Smith 0, 17609dc0095SBarry Smith 0, 17709dc0095SBarry Smith 0, 17809dc0095SBarry Smith 0, 17909dc0095SBarry Smith 0, 180*b9b97703SBarry Smith MatDestroy_Shell, 18109dc0095SBarry Smith 0, 18209dc0095SBarry Smith MatGetMaps_Petsc}; 183e51e0e81SBarry Smith 1845615d1e5SSatish Balay #undef __FUNC__ 185b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatCreateShell" 1864b828684SBarry Smith /*@C 187052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 188ff756334SLois Curfman McInnes private data storage format. 189e51e0e81SBarry Smith 190c7fcc2eaSBarry Smith Collective on MPI_Comm 191c7fcc2eaSBarry Smith 192e51e0e81SBarry Smith Input Parameters: 193c7fcc2eaSBarry Smith + comm - MPI communicator 194c7fcc2eaSBarry Smith . m - number of local rows (must be given) 195c7fcc2eaSBarry Smith . n - number of local columns (must be given) 196c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 197c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 198c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 199e51e0e81SBarry Smith 200ff756334SLois Curfman McInnes Output Parameter: 20144cd7ae7SLois Curfman McInnes . A - the matrix 202e51e0e81SBarry Smith 203ff2fd236SBarry Smith Level: advanced 204ff2fd236SBarry Smith 205f39d1f56SLois Curfman McInnes Usage: 2067b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 207f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 2087b2a1423SBarry Smith $ MatShellSetOperation(mat,MATOP_MULT,(void *)mult); 209f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 210f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 211f39d1f56SLois Curfman McInnes 212ff756334SLois Curfman McInnes Notes: 213ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 214ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 215ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 216e51e0e81SBarry Smith 217f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 218f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 219645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 220645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 221645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 222645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 223645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 224645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 225645985a0SLois Curfman McInnes For example, 226f39d1f56SLois Curfman McInnes 227f39d1f56SLois Curfman McInnes $ 228f39d1f56SLois Curfman McInnes $ Vec x, y 2297b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 230645985a0SLois Curfman McInnes $ Mat A 231f39d1f56SLois Curfman McInnes $ 232c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 233c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 234f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 235c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 236c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 2377b2a1423SBarry Smith $ MatShellSetOperation(mat,MATOP_MULT,(void *)mult); 238645985a0SLois Curfman McInnes $ MatMult(A,x,y); 239645985a0SLois Curfman McInnes $ MatDestroy(A); 240f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 241645985a0SLois Curfman McInnes $ 242e51e0e81SBarry Smith 2430b627109SLois Curfman McInnes .keywords: matrix, shell, create 2440b627109SLois Curfman McInnes 2453a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext() 246e51e0e81SBarry Smith @*/ 247f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A) 248e51e0e81SBarry Smith { 24944cd7ae7SLois Curfman McInnes Mat B; 25044cd7ae7SLois Curfman McInnes Mat_Shell *b; 251c7fcc2eaSBarry Smith int ierr; 252ed3cc1f0SBarry Smith 2533a40ed3dSBarry Smith PetscFunctionBegin; 2543f1db9ecSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSHELL,"Mat",comm,MatDestroy,MatView); 25544cd7ae7SLois Curfman McInnes PLogObjectCreate(B); 25644cd7ae7SLois Curfman McInnes B->factor = 0; 25744cd7ae7SLois Curfman McInnes B->assembled = PETSC_TRUE; 258549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 259227d817aSBarry Smith 26044cd7ae7SLois Curfman McInnes b = PetscNew(Mat_Shell);CHKPTRQ(b); 261eed86810SBarry Smith PLogObjectMemory(B,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 262549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_Shell));CHKERRQ(ierr); 26344cd7ae7SLois Curfman McInnes B->data = (void*)b; 264c7fcc2eaSBarry Smith 265c7fcc2eaSBarry Smith if (m == PETSC_DECIDE || n == PETSC_DECIDE) { 266c7fcc2eaSBarry Smith SETERRQ(1,1,"Must give local row and column count for matrix"); 267c7fcc2eaSBarry Smith } 268c7fcc2eaSBarry Smith 2690462333dSBarry Smith ierr = PetscSplitOwnership(comm,&m,&M);CHKERRQ(ierr); 2700462333dSBarry Smith ierr = PetscSplitOwnership(comm,&n,&N);CHKERRQ(ierr); 271f39d1f56SLois Curfman McInnes b->M = M; B->M = M; 272f39d1f56SLois Curfman McInnes b->N = N; B->N = N; 273f39d1f56SLois Curfman McInnes b->m = m; B->m = m; 274f39d1f56SLois Curfman McInnes b->n = n; B->n = n; 275c7fcc2eaSBarry Smith 276488ecbafSBarry Smith ierr = MapCreateMPI(comm,m,M,&B->rmap);CHKERRQ(ierr); 277488ecbafSBarry Smith ierr = MapCreateMPI(comm,n,N,&B->cmap);CHKERRQ(ierr); 278c7fcc2eaSBarry Smith 27944cd7ae7SLois Curfman McInnes b->ctx = ctx; 28044cd7ae7SLois Curfman McInnes *A = B; 2813a40ed3dSBarry Smith PetscFunctionReturn(0); 282e51e0e81SBarry Smith } 283e51e0e81SBarry Smith 2845615d1e5SSatish Balay #undef __FUNC__ 285b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatShellSetOperation" 286c16cb8f2SBarry Smith /*@C 2873a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 2883a3eedf2SBarry Smith a shell matrix. 289e51e0e81SBarry Smith 290fee21e36SBarry Smith Collective on Mat 291fee21e36SBarry Smith 292c7fcc2eaSBarry Smith Input Parameters: 293c7fcc2eaSBarry Smith + mat - the shell matrix 294c7fcc2eaSBarry Smith . op - the name of the operation 295c7fcc2eaSBarry Smith - f - the function that provides the operation. 296c7fcc2eaSBarry Smith 29715091d37SBarry Smith Level: advanced 29815091d37SBarry Smith 299fae171e0SBarry Smith Usage: 300a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 301f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 302c94f878dSBarry Smith $ ierr = MatShellSetOperation(A,MATOP_MULT,(void*) usermult); 3030b627109SLois Curfman McInnes 304a62d957aSLois Curfman McInnes Notes: 305e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 3061c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 307a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 3081c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 309a62d957aSLois Curfman McInnes 310a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 311deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 312deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 313deebb3c3SLois Curfman McInnes routines, e.g., 314a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 315a62d957aSLois Curfman McInnes 316a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 317a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 318a62d957aSLois Curfman McInnes set by MatCreateShell(). 319a62d957aSLois Curfman McInnes 320a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 321a62d957aSLois Curfman McInnes 322d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 323e51e0e81SBarry Smith @*/ 324fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op,void *f) 325e51e0e81SBarry Smith { 3263a40ed3dSBarry Smith PetscFunctionBegin; 32777c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 328fae171e0SBarry Smith 3291c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 330a62d957aSLois Curfman McInnes if (mat->type == MATSHELL) { 331a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 3323a3eedf2SBarry Smith shell->destroy = (int (*)(Mat)) f; 3330c0c84c0SBarry Smith } else mat->ops->destroy = (int (*)(Mat)) f; 334a62d957aSLois Curfman McInnes } 335e1311b90SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (int (*)(Mat,Viewer)) f; 336f830108cSBarry Smith else (((void**)mat->ops)[op]) = f; 337a62d957aSLois Curfman McInnes 3383a40ed3dSBarry Smith PetscFunctionReturn(0); 339e51e0e81SBarry Smith } 340f0479e8cSBarry Smith 341d4bb536fSBarry Smith #undef __FUNC__ 342b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatShellGetOperation" 343d4bb536fSBarry Smith /*@C 344d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 345d4bb536fSBarry Smith 346c7fcc2eaSBarry Smith Not Collective 347c7fcc2eaSBarry Smith 348d4bb536fSBarry Smith Input Parameters: 349c7fcc2eaSBarry Smith + mat - the shell matrix 350c7fcc2eaSBarry Smith - op - the name of the operation 351d4bb536fSBarry Smith 352d4bb536fSBarry Smith Output Parameter: 353d4bb536fSBarry Smith . f - the function that provides the operation. 354d4bb536fSBarry Smith 35515091d37SBarry Smith Level: advanced 35615091d37SBarry Smith 357d4bb536fSBarry Smith Notes: 358e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 359d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 360d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 361d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 362d4bb536fSBarry Smith 363d4bb536fSBarry Smith All user-provided functions have the same calling 364d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 365d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 366d4bb536fSBarry Smith routines, e.g., 367d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 368d4bb536fSBarry Smith 369d4bb536fSBarry Smith Within each user-defined routine, the user should call 370d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 371d4bb536fSBarry Smith set by MatCreateShell(). 372d4bb536fSBarry Smith 373d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 374d4bb536fSBarry Smith 375d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation() 376d4bb536fSBarry Smith @*/ 377d4bb536fSBarry Smith int MatShellGetOperation(Mat mat,MatOperation op,void **f) 378d4bb536fSBarry Smith { 3793a40ed3dSBarry Smith PetscFunctionBegin; 380d4bb536fSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 381d4bb536fSBarry Smith 382d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 383d4bb536fSBarry Smith if (mat->type == MATSHELL) { 384d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 385d4bb536fSBarry Smith *f = (void*)shell->destroy; 386c7fcc2eaSBarry Smith } else { 387c7fcc2eaSBarry Smith *f = (void*)mat->ops->destroy; 388d4bb536fSBarry Smith } 389c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 390c7fcc2eaSBarry Smith *f = (void*)mat->ops->view; 391c7fcc2eaSBarry Smith } else { 39241328d39SSatish Balay *f = (((void**)mat->ops)[op]); 393d4bb536fSBarry Smith } 394d4bb536fSBarry Smith 3953a40ed3dSBarry Smith PetscFunctionReturn(0); 396d4bb536fSBarry Smith } 397d4bb536fSBarry Smith 398