1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*7fc3c18eSBarry Smith static char vcid[] = "$Id: shell.c,v 1.67 1999/03/17 23:22:56 bsmith Exp bsmith $"; 3357feee3SLois Curfman McInnes #endif 4e51e0e81SBarry Smith 5e51e0e81SBarry Smith /* 620563c6bSBarry Smith This provides a simple shell for Fortran (and C programmers) to 720563c6bSBarry Smith create a very simple matrix class for use with KSP without coding 8ed3cc1f0SBarry Smith much of anything. 9e51e0e81SBarry Smith */ 10e51e0e81SBarry Smith 11e51e0e81SBarry Smith #include "petsc.h" 1270f55243SBarry Smith #include "src/mat/matimpl.h" /*I "mat.h" I*/ 13f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 14e51e0e81SBarry Smith 1520563c6bSBarry Smith typedef struct { 16f39d1f56SLois Curfman McInnes int M, N; /* number of global rows, columns */ 17f39d1f56SLois Curfman McInnes int m, n; /* number of local rows, columns */ 183a3eedf2SBarry Smith int (*destroy)(Mat); 1920563c6bSBarry Smith void *ctx; 2088cf3e7dSBarry Smith } Mat_Shell; 21e51e0e81SBarry Smith 225615d1e5SSatish Balay #undef __FUNC__ 23d4bb536fSBarry Smith #define __FUNC__ "MatShellGetContext" 24b4fd4287SBarry Smith /*@ 25a62d957aSLois Curfman McInnes MatShellGetContext - Returns the user-provided context associated with a shell matrix. 26b4fd4287SBarry Smith 27c7fcc2eaSBarry Smith Not Collective 28c7fcc2eaSBarry Smith 29b4fd4287SBarry Smith Input Parameter: 30b4fd4287SBarry Smith . mat - the matrix, should have been created with MatCreateShell() 31b4fd4287SBarry Smith 32b4fd4287SBarry Smith Output Parameter: 33b4fd4287SBarry Smith . ctx - the user provided context 34b4fd4287SBarry Smith 3515091d37SBarry Smith Level: advanced 3615091d37SBarry Smith 37a62d957aSLois Curfman McInnes Notes: 38a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 39a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 40a62d957aSLois Curfman McInnes 41a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 42a62d957aSLois Curfman McInnes 43a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellSetOperation() 44b4fd4287SBarry Smith @*/ 45b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx) 46b4fd4287SBarry Smith { 473a40ed3dSBarry Smith PetscFunctionBegin; 4877c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 49b4fd4287SBarry Smith if (mat->type != MATSHELL) *ctx = 0; 50b4fd4287SBarry Smith else *ctx = ((Mat_Shell *) (mat->data))->ctx; 513a40ed3dSBarry Smith PetscFunctionReturn(0); 52b4fd4287SBarry Smith } 53b4fd4287SBarry Smith 545615d1e5SSatish Balay #undef __FUNC__ 55d4bb536fSBarry Smith #define __FUNC__ "MatGetSize_Shell" 568f6be9afSLois Curfman McInnes int MatGetSize_Shell(Mat mat,int *M,int *N) 5771b459e3SLois Curfman McInnes { 5871b459e3SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 593a40ed3dSBarry Smith 603a40ed3dSBarry Smith PetscFunctionBegin; 61f830108cSBarry Smith if (M) *M = shell->M; 62f830108cSBarry Smith if (N) *N = shell->N; 633a40ed3dSBarry Smith PetscFunctionReturn(0); 64f39d1f56SLois Curfman McInnes } 65f39d1f56SLois Curfman McInnes 665615d1e5SSatish Balay #undef __FUNC__ 67d4bb536fSBarry Smith #define __FUNC__ "MatGetLocalSize_Shell" 688f6be9afSLois Curfman McInnes int MatGetLocalSize_Shell(Mat mat,int *m,int *n) 69f39d1f56SLois Curfman McInnes { 70f39d1f56SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 713a40ed3dSBarry Smith 723a40ed3dSBarry Smith PetscFunctionBegin; 73f830108cSBarry Smith if (m) *m = shell->m; 74f830108cSBarry Smith if (n) *n = shell->n; 753a40ed3dSBarry Smith PetscFunctionReturn(0); 7671b459e3SLois Curfman McInnes } 7771b459e3SLois Curfman McInnes 785615d1e5SSatish Balay #undef __FUNC__ 79d4bb536fSBarry Smith #define __FUNC__ "MatDestroy_Shell" 80e1311b90SBarry Smith int MatDestroy_Shell(Mat mat) 81e51e0e81SBarry Smith { 82b9fa9cd0SBarry Smith int ierr; 8388cf3e7dSBarry Smith Mat_Shell *shell; 84ed3cc1f0SBarry Smith 853a40ed3dSBarry Smith PetscFunctionBegin; 8694d884c6SBarry Smith if (--mat->refct > 0) PetscFunctionReturn(0); 8794d884c6SBarry Smith 8894d884c6SBarry Smith if (mat->mapping) { 8994d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->mapping); CHKERRQ(ierr); 9094d884c6SBarry Smith } 9194d884c6SBarry Smith if (mat->bmapping) { 9294d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->bmapping); CHKERRQ(ierr); 9394d884c6SBarry Smith } 9461b13de0SBarry Smith if (mat->rmap) { 9561b13de0SBarry Smith ierr = MapDestroy(mat->rmap);CHKERRQ(ierr); 9661b13de0SBarry Smith } 9761b13de0SBarry Smith if (mat->cmap) { 9861b13de0SBarry Smith ierr = MapDestroy(mat->cmap);CHKERRQ(ierr); 9961b13de0SBarry Smith } 10088cf3e7dSBarry Smith shell = (Mat_Shell *) mat->data; 1013a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 1020452661fSBarry Smith PetscFree(shell); 1033a3eedf2SBarry Smith PLogObjectDestroy(mat); 1043a3eedf2SBarry Smith PetscHeaderDestroy(mat); 1053a40ed3dSBarry Smith PetscFunctionReturn(0); 106e51e0e81SBarry Smith } 107e51e0e81SBarry Smith 1088f6be9afSLois Curfman McInnes int MatGetOwnershipRange_Shell(Mat mat, int *rstart,int *rend) 109b951964fSBarry Smith { 110ca161407SBarry Smith int ierr; 111ca161407SBarry Smith 112ca161407SBarry Smith PetscFunctionBegin; 113ca161407SBarry Smith ierr = MPI_Scan(&mat->m,rend,1,MPI_INT,MPI_SUM,mat->comm);CHKERRQ(ierr); 114b951964fSBarry Smith *rstart = *rend - mat->m; 1153a40ed3dSBarry Smith PetscFunctionReturn(0); 116b951964fSBarry Smith } 117b951964fSBarry Smith 11809dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 11920563c6bSBarry Smith 0, 12020563c6bSBarry Smith 0, 12120563c6bSBarry Smith 0, 12220563c6bSBarry 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 0, 148b951964fSBarry Smith MatGetSize_Shell, 149b951964fSBarry Smith MatGetLocalSize_Shell, 150b951964fSBarry Smith MatGetOwnershipRange_Shell, 151b951964fSBarry Smith 0, 152b951964fSBarry Smith 0, 153b951964fSBarry Smith 0, 154b951964fSBarry 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 0, 18309dc0095SBarry Smith MatGetMaps_Petsc}; 184e51e0e81SBarry Smith 1855615d1e5SSatish Balay #undef __FUNC__ 186d4bb536fSBarry Smith #define __FUNC__ "MatCreateShell" 1874b828684SBarry Smith /*@C 188052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 189ff756334SLois Curfman McInnes private data storage format. 190e51e0e81SBarry Smith 191c7fcc2eaSBarry Smith Collective on MPI_Comm 192c7fcc2eaSBarry Smith 193e51e0e81SBarry Smith Input Parameters: 194c7fcc2eaSBarry Smith + comm - MPI communicator 195c7fcc2eaSBarry Smith . m - number of local rows (must be given) 196c7fcc2eaSBarry Smith . n - number of local columns (must be given) 197c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 198c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 199c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 200e51e0e81SBarry Smith 201ff756334SLois Curfman McInnes Output Parameter: 20244cd7ae7SLois Curfman McInnes . A - the matrix 203e51e0e81SBarry Smith 204ff2fd236SBarry Smith Level: advanced 205ff2fd236SBarry Smith 206f39d1f56SLois Curfman McInnes Usage: 2077b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 208f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 2097b2a1423SBarry Smith $ MatShellSetOperation(mat,MATOP_MULT,(void *)mult); 210f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 211f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 212f39d1f56SLois Curfman McInnes 213ff756334SLois Curfman McInnes Notes: 214ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 215ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 216ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 217e51e0e81SBarry Smith 218f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 219f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 220645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 221645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 222645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 223645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 224645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 225645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 226645985a0SLois Curfman McInnes For example, 227f39d1f56SLois Curfman McInnes 228f39d1f56SLois Curfman McInnes $ 229f39d1f56SLois Curfman McInnes $ Vec x, y 2307b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 231645985a0SLois Curfman McInnes $ Mat A 232f39d1f56SLois Curfman McInnes $ 233c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 234c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 235f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 236c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 237c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 2387b2a1423SBarry Smith $ MatShellSetOperation(mat,MATOP_MULT,(void *)mult); 239645985a0SLois Curfman McInnes $ MatMult(A,x,y); 240645985a0SLois Curfman McInnes $ MatDestroy(A); 241f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 242645985a0SLois Curfman McInnes $ 243e51e0e81SBarry Smith 2440b627109SLois Curfman McInnes .keywords: matrix, shell, create 2450b627109SLois Curfman McInnes 2463a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext() 247e51e0e81SBarry Smith @*/ 248f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A) 249e51e0e81SBarry Smith { 25044cd7ae7SLois Curfman McInnes Mat B; 25144cd7ae7SLois Curfman McInnes Mat_Shell *b; 252c7fcc2eaSBarry Smith int ierr; 253ed3cc1f0SBarry Smith 2543a40ed3dSBarry Smith PetscFunctionBegin; 2553f1db9ecSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSHELL,"Mat",comm,MatDestroy,MatView); 25644cd7ae7SLois Curfman McInnes PLogObjectCreate(B); 25744cd7ae7SLois Curfman McInnes B->factor = 0; 25844cd7ae7SLois Curfman McInnes B->assembled = PETSC_TRUE; 25909dc0095SBarry Smith PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); 260e1311b90SBarry Smith B->ops->destroy = MatDestroy_Shell; 261227d817aSBarry Smith 26244cd7ae7SLois Curfman McInnes b = PetscNew(Mat_Shell); CHKPTRQ(b); 263eed86810SBarry Smith PLogObjectMemory(B,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 26444cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_Shell)); 26544cd7ae7SLois Curfman McInnes B->data = (void *) b; 266c7fcc2eaSBarry Smith 267c7fcc2eaSBarry Smith if (m == PETSC_DECIDE || n == PETSC_DECIDE) { 268c7fcc2eaSBarry Smith SETERRQ(1,1,"Must give local row and column count for matrix"); 269c7fcc2eaSBarry Smith } 270c7fcc2eaSBarry Smith 2710462333dSBarry Smith ierr = PetscSplitOwnership(comm,&m,&M);CHKERRQ(ierr); 2720462333dSBarry Smith ierr = PetscSplitOwnership(comm,&n,&N);CHKERRQ(ierr); 273f39d1f56SLois Curfman McInnes b->M = M; B->M = M; 274f39d1f56SLois Curfman McInnes b->N = N; B->N = N; 275f39d1f56SLois Curfman McInnes b->m = m; B->m = m; 276f39d1f56SLois Curfman McInnes b->n = n; B->n = n; 277c7fcc2eaSBarry Smith 278488ecbafSBarry Smith ierr = MapCreateMPI(comm,m,M,&B->rmap);CHKERRQ(ierr); 279488ecbafSBarry Smith ierr = MapCreateMPI(comm,n,N,&B->cmap);CHKERRQ(ierr); 280c7fcc2eaSBarry Smith 28144cd7ae7SLois Curfman McInnes b->ctx = ctx; 28244cd7ae7SLois Curfman McInnes *A = B; 2833a40ed3dSBarry Smith PetscFunctionReturn(0); 284e51e0e81SBarry Smith } 285e51e0e81SBarry Smith 2865615d1e5SSatish Balay #undef __FUNC__ 287d4bb536fSBarry Smith #define __FUNC__ "MatShellSetOperation" 288c16cb8f2SBarry Smith /*@C 2893a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 2903a3eedf2SBarry Smith a shell matrix. 291e51e0e81SBarry Smith 292fee21e36SBarry Smith Collective on Mat 293fee21e36SBarry Smith 294c7fcc2eaSBarry Smith Input Parameters: 295c7fcc2eaSBarry Smith + mat - the shell matrix 296c7fcc2eaSBarry Smith . op - the name of the operation 297c7fcc2eaSBarry Smith - f - the function that provides the operation. 298c7fcc2eaSBarry Smith 29915091d37SBarry Smith Level: advanced 30015091d37SBarry Smith 301fae171e0SBarry Smith Usage: 302a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 303f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 304c94f878dSBarry Smith $ ierr = MatShellSetOperation(A,MATOP_MULT,(void*) usermult); 3050b627109SLois Curfman McInnes 306a62d957aSLois Curfman McInnes Notes: 307*7fc3c18eSBarry Smith See the file include/mat.h for a complete list of matrix 3081c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 309a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 3101c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 311a62d957aSLois Curfman McInnes 312a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 313deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 314deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 315deebb3c3SLois Curfman McInnes routines, e.g., 316a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 317a62d957aSLois Curfman McInnes 318a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 319a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 320a62d957aSLois Curfman McInnes set by MatCreateShell(). 321a62d957aSLois Curfman McInnes 322a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 323a62d957aSLois Curfman McInnes 324d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 325e51e0e81SBarry Smith @*/ 326fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op, void *f) 327e51e0e81SBarry Smith { 3283a40ed3dSBarry Smith PetscFunctionBegin; 32977c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 330fae171e0SBarry Smith 3311c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 332a62d957aSLois Curfman McInnes if (mat->type == MATSHELL) { 333a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 3343a3eedf2SBarry Smith shell->destroy = (int (*)(Mat)) f; 335a62d957aSLois Curfman McInnes } 336e1311b90SBarry Smith else mat->ops->destroy = (int (*)(Mat)) f; 337a62d957aSLois Curfman McInnes } 338e1311b90SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (int (*)(Mat,Viewer)) f; 339f830108cSBarry Smith else (((void**)mat->ops)[op]) = f; 340a62d957aSLois Curfman McInnes 3413a40ed3dSBarry Smith PetscFunctionReturn(0); 342e51e0e81SBarry Smith } 343f0479e8cSBarry Smith 344d4bb536fSBarry Smith #undef __FUNC__ 345d4bb536fSBarry Smith #define __FUNC__ "MatShellGetOperation" 346d4bb536fSBarry Smith /*@C 347d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 348d4bb536fSBarry Smith 349c7fcc2eaSBarry Smith Not Collective 350c7fcc2eaSBarry Smith 351d4bb536fSBarry Smith Input Parameters: 352c7fcc2eaSBarry Smith + mat - the shell matrix 353c7fcc2eaSBarry Smith - op - the name of the operation 354d4bb536fSBarry Smith 355d4bb536fSBarry Smith Output Parameter: 356d4bb536fSBarry Smith . f - the function that provides the operation. 357d4bb536fSBarry Smith 35815091d37SBarry Smith Level: advanced 35915091d37SBarry Smith 360d4bb536fSBarry Smith Notes: 361*7fc3c18eSBarry Smith See the file include/mat.h for a complete list of matrix 362d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 363d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 364d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 365d4bb536fSBarry Smith 366d4bb536fSBarry Smith All user-provided functions have the same calling 367d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 368d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 369d4bb536fSBarry Smith routines, e.g., 370d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 371d4bb536fSBarry Smith 372d4bb536fSBarry Smith Within each user-defined routine, the user should call 373d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 374d4bb536fSBarry Smith set by MatCreateShell(). 375d4bb536fSBarry Smith 376d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 377d4bb536fSBarry Smith 378d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation() 379d4bb536fSBarry Smith @*/ 380d4bb536fSBarry Smith int MatShellGetOperation(Mat mat,MatOperation op, void **f) 381d4bb536fSBarry Smith { 3823a40ed3dSBarry Smith PetscFunctionBegin; 383d4bb536fSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 384d4bb536fSBarry Smith 385d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 386d4bb536fSBarry Smith if (mat->type == MATSHELL) { 387d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell *) mat->data; 388d4bb536fSBarry Smith *f = (void *) shell->destroy; 389c7fcc2eaSBarry Smith } else { 390c7fcc2eaSBarry Smith *f = (void *) mat->ops->destroy; 391d4bb536fSBarry Smith } 392c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 393c7fcc2eaSBarry Smith *f = (void *) mat->ops->view; 394c7fcc2eaSBarry Smith } else { 395c7fcc2eaSBarry Smith *f = (((void**)&mat->ops)[op]); 396d4bb536fSBarry Smith } 397d4bb536fSBarry Smith 3983a40ed3dSBarry Smith PetscFunctionReturn(0); 399d4bb536fSBarry Smith } 400d4bb536fSBarry Smith 401