1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*ff2fd236SBarry Smith static char vcid[] = "$Id: shell.c,v 1.65 1999/03/01 04:53:54 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 35a62d957aSLois Curfman McInnes Notes: 36a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 37a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 38a62d957aSLois Curfman McInnes 39a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 40a62d957aSLois Curfman McInnes 41a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellSetOperation() 42b4fd4287SBarry Smith @*/ 43b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx) 44b4fd4287SBarry Smith { 453a40ed3dSBarry Smith PetscFunctionBegin; 4677c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 47b4fd4287SBarry Smith if (mat->type != MATSHELL) *ctx = 0; 48b4fd4287SBarry Smith else *ctx = ((Mat_Shell *) (mat->data))->ctx; 493a40ed3dSBarry Smith PetscFunctionReturn(0); 50b4fd4287SBarry Smith } 51b4fd4287SBarry Smith 525615d1e5SSatish Balay #undef __FUNC__ 53d4bb536fSBarry Smith #define __FUNC__ "MatGetSize_Shell" 548f6be9afSLois Curfman McInnes int MatGetSize_Shell(Mat mat,int *M,int *N) 5571b459e3SLois Curfman McInnes { 5671b459e3SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 573a40ed3dSBarry Smith 583a40ed3dSBarry Smith PetscFunctionBegin; 59f830108cSBarry Smith if (M) *M = shell->M; 60f830108cSBarry Smith if (N) *N = shell->N; 613a40ed3dSBarry Smith PetscFunctionReturn(0); 62f39d1f56SLois Curfman McInnes } 63f39d1f56SLois Curfman McInnes 645615d1e5SSatish Balay #undef __FUNC__ 65d4bb536fSBarry Smith #define __FUNC__ "MatGetLocalSize_Shell" 668f6be9afSLois Curfman McInnes int MatGetLocalSize_Shell(Mat mat,int *m,int *n) 67f39d1f56SLois Curfman McInnes { 68f39d1f56SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 693a40ed3dSBarry Smith 703a40ed3dSBarry Smith PetscFunctionBegin; 71f830108cSBarry Smith if (m) *m = shell->m; 72f830108cSBarry Smith if (n) *n = shell->n; 733a40ed3dSBarry Smith PetscFunctionReturn(0); 7471b459e3SLois Curfman McInnes } 7571b459e3SLois Curfman McInnes 765615d1e5SSatish Balay #undef __FUNC__ 77d4bb536fSBarry Smith #define __FUNC__ "MatDestroy_Shell" 78e1311b90SBarry Smith int MatDestroy_Shell(Mat mat) 79e51e0e81SBarry Smith { 80b9fa9cd0SBarry Smith int ierr; 8188cf3e7dSBarry Smith Mat_Shell *shell; 82ed3cc1f0SBarry Smith 833a40ed3dSBarry Smith PetscFunctionBegin; 8494d884c6SBarry Smith if (--mat->refct > 0) PetscFunctionReturn(0); 8594d884c6SBarry Smith 8694d884c6SBarry Smith if (mat->mapping) { 8794d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->mapping); CHKERRQ(ierr); 8894d884c6SBarry Smith } 8994d884c6SBarry Smith if (mat->bmapping) { 9094d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->bmapping); CHKERRQ(ierr); 9194d884c6SBarry Smith } 9261b13de0SBarry Smith if (mat->rmap) { 9361b13de0SBarry Smith ierr = MapDestroy(mat->rmap);CHKERRQ(ierr); 9461b13de0SBarry Smith } 9561b13de0SBarry Smith if (mat->cmap) { 9661b13de0SBarry Smith ierr = MapDestroy(mat->cmap);CHKERRQ(ierr); 9761b13de0SBarry Smith } 9888cf3e7dSBarry Smith shell = (Mat_Shell *) mat->data; 993a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 1000452661fSBarry Smith PetscFree(shell); 1013a3eedf2SBarry Smith PLogObjectDestroy(mat); 1023a3eedf2SBarry Smith PetscHeaderDestroy(mat); 1033a40ed3dSBarry Smith PetscFunctionReturn(0); 104e51e0e81SBarry Smith } 105e51e0e81SBarry Smith 1068f6be9afSLois Curfman McInnes int MatGetOwnershipRange_Shell(Mat mat, int *rstart,int *rend) 107b951964fSBarry Smith { 108ca161407SBarry Smith int ierr; 109ca161407SBarry Smith 110ca161407SBarry Smith PetscFunctionBegin; 111ca161407SBarry Smith ierr = MPI_Scan(&mat->m,rend,1,MPI_INT,MPI_SUM,mat->comm);CHKERRQ(ierr); 112b951964fSBarry Smith *rstart = *rend - mat->m; 1133a40ed3dSBarry Smith PetscFunctionReturn(0); 114b951964fSBarry Smith } 115b951964fSBarry Smith 11609dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 11720563c6bSBarry Smith 0, 11820563c6bSBarry Smith 0, 11920563c6bSBarry Smith 0, 12020563c6bSBarry Smith 0, 121b951964fSBarry 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 MatGetSize_Shell, 147b951964fSBarry Smith MatGetLocalSize_Shell, 148b951964fSBarry Smith MatGetOwnershipRange_Shell, 149b951964fSBarry Smith 0, 150b951964fSBarry Smith 0, 151b951964fSBarry Smith 0, 152b951964fSBarry Smith 0, 15309dc0095SBarry 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 MatGetMaps_Petsc}; 182e51e0e81SBarry Smith 1835615d1e5SSatish Balay #undef __FUNC__ 184d4bb536fSBarry Smith #define __FUNC__ "MatCreateShell" 1854b828684SBarry Smith /*@C 186052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 187ff756334SLois Curfman McInnes private data storage format. 188e51e0e81SBarry Smith 189c7fcc2eaSBarry Smith Collective on MPI_Comm 190c7fcc2eaSBarry Smith 191e51e0e81SBarry Smith Input Parameters: 192c7fcc2eaSBarry Smith + comm - MPI communicator 193c7fcc2eaSBarry Smith . m - number of local rows (must be given) 194c7fcc2eaSBarry Smith . n - number of local columns (must be given) 195c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 196c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 197c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 198e51e0e81SBarry Smith 199ff756334SLois Curfman McInnes Output Parameter: 20044cd7ae7SLois Curfman McInnes . A - the matrix 201e51e0e81SBarry Smith 202*ff2fd236SBarry Smith Level: advanced 203*ff2fd236SBarry Smith 204f39d1f56SLois Curfman McInnes Usage: 2057b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 206f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 2077b2a1423SBarry Smith $ MatShellSetOperation(mat,MATOP_MULT,(void *)mult); 208f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 209f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 210f39d1f56SLois Curfman McInnes 211ff756334SLois Curfman McInnes Notes: 212ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 213ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 214ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 215e51e0e81SBarry Smith 216f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 217f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 218645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 219645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 220645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 221645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 222645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 223645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 224645985a0SLois Curfman McInnes For example, 225f39d1f56SLois Curfman McInnes 226f39d1f56SLois Curfman McInnes $ 227f39d1f56SLois Curfman McInnes $ Vec x, y 2287b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 229645985a0SLois Curfman McInnes $ Mat A 230f39d1f56SLois Curfman McInnes $ 231c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 232c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 233f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 234c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 235c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 2367b2a1423SBarry Smith $ MatShellSetOperation(mat,MATOP_MULT,(void *)mult); 237645985a0SLois Curfman McInnes $ MatMult(A,x,y); 238645985a0SLois Curfman McInnes $ MatDestroy(A); 239f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 240645985a0SLois Curfman McInnes $ 241e51e0e81SBarry Smith 2420b627109SLois Curfman McInnes .keywords: matrix, shell, create 2430b627109SLois Curfman McInnes 2443a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext() 245e51e0e81SBarry Smith @*/ 246f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A) 247e51e0e81SBarry Smith { 24844cd7ae7SLois Curfman McInnes Mat B; 24944cd7ae7SLois Curfman McInnes Mat_Shell *b; 250c7fcc2eaSBarry Smith int ierr; 251ed3cc1f0SBarry Smith 2523a40ed3dSBarry Smith PetscFunctionBegin; 2533f1db9ecSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSHELL,"Mat",comm,MatDestroy,MatView); 25444cd7ae7SLois Curfman McInnes PLogObjectCreate(B); 25544cd7ae7SLois Curfman McInnes B->factor = 0; 25644cd7ae7SLois Curfman McInnes B->assembled = PETSC_TRUE; 25709dc0095SBarry Smith PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); 258e1311b90SBarry Smith B->ops->destroy = MatDestroy_Shell; 259227d817aSBarry Smith 26044cd7ae7SLois Curfman McInnes b = PetscNew(Mat_Shell); CHKPTRQ(b); 261eed86810SBarry Smith PLogObjectMemory(B,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 26244cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_Shell)); 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__ 285d4bb536fSBarry Smith #define __FUNC__ "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 297fae171e0SBarry Smith Usage: 298a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 299f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 300c94f878dSBarry Smith $ ierr = MatShellSetOperation(A,MATOP_MULT,(void*) usermult); 3010b627109SLois Curfman McInnes 302a62d957aSLois Curfman McInnes Notes: 303a62d957aSLois Curfman McInnes See the file petsc/include/mat.h for a complete list of matrix 3041c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 305a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 3061c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 307a62d957aSLois Curfman McInnes 308a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 309deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 310deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 311deebb3c3SLois Curfman McInnes routines, e.g., 312a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 313a62d957aSLois Curfman McInnes 314a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 315a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 316a62d957aSLois Curfman McInnes set by MatCreateShell(). 317a62d957aSLois Curfman McInnes 318a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 319a62d957aSLois Curfman McInnes 320d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 321e51e0e81SBarry Smith @*/ 322fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op, void *f) 323e51e0e81SBarry Smith { 3243a40ed3dSBarry Smith PetscFunctionBegin; 32577c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 326fae171e0SBarry Smith 3271c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 328a62d957aSLois Curfman McInnes if (mat->type == MATSHELL) { 329a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 3303a3eedf2SBarry Smith shell->destroy = (int (*)(Mat)) f; 331a62d957aSLois Curfman McInnes } 332e1311b90SBarry Smith else mat->ops->destroy = (int (*)(Mat)) f; 333a62d957aSLois Curfman McInnes } 334e1311b90SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (int (*)(Mat,Viewer)) f; 335f830108cSBarry Smith else (((void**)mat->ops)[op]) = f; 336a62d957aSLois Curfman McInnes 3373a40ed3dSBarry Smith PetscFunctionReturn(0); 338e51e0e81SBarry Smith } 339f0479e8cSBarry Smith 340d4bb536fSBarry Smith #undef __FUNC__ 341d4bb536fSBarry Smith #define __FUNC__ "MatShellGetOperation" 342d4bb536fSBarry Smith /*@C 343d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 344d4bb536fSBarry Smith 345c7fcc2eaSBarry Smith Not Collective 346c7fcc2eaSBarry Smith 347d4bb536fSBarry Smith Input Parameters: 348c7fcc2eaSBarry Smith + mat - the shell matrix 349c7fcc2eaSBarry Smith - op - the name of the operation 350d4bb536fSBarry Smith 351d4bb536fSBarry Smith Output Parameter: 352d4bb536fSBarry Smith . f - the function that provides the operation. 353d4bb536fSBarry Smith 354d4bb536fSBarry Smith Notes: 355d4bb536fSBarry Smith See the file petsc/include/mat.h for a complete list of matrix 356d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 357d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 358d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 359d4bb536fSBarry Smith 360d4bb536fSBarry Smith All user-provided functions have the same calling 361d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 362d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 363d4bb536fSBarry Smith routines, e.g., 364d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 365d4bb536fSBarry Smith 366d4bb536fSBarry Smith Within each user-defined routine, the user should call 367d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 368d4bb536fSBarry Smith set by MatCreateShell(). 369d4bb536fSBarry Smith 370d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 371d4bb536fSBarry Smith 372d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation() 373d4bb536fSBarry Smith @*/ 374d4bb536fSBarry Smith int MatShellGetOperation(Mat mat,MatOperation op, void **f) 375d4bb536fSBarry Smith { 3763a40ed3dSBarry Smith PetscFunctionBegin; 377d4bb536fSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 378d4bb536fSBarry Smith 379d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 380d4bb536fSBarry Smith if (mat->type == MATSHELL) { 381d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell *) mat->data; 382d4bb536fSBarry Smith *f = (void *) shell->destroy; 383c7fcc2eaSBarry Smith } else { 384c7fcc2eaSBarry Smith *f = (void *) mat->ops->destroy; 385d4bb536fSBarry Smith } 386c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 387c7fcc2eaSBarry Smith *f = (void *) mat->ops->view; 388c7fcc2eaSBarry Smith } else { 389c7fcc2eaSBarry Smith *f = (((void**)&mat->ops)[op]); 390d4bb536fSBarry Smith } 391d4bb536fSBarry Smith 3923a40ed3dSBarry Smith PetscFunctionReturn(0); 393d4bb536fSBarry Smith } 394d4bb536fSBarry Smith 395