xref: /petsc/src/mat/impls/shell/shell.c (revision 4b33d51a05c989562b9b24c7595ed9e56756eaaf)
1 #ifndef lint
2 static char vcid[] = "$Id: shell.c,v 1.22 1995/11/03 03:00:36 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  (*mult)(void*,Vec,Vec);
18   int  (*multtransadd)(void*,Vec,Vec,Vec);
19   int  (*destroy)(void*);
20   int  (*getsize)(void*,int*,int*);
21   void *ctx;
22 } Mat_Shell;
23 
24 /*@
25     MatShellGetContext - Returns the user provided context associated
26          with a MatShell.
27 
28   Input Parameter:
29 .   mat - the matrix, should have been created with MatCreateShell()
30 
31   Output Parameter:
32 .   ctx - the user provided context
33 
34 @*/
35 int MatShellGetContext(Mat mat,void **ctx)
36 {
37   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
38   if (mat->type != MATSHELL) *ctx = 0;
39   else                       *ctx = ((Mat_Shell *) (mat->data))->ctx;
40   return 0;
41 }
42 
43 static int MatGetSize_Shell(Mat mat,int *m,int *n)
44 {
45   Mat_Shell *shell = (Mat_Shell *) mat->data;
46   *m = shell->m; *n = shell->n;
47   return 0;
48 }
49 
50 static int MatMult_Shell(Mat mat,Vec x,Vec y)
51 {
52   Mat_Shell *shell = (Mat_Shell *) mat->data;
53   return (*shell->mult)(shell->ctx,x,y);
54 }
55 
56 static int MatMultTransAdd_Shell(Mat mat,Vec x,Vec y,Vec z)
57 {
58   Mat_Shell *shell = (Mat_Shell *) mat->data;
59   return (*shell->multtransadd)(shell->ctx,x,y,z);
60 }
61 
62 static int MatDestroy_Shell(PetscObject obj)
63 {
64   int       ierr;
65   Mat       mat = (Mat) obj;
66   Mat_Shell *shell;
67 
68   shell = (Mat_Shell *) mat->data;
69   if (shell->destroy) {ierr = (*shell->destroy)(shell->ctx);CHKERRQ(ierr);}
70   PetscFree(shell);
71   PLogObjectDestroy(mat);
72   PetscHeaderDestroy(mat);
73   return 0;
74 }
75 
76 static struct _MatOps MatOps = {0,0,
77        0,
78        MatMult_Shell,0,0,MatMultTransAdd_Shell,
79        0,0,0,0,
80        0,0,
81        0,
82        0,
83        0,0,0,
84        0,
85        0,0,0,
86        0,0,
87        0,
88        0,0,0,0,
89        0,0,MatGetSize_Shell,
90        0,0,0,0,
91        0,0,0,0 };
92 
93 /*@C
94    MatShellCreate - Creates a new matrix class for use with a user-defined
95    private data storage format.
96 
97    Input Parameters:
98 .  comm - MPI communicator
99 .  m - number of rows
100 .  n - number of columns
101 .  ctx - pointer to data needed by matrix-vector multiplication routine(s)
102 
103    Output Parameter:
104 .  mat - the matrix
105 
106    Notes:
107    The shell matrix type is intended to provide a simple class to use
108    with KSP (such as, for use with matrix-free methods). You should not
109    use the shell type if you plan to define a complete matrix class.
110 
111   Usage:
112 $   MatShellCreate(m,n,ctx,&mat);
113 $   MatShellSetMult(mat,mult);
114 
115 .keywords: matrix, shell, create
116 
117 .seealso: MatShellSetMult(), MatShellSetMultTransAdd()
118 @*/
119 int MatShellCreate(MPI_Comm comm,int m,int n,void *ctx,Mat *mat)
120 {
121   Mat       newmat;
122   Mat_Shell *shell;
123 
124   PetscHeaderCreate(newmat,_Mat,MAT_COOKIE,MATSHELL,comm);
125   PLogObjectCreate(newmat);
126   *mat           = newmat;
127   newmat->factor = 0;
128   newmat->destroy= MatDestroy_Shell;
129   PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps));
130   shell          = PetscNew(Mat_Shell); CHKPTRQ(shell);
131   PetscMemzero(shell,sizeof(Mat_Shell));
132   newmat->data   = (void *) shell;
133   shell->mult    = 0;
134   shell->m       = m;
135   shell->n       = n;
136   shell->ctx     = ctx;
137   return 0;
138 }
139 
140 /*@C
141    MatShellSetMult - Sets the routine for computing the matrix-vector product.
142 
143    Input Parameters:
144 .  mat - the matrix associated with this operation, created
145          with MatShellCreate()
146 .  mult - the user-defined routine
147 
148    Calling sequence of mult:
149    int mult (void *ptr,Vec xin,Vec xout)
150 .  ptr - the application context for matrix data
151 .  xin - input vector
152 .  xout - output vector
153 
154 .keywords: matrix, multiply, shell, set
155 
156 .seealso: MatShellCreate(), MatShellSetMultTransAdd()
157 @*/
158 int MatShellSetMult(Mat mat,int (*mult)(void*,Vec,Vec))
159 {
160   Mat_Shell *shell;
161   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
162   shell = (Mat_Shell *) mat->data;
163   shell->mult = mult;
164   return 0;
165 }
166 /*@C
167    MatShellSetMultTransAdd - Sets the routine for computing v3 = v2 + A' * v1.
168 
169    Input Parameters:
170 .  mat - the matrix associated with this operation, created
171          with MatShellCreate()
172 .  mult - the user-defined routine
173 
174    Calling sequence of mult:
175    int mult (void *ptr,Vec v1,Vec v2,Vec v3)
176 .  ptr - the application context for matrix data
177 .  v1, v2 - the input vectors
178 .  v3 - the result
179 
180 .keywords: matrix, multiply, transpose
181 
182 .seealso: MatShellCreate(), MatShellSetMult()
183 @*/
184 int MatShellSetMultTransAdd(Mat mat,int (*mult)(void*,Vec,Vec,Vec))
185 {
186   Mat_Shell *shell;
187   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
188   shell               = (Mat_Shell *) mat->data;
189   shell->multtransadd = mult;
190   return 0;
191 }
192 /*@C
193    MatShellSetDestroy - Set the routine to use to destroy the
194         private contents of your MatShell.
195 
196    Input Parameters:
197 .  mat - the matrix associated with this operation, created
198          with MatShellCreate()
199 .  destroy - the user-defined routine
200 
201    Calling sequence of mult:
202    int destroy (void *ptr)
203 .  ptr - the application context for matrix data
204 
205 .keywords: matrix, destroy, shell, set
206 
207 .seealso: MatShellCreate()
208 @*/
209 int MatShellSetDestroy(Mat mat,int (*destroy)(void*))
210 {
211   Mat_Shell *shell;
212   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
213   shell = (Mat_Shell *) mat->data;
214   shell->destroy = destroy;
215   return 0;
216 }
217 
218 
219