xref: /petsc/src/mat/impls/shell/shell.c (revision deebb3c3fd3213c602f3e5660fb3343d8a7e852b)
1 #ifndef lint
2 static char vcid[] = "$Id: shell.c,v 1.30 1996/03/31 16:50:54 bsmith Exp curfman $";
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)(Mat);
18   void *ctx;
19 } Mat_Shell;
20 
21 /*@
22     MatShellGetContext - Returns the user-provided context associated with a shell matrix.
23 
24     Input Parameter:
25 .   mat - the matrix, should have been created with MatCreateShell()
26 
27     Output Parameter:
28 .   ctx - the user provided context
29 
30     Notes:
31     This routine is intended for use within various shell matrix routines,
32     as set with MatShellSetOperation().
33 
34 .keywords: matrix, shell, get, context
35 
36 .seealso: MatCreateShell(), MatShellSetOperation()
37 @*/
38 int MatShellGetContext(Mat mat,void **ctx)
39 {
40   PetscValidHeaderSpecific(mat,MAT_COOKIE);
41   if (mat->type != MATSHELL) *ctx = 0;
42   else                       *ctx = ((Mat_Shell *) (mat->data))->ctx;
43   return 0;
44 }
45 
46 static int MatGetSize_Shell(Mat mat,int *m,int *n)
47 {
48   Mat_Shell *shell = (Mat_Shell *) mat->data;
49   *m = shell->m; *n = shell->n;
50   return 0;
51 }
52 
53 static int MatDestroy_Shell(PetscObject obj)
54 {
55   int       ierr;
56   Mat       mat = (Mat) obj;
57   Mat_Shell *shell;
58 
59   shell = (Mat_Shell *) mat->data;
60   if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);}
61   PetscFree(shell);
62   PLogObjectDestroy(mat);
63   PetscHeaderDestroy(mat);
64   return 0;
65 }
66 
67 static struct _MatOps MatOps = {0,0,
68        0,
69        0,0,0,0,
70        0,0,0,0,
71        0,0,
72        0,
73        0,
74        0,0,0,
75        0,
76        0,0,0,
77        0,0,
78        0,
79        0,0,0,0,
80        0,0,MatGetSize_Shell,
81        0,0,0,0,
82        0,0,0,0 };
83 
84 /*@C
85    MatCreateShell - Creates a new matrix class for use with a user-defined
86    private data storage format.
87 
88    Input Parameters:
89 .  comm - MPI communicator
90 .  m - number of rows
91 .  n - number of columns
92 .  ctx - pointer to data needed by the shell matrix routines
93 
94    Output Parameter:
95 .  mat - the matrix
96 
97    Notes:
98    The shell matrix type is intended to provide a simple class to use
99    with KSP (such as, for use with matrix-free methods). You should not
100    use the shell type if you plan to define a complete matrix class.
101 
102    Usage:
103 $   MatCreateShell(m,n,ctx,&mat);
104 $   MatShellSetOperation(mat,MAT_MULT,mult);
105 $   [ Use matrix for operations that have been set ]
106 $   MatDestroy(mat);
107 
108 .keywords: matrix, shell, create
109 
110 .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext()
111 @*/
112 int MatCreateShell(MPI_Comm comm,int m,int n,void *ctx,Mat *mat)
113 {
114   Mat       newmat;
115   Mat_Shell *shell;
116 
117   PetscHeaderCreate(newmat,_Mat,MAT_COOKIE,MATSHELL,comm);
118   PLogObjectCreate(newmat);
119   *mat              = newmat;
120   newmat->factor    = 0;
121   newmat->destroy   = MatDestroy_Shell;
122   newmat->assembled = PETSC_TRUE;
123   PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps));
124 
125   shell          = PetscNew(Mat_Shell); CHKPTRQ(shell);
126   PetscMemzero(shell,sizeof(Mat_Shell));
127   newmat->data   = (void *) shell;
128   shell->m       = m;
129   shell->n       = n;
130   shell->ctx     = ctx;
131   return 0;
132 }
133 
134 /*@
135     MatShellSetOperation - Allows user to set a matrix operation for
136                            a shell matrix.
137 
138     Input Parameters:
139 .   mat - the shell matrix
140 .   op - the name of the operation
141 .   f - the function that provides the operation.
142 
143     Usage:
144 $      extern int usermult(Mat,Vec,Vec);
145 $      ierr = MatCreateShell(comm,m,m,ctx,&A);
146 $      ierr = MatShellSetOperation(A,MAT_MULT,usermult);
147 
148     Notes:
149     See the file petsc/include/mat.h for a complete list of matrix
150     operations, which all have the form MAT_<OPERATION>, where
151     <OPERATION> is the name (in all capital letters) of the
152     user interface routine (e.g., MatMult() -> MAT_MULT).
153 
154     All user-provided functions should have the same calling
155     sequence as the usual matrix interface routines, since they
156     are intended to be accessed via the usual matrix interface
157     routines, e.g.,
158 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
159 
160     Within each user-defined routine, the user should call
161     MatShellGetContext() to obtain the user-defined context that was
162     set by MatCreateShell().
163 
164 .keywords: matrix, shell, set, operation
165 
166 .seealso: MatCreateShell(), MatShellGetContext()
167 @*/
168 int MatShellSetOperation(Mat mat,MatOperation op, void *f)
169 {
170   PetscValidHeaderSpecific(mat,MAT_COOKIE);
171 
172   if (op == MAT_DESTROY) {
173     if (mat->type == MATSHELL) {
174        Mat_Shell *shell = (Mat_Shell *) mat->data;
175        shell->destroy                                 = (int (*)(Mat)) f;
176     }
177     else mat->destroy                                 = (int (*)(PetscObject)) f;
178   }
179   else if (op == MAT_VIEW) mat->view                  = (int (*)(PetscObject,Viewer)) f;
180   else                     (((void **)&mat->ops)[op]) = f;
181 
182   return 0;
183 }
184 
185 
186 
187 
188 
189 
190