xref: /petsc/src/mat/impls/shell/shell.c (revision 3f1db9ec2fd39765c6c3a00831044586630c4cca)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*3f1db9ecSBarry Smith static char vcid[] = "$Id: shell.c,v 1.61 1998/07/23 22:47:58 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 
202f39d1f56SLois Curfman McInnes   Usage:
203f39d1f56SLois Curfman McInnes $    MatCreateShell(comm,m,n,M,N,ctx,&mat);
2041c1c02c0SLois Curfman McInnes $    MatShellSetOperation(mat,MATOP_MULT,mult);
205f39d1f56SLois Curfman McInnes $    [ Use matrix for operations that have been set ]
206f39d1f56SLois Curfman McInnes $    MatDestroy(mat);
207f39d1f56SLois Curfman McInnes 
208ff756334SLois Curfman McInnes    Notes:
209ff756334SLois Curfman McInnes    The shell matrix type is intended to provide a simple class to use
210ff756334SLois Curfman McInnes    with KSP (such as, for use with matrix-free methods). You should not
211ff756334SLois Curfman McInnes    use the shell type if you plan to define a complete matrix class.
212e51e0e81SBarry Smith 
213f39d1f56SLois Curfman McInnes    PETSc requires that matrices and vectors being used for certain
214f39d1f56SLois Curfman McInnes    operations are partitioned accordingly.  For example, when
215645985a0SLois Curfman McInnes    creating a shell matrix, A, that supports parallel matrix-vector
216645985a0SLois Curfman McInnes    products using MatMult(A,x,y) the user should set the number
217645985a0SLois Curfman McInnes    of local matrix rows to be the number of local elements of the
218645985a0SLois Curfman McInnes    corresponding result vector, y. Note that this is information is
219645985a0SLois Curfman McInnes    required for use of the matrix interface routines, even though
220645985a0SLois Curfman McInnes    the shell matrix may not actually be physically partitioned.
221645985a0SLois Curfman McInnes    For example,
222f39d1f56SLois Curfman McInnes 
223f39d1f56SLois Curfman McInnes $
224f39d1f56SLois Curfman McInnes $     Vec x, y
225645985a0SLois Curfman McInnes $     Mat A
226f39d1f56SLois Curfman McInnes $
227522c5e43SBarry Smith $     VecCreate(comm,PETSC_DECIDE,M,&y);
228522c5e43SBarry Smith $     VecCreate(comm,PETSC_DECIDE,N,&x);
229f39d1f56SLois Curfman McInnes $     VecGetLocalSize(y,&m);
230c7fcc2eaSBarry Smith $     VecGetLocalSize(x,&n);
231c7fcc2eaSBarry Smith $     MatCreateShell(comm,m,n,M,N,ctx,&A);
2321c1c02c0SLois Curfman McInnes $     MatShellSetOperation(mat,MATOP_MULT,mult);
233645985a0SLois Curfman McInnes $     MatMult(A,x,y);
234645985a0SLois Curfman McInnes $     MatDestroy(A);
235f39d1f56SLois Curfman McInnes $     VecDestroy(y); VecDestroy(x);
236645985a0SLois Curfman McInnes $
237e51e0e81SBarry Smith 
2380b627109SLois Curfman McInnes .keywords: matrix, shell, create
2390b627109SLois Curfman McInnes 
2403a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext()
241e51e0e81SBarry Smith @*/
242f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A)
243e51e0e81SBarry Smith {
24444cd7ae7SLois Curfman McInnes   Mat       B;
24544cd7ae7SLois Curfman McInnes   Mat_Shell *b;
246c7fcc2eaSBarry Smith   int       ierr;
247ed3cc1f0SBarry Smith 
2483a40ed3dSBarry Smith   PetscFunctionBegin;
249*3f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSHELL,"Mat",comm,MatDestroy,MatView);
25044cd7ae7SLois Curfman McInnes   PLogObjectCreate(B);
25144cd7ae7SLois Curfman McInnes   B->factor    = 0;
25244cd7ae7SLois Curfman McInnes   B->assembled = PETSC_TRUE;
25309dc0095SBarry Smith   PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));
254e1311b90SBarry Smith   B->ops->destroy   = MatDestroy_Shell;
255227d817aSBarry Smith 
25644cd7ae7SLois Curfman McInnes   b          = PetscNew(Mat_Shell); CHKPTRQ(b);
257eed86810SBarry Smith   PLogObjectMemory(B,sizeof(struct _p_Mat)+sizeof(Mat_Shell));
25844cd7ae7SLois Curfman McInnes   PetscMemzero(b,sizeof(Mat_Shell));
25944cd7ae7SLois Curfman McInnes   B->data   = (void *) b;
260c7fcc2eaSBarry Smith 
261c7fcc2eaSBarry Smith   if (m == PETSC_DECIDE || n == PETSC_DECIDE) {
262c7fcc2eaSBarry Smith     SETERRQ(1,1,"Must give local row and column count for matrix");
263c7fcc2eaSBarry Smith   }
264c7fcc2eaSBarry Smith 
265c7fcc2eaSBarry Smith   if (M == PETSC_DETERMINE || N == PETSC_DETERMINE) {
266c7fcc2eaSBarry Smith     int work[2], sum[2];
267c7fcc2eaSBarry Smith 
268c7fcc2eaSBarry Smith     work[0] = m; work[1] = n;
269c7fcc2eaSBarry Smith     ierr = MPI_Allreduce( work, sum,2,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr);
270c7fcc2eaSBarry Smith     if (M == PETSC_DECIDE) M = sum[0];
271c7fcc2eaSBarry Smith     if (N == PETSC_DECIDE) N = sum[1];
272c7fcc2eaSBarry Smith   }
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 
299fae171e0SBarry Smith     Usage:
300a62d957aSLois Curfman McInnes $      extern int usermult(Mat,Vec,Vec);
301f39d1f56SLois Curfman McInnes $      ierr = MatCreateShell(comm,m,n,M,N,ctx,&A);
3021c1c02c0SLois Curfman McInnes $      ierr = MatShellSetOperation(A,MATOP_MULT,usermult);
3030b627109SLois Curfman McInnes 
304a62d957aSLois Curfman McInnes     Notes:
305a62d957aSLois Curfman McInnes     See the file petsc/include/mat.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;
333a62d957aSLois Curfman McInnes     }
334e1311b90SBarry 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__
343d4bb536fSBarry Smith #define __FUNC__ "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 
356d4bb536fSBarry Smith     Notes:
357d4bb536fSBarry Smith     See the file petsc/include/mat.h for a complete list of matrix
358d4bb536fSBarry Smith     operations, which all have the form MATOP_<OPERATION>, where
359d4bb536fSBarry Smith     <OPERATION> is the name (in all capital letters) of the
360d4bb536fSBarry Smith     user interface routine (e.g., MatMult() -> MATOP_MULT).
361d4bb536fSBarry Smith 
362d4bb536fSBarry Smith     All user-provided functions have the same calling
363d4bb536fSBarry Smith     sequence as the usual matrix interface routines, since they
364d4bb536fSBarry Smith     are intended to be accessed via the usual matrix interface
365d4bb536fSBarry Smith     routines, e.g.,
366d4bb536fSBarry Smith $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
367d4bb536fSBarry Smith 
368d4bb536fSBarry Smith     Within each user-defined routine, the user should call
369d4bb536fSBarry Smith     MatShellGetContext() to obtain the user-defined context that was
370d4bb536fSBarry Smith     set by MatCreateShell().
371d4bb536fSBarry Smith 
372d4bb536fSBarry Smith .keywords: matrix, shell, set, operation
373d4bb536fSBarry Smith 
374d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation()
375d4bb536fSBarry Smith @*/
376d4bb536fSBarry Smith int MatShellGetOperation(Mat mat,MatOperation op, void **f)
377d4bb536fSBarry Smith {
3783a40ed3dSBarry Smith   PetscFunctionBegin;
379d4bb536fSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
380d4bb536fSBarry Smith 
381d4bb536fSBarry Smith   if (op == MATOP_DESTROY) {
382d4bb536fSBarry Smith     if (mat->type == MATSHELL) {
383d4bb536fSBarry Smith       Mat_Shell *shell = (Mat_Shell *) mat->data;
384d4bb536fSBarry Smith       *f = (void *) shell->destroy;
385c7fcc2eaSBarry Smith     } else {
386c7fcc2eaSBarry Smith       *f = (void *) mat->ops->destroy;
387d4bb536fSBarry Smith     }
388c7fcc2eaSBarry Smith   } else if (op == MATOP_VIEW) {
389c7fcc2eaSBarry Smith     *f = (void *) mat->ops->view;
390c7fcc2eaSBarry Smith   } else {
391c7fcc2eaSBarry Smith     *f = (((void**)&mat->ops)[op]);
392d4bb536fSBarry Smith   }
393d4bb536fSBarry Smith 
3943a40ed3dSBarry Smith   PetscFunctionReturn(0);
395d4bb536fSBarry Smith }
396d4bb536fSBarry Smith 
397