1*b2863d3aSBarry Smith /*$Id: shell.c,v 1.77 2000/02/02 20:09:02 bsmith 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 970f55243SBarry Smith #include "src/mat/matimpl.h" /*I "mat.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__ 20*b2863d3aSBarry 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__ 52*b2863d3aSBarry 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__ 64*b2863d3aSBarry 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__ 76*b2863d3aSBarry 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__ 105*b2863d3aSBarry 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, 18009dc0095SBarry Smith 0, 18109dc0095SBarry Smith 0, 18209dc0095SBarry Smith MatGetMaps_Petsc}; 183e51e0e81SBarry Smith 1845615d1e5SSatish Balay #undef __FUNC__ 185*b2863d3aSBarry 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); 259e1311b90SBarry Smith B->ops->destroy = MatDestroy_Shell; 260227d817aSBarry Smith 26144cd7ae7SLois Curfman McInnes b = PetscNew(Mat_Shell);CHKPTRQ(b); 262eed86810SBarry Smith PLogObjectMemory(B,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 263549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_Shell));CHKERRQ(ierr); 26444cd7ae7SLois Curfman McInnes B->data = (void*)b; 265c7fcc2eaSBarry Smith 266c7fcc2eaSBarry Smith if (m == PETSC_DECIDE || n == PETSC_DECIDE) { 267c7fcc2eaSBarry Smith SETERRQ(1,1,"Must give local row and column count for matrix"); 268c7fcc2eaSBarry Smith } 269c7fcc2eaSBarry Smith 2700462333dSBarry Smith ierr = PetscSplitOwnership(comm,&m,&M);CHKERRQ(ierr); 2710462333dSBarry Smith ierr = PetscSplitOwnership(comm,&n,&N);CHKERRQ(ierr); 272f39d1f56SLois Curfman McInnes b->M = M; B->M = M; 273f39d1f56SLois Curfman McInnes b->N = N; B->N = N; 274f39d1f56SLois Curfman McInnes b->m = m; B->m = m; 275f39d1f56SLois Curfman McInnes b->n = n; B->n = n; 276c7fcc2eaSBarry Smith 277488ecbafSBarry Smith ierr = MapCreateMPI(comm,m,M,&B->rmap);CHKERRQ(ierr); 278488ecbafSBarry Smith ierr = MapCreateMPI(comm,n,N,&B->cmap);CHKERRQ(ierr); 279c7fcc2eaSBarry Smith 28044cd7ae7SLois Curfman McInnes b->ctx = ctx; 28144cd7ae7SLois Curfman McInnes *A = B; 2823a40ed3dSBarry Smith PetscFunctionReturn(0); 283e51e0e81SBarry Smith } 284e51e0e81SBarry Smith 2855615d1e5SSatish Balay #undef __FUNC__ 286*b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatShellSetOperation" 287c16cb8f2SBarry Smith /*@C 2883a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 2893a3eedf2SBarry Smith a shell matrix. 290e51e0e81SBarry Smith 291fee21e36SBarry Smith Collective on Mat 292fee21e36SBarry Smith 293c7fcc2eaSBarry Smith Input Parameters: 294c7fcc2eaSBarry Smith + mat - the shell matrix 295c7fcc2eaSBarry Smith . op - the name of the operation 296c7fcc2eaSBarry Smith - f - the function that provides the operation. 297c7fcc2eaSBarry Smith 29815091d37SBarry Smith Level: advanced 29915091d37SBarry Smith 300fae171e0SBarry Smith Usage: 301a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 302f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 303c94f878dSBarry Smith $ ierr = MatShellSetOperation(A,MATOP_MULT,(void*) usermult); 3040b627109SLois Curfman McInnes 305a62d957aSLois Curfman McInnes Notes: 3067fc3c18eSBarry Smith See the file include/mat.h for a complete list of matrix 3071c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 308a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 3091c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 310a62d957aSLois Curfman McInnes 311a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 312deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 313deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 314deebb3c3SLois Curfman McInnes routines, e.g., 315a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 316a62d957aSLois Curfman McInnes 317a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 318a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 319a62d957aSLois Curfman McInnes set by MatCreateShell(). 320a62d957aSLois Curfman McInnes 321a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 322a62d957aSLois Curfman McInnes 323d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 324e51e0e81SBarry Smith @*/ 325fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op,void *f) 326e51e0e81SBarry Smith { 3273a40ed3dSBarry Smith PetscFunctionBegin; 32877c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 329fae171e0SBarry Smith 3301c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 331a62d957aSLois Curfman McInnes if (mat->type == MATSHELL) { 332a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 3333a3eedf2SBarry Smith shell->destroy = (int (*)(Mat)) f; 3340c0c84c0SBarry Smith } else mat->ops->destroy = (int (*)(Mat)) f; 335a62d957aSLois Curfman McInnes } 336e1311b90SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (int (*)(Mat,Viewer)) f; 337f830108cSBarry Smith else (((void**)mat->ops)[op]) = f; 338a62d957aSLois Curfman McInnes 3393a40ed3dSBarry Smith PetscFunctionReturn(0); 340e51e0e81SBarry Smith } 341f0479e8cSBarry Smith 342d4bb536fSBarry Smith #undef __FUNC__ 343*b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatShellGetOperation" 344d4bb536fSBarry Smith /*@C 345d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 346d4bb536fSBarry Smith 347c7fcc2eaSBarry Smith Not Collective 348c7fcc2eaSBarry Smith 349d4bb536fSBarry Smith Input Parameters: 350c7fcc2eaSBarry Smith + mat - the shell matrix 351c7fcc2eaSBarry Smith - op - the name of the operation 352d4bb536fSBarry Smith 353d4bb536fSBarry Smith Output Parameter: 354d4bb536fSBarry Smith . f - the function that provides the operation. 355d4bb536fSBarry Smith 35615091d37SBarry Smith Level: advanced 35715091d37SBarry Smith 358d4bb536fSBarry Smith Notes: 3597fc3c18eSBarry Smith See the file include/mat.h for a complete list of matrix 360d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 361d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 362d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 363d4bb536fSBarry Smith 364d4bb536fSBarry Smith All user-provided functions have the same calling 365d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 366d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 367d4bb536fSBarry Smith routines, e.g., 368d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 369d4bb536fSBarry Smith 370d4bb536fSBarry Smith Within each user-defined routine, the user should call 371d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 372d4bb536fSBarry Smith set by MatCreateShell(). 373d4bb536fSBarry Smith 374d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 375d4bb536fSBarry Smith 376d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation() 377d4bb536fSBarry Smith @*/ 378d4bb536fSBarry Smith int MatShellGetOperation(Mat mat,MatOperation op,void **f) 379d4bb536fSBarry Smith { 3803a40ed3dSBarry Smith PetscFunctionBegin; 381d4bb536fSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 382d4bb536fSBarry Smith 383d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 384d4bb536fSBarry Smith if (mat->type == MATSHELL) { 385d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 386d4bb536fSBarry Smith *f = (void*)shell->destroy; 387c7fcc2eaSBarry Smith } else { 388c7fcc2eaSBarry Smith *f = (void*)mat->ops->destroy; 389d4bb536fSBarry Smith } 390c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 391c7fcc2eaSBarry Smith *f = (void*)mat->ops->view; 392c7fcc2eaSBarry Smith } else { 39341328d39SSatish Balay *f = (((void**)mat->ops)[op]); 394d4bb536fSBarry Smith } 395d4bb536fSBarry Smith 3963a40ed3dSBarry Smith PetscFunctionReturn(0); 397d4bb536fSBarry Smith } 398d4bb536fSBarry Smith 399