xref: /petsc/src/mat/impls/shell/shell.c (revision fae171e0928a68051052473fbd80ecaec6ec1e7e)
1 #ifndef lint
2 static char vcid[] = "$Id: shell.c,v 1.26 1996/03/19 21:26:12 bsmith Exp bsmith $";
3 #endif
4 
5 /*
6    This provides a simple shell for Fortran (and C programmers) to
7   create a very simple matrix class for use with KSP without coding
8   much of anything.
9 */
10 
11 #include "petsc.h"
12 #include "matimpl.h"        /*I "mat.h" I*/
13 #include "vec/vecimpl.h"
14 
15 typedef struct {
16   int  m, n;                       /* rows, columns */
17   int  (*destroy)(void*);
18   void *ctx;
19 } Mat_Shell;
20 
21 /*@
22     MatShellGetContext - Returns the user provided context associated
23          with a MatShell.
24 
25   Input Parameter:
26 .   mat - the matrix, should have been created with MatCreateShell()
27 
28   Output Parameter:
29 .   ctx - the user provided context
30 
31 @*/
32 int MatShellGetContext(Mat mat,void **ctx)
33 {
34   PetscValidHeaderSpecific(mat,MAT_COOKIE);
35   if (mat->type != MATSHELL) *ctx = 0;
36   else                       *ctx = ((Mat_Shell *) (mat->data))->ctx;
37   return 0;
38 }
39 
40 static int MatGetSize_Shell(Mat mat,int *m,int *n)
41 {
42   Mat_Shell *shell = (Mat_Shell *) mat->data;
43   *m = shell->m; *n = shell->n;
44   return 0;
45 }
46 
47 static int MatDestroy_Shell(PetscObject obj)
48 {
49   int       ierr;
50   Mat       mat = (Mat) obj;
51   Mat_Shell *shell;
52 
53   shell = (Mat_Shell *) mat->data;
54   if (shell->destroy) {ierr = (*shell->destroy)(shell->ctx);CHKERRQ(ierr);}
55   PetscFree(shell);
56   PLogObjectDestroy(mat);
57   PetscHeaderDestroy(mat);
58   return 0;
59 }
60 
61 static struct _MatOps MatOps = {0,0,
62        0,
63        0,0,0,0,
64        0,0,0,0,
65        0,0,
66        0,
67        0,
68        0,0,0,
69        0,
70        0,0,0,
71        0,0,
72        0,
73        0,0,0,0,
74        0,0,MatGetSize_Shell,
75        0,0,0,0,
76        0,0,0,0 };
77 
78 /*@C
79    MatCreateShell - Creates a new matrix class for use with a user-defined
80    private data storage format.
81 
82    Input Parameters:
83 .  comm - MPI communicator
84 .  m - number of rows
85 .  n - number of columns
86 .  ctx - pointer to data needed by the matrix routines
87 
88    Output Parameter:
89 .  mat - the matrix
90 
91    Notes:
92    The shell matrix type is intended to provide a simple class to use
93    with KSP (such as, for use with matrix-free methods). You should not
94    use the shell type if you plan to define a complete matrix class.
95 
96   Usage:
97 $   MatCreateShell(m,n,ctx,&mat);
98 $   MatSetOperation(mat,MAT_MULT,mult);
99 
100 .keywords: matrix, shell, create
101 
102 .seealso: MatSetOperation(), MatHasOperation(), MatShellGetContext()
103 @*/
104 int MatCreateShell(MPI_Comm comm,int m,int n,void *ctx,Mat *mat)
105 {
106   Mat       newmat;
107   Mat_Shell *shell;
108 
109   PetscHeaderCreate(newmat,_Mat,MAT_COOKIE,MATSHELL,comm);
110   PLogObjectCreate(newmat);
111   *mat              = newmat;
112   newmat->factor    = 0;
113   newmat->destroy   = MatDestroy_Shell;
114   newmat->assembled = PETSC_TRUE;
115   PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps));
116 
117   shell          = PetscNew(Mat_Shell); CHKPTRQ(shell);
118   PetscMemzero(shell,sizeof(Mat_Shell));
119   newmat->data   = (void *) shell;
120   shell->m       = m;
121   shell->n       = n;
122   shell->ctx     = ctx;
123   return 0;
124 }
125 
126 /*@
127     MatShellSetOperation - Allows use to set a matrix operation for a shell matrix.
128 
129   Input Parameters:
130 .   mat - the shell matrix
131 .   op - the name of the operation
132 .   f - the function that provides the operation.
133 
134   Usage:
135    extern int mult(Mat,Vec,Vec);
136    ierr = MatCreateShell(comm,m,m,ctx,&A);
137    ierr = MatSetOperation(A,MAT_MULT,mult);
138 
139    In the user provided function, use MatShellGetContext() to obtain the
140 context passed into MatCreateShell().
141 @*/
142 int MatShellSetOperation(Mat mat,MatOperation op, void *f)
143 {
144   PetscValidHeaderSpecific(mat,MAT_COOKIE);
145 
146   if (op == MAT_DESTROY)   mat->destroy              = (int (*)(PetscObject)) f;
147   else if (op == MAT_VIEW) mat->view                 = (int (*)(PetscObject,Viewer)) f;
148   else                     (((void **)&mat->ops)[op])= f;
149   return 0;
150 }
151 
152