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