xref: /petsc/src/mat/impls/shell/shell.c (revision 052efed2d4d49f85092290ff2aaacf5d901780e1)
1357feee3SLois Curfman McInnes #ifndef lint
2*052efed2SBarry Smith static char vcid[] = "$Id: shell.c,v 1.23 1995/12/21 18:31:54 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"
12e51e0e81SBarry Smith #include "matimpl.h"        /*I "mat.h" I*/
13e51e0e81SBarry Smith #include "vec/vecimpl.h"
14e51e0e81SBarry Smith 
1520563c6bSBarry Smith typedef struct {
1671b459e3SLois Curfman McInnes   int  m, n;                       /* rows, columns */
1720563c6bSBarry Smith   int  (*mult)(void*,Vec,Vec);
18f0479e8cSBarry Smith   int  (*multtransadd)(void*,Vec,Vec,Vec);
19b9fa9cd0SBarry Smith   int  (*destroy)(void*);
2071b459e3SLois Curfman McInnes   int  (*getsize)(void*,int*,int*);
2120563c6bSBarry Smith   void *ctx;
2288cf3e7dSBarry Smith } Mat_Shell;
23e51e0e81SBarry Smith 
24b4fd4287SBarry Smith /*@
25b4fd4287SBarry Smith     MatShellGetContext - Returns the user provided context associated
26b4fd4287SBarry Smith          with a MatShell.
27b4fd4287SBarry Smith 
28b4fd4287SBarry Smith   Input Parameter:
29b4fd4287SBarry Smith .   mat - the matrix, should have been created with MatCreateShell()
30b4fd4287SBarry Smith 
31b4fd4287SBarry Smith   Output Parameter:
32b4fd4287SBarry Smith .   ctx - the user provided context
33b4fd4287SBarry Smith 
34b4fd4287SBarry Smith @*/
35b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx)
36b4fd4287SBarry Smith {
37b4fd4287SBarry Smith   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
38b4fd4287SBarry Smith   if (mat->type != MATSHELL) *ctx = 0;
39b4fd4287SBarry Smith   else                       *ctx = ((Mat_Shell *) (mat->data))->ctx;
40b4fd4287SBarry Smith   return 0;
41b4fd4287SBarry Smith }
42b4fd4287SBarry Smith 
4371b459e3SLois Curfman McInnes static int MatGetSize_Shell(Mat mat,int *m,int *n)
4471b459e3SLois Curfman McInnes {
4571b459e3SLois Curfman McInnes   Mat_Shell *shell = (Mat_Shell *) mat->data;
4671b459e3SLois Curfman McInnes   *m = shell->m; *n = shell->n;
4771b459e3SLois Curfman McInnes   return 0;
4871b459e3SLois Curfman McInnes }
4971b459e3SLois Curfman McInnes 
5088cf3e7dSBarry Smith static int MatMult_Shell(Mat mat,Vec x,Vec y)
51e51e0e81SBarry Smith {
5271b459e3SLois Curfman McInnes   Mat_Shell *shell = (Mat_Shell *) mat->data;
5320563c6bSBarry Smith   return (*shell->mult)(shell->ctx,x,y);
54e51e0e81SBarry Smith }
5571b459e3SLois Curfman McInnes 
5688cf3e7dSBarry Smith static int MatMultTransAdd_Shell(Mat mat,Vec x,Vec y,Vec z)
57f0479e8cSBarry Smith {
5871b459e3SLois Curfman McInnes   Mat_Shell *shell = (Mat_Shell *) mat->data;
59f0479e8cSBarry Smith   return (*shell->multtransadd)(shell->ctx,x,y,z);
60f0479e8cSBarry Smith }
6171b459e3SLois Curfman McInnes 
6288cf3e7dSBarry Smith static int MatDestroy_Shell(PetscObject obj)
63e51e0e81SBarry Smith {
64b9fa9cd0SBarry Smith   int       ierr;
6520563c6bSBarry Smith   Mat       mat = (Mat) obj;
6688cf3e7dSBarry Smith   Mat_Shell *shell;
67ed3cc1f0SBarry Smith 
6888cf3e7dSBarry Smith   shell = (Mat_Shell *) mat->data;
69b9fa9cd0SBarry Smith   if (shell->destroy) {ierr = (*shell->destroy)(shell->ctx);CHKERRQ(ierr);}
700452661fSBarry Smith   PetscFree(shell);
71a5a9c739SBarry Smith   PLogObjectDestroy(mat);
720452661fSBarry Smith   PetscHeaderDestroy(mat);
73e51e0e81SBarry Smith   return 0;
74e51e0e81SBarry Smith }
75e51e0e81SBarry Smith 
7620563c6bSBarry Smith static struct _MatOps MatOps = {0,0,
7720563c6bSBarry Smith        0,
7888cf3e7dSBarry Smith        MatMult_Shell,0,0,MatMultTransAdd_Shell,
7920563c6bSBarry Smith        0,0,0,0,
8020563c6bSBarry Smith        0,0,
8120563c6bSBarry Smith        0,
8220563c6bSBarry Smith        0,
8320563c6bSBarry Smith        0,0,0,
8420563c6bSBarry Smith        0,
8520563c6bSBarry Smith        0,0,0,
8620563c6bSBarry Smith        0,0,
8720563c6bSBarry Smith        0,
8820563c6bSBarry Smith        0,0,0,0,
8971b459e3SLois Curfman McInnes        0,0,MatGetSize_Shell,
9071b459e3SLois Curfman McInnes        0,0,0,0,
9171b459e3SLois Curfman McInnes        0,0,0,0 };
92e51e0e81SBarry Smith 
934b828684SBarry Smith /*@C
94*052efed2SBarry Smith    MatCreateShell - Creates a new matrix class for use with a user-defined
95ff756334SLois Curfman McInnes    private data storage format.
96e51e0e81SBarry Smith 
97e51e0e81SBarry Smith    Input Parameters:
986b5873e3SBarry Smith .  comm - MPI communicator
99ff756334SLois Curfman McInnes .  m - number of rows
100ff756334SLois Curfman McInnes .  n - number of columns
1010b627109SLois Curfman McInnes .  ctx - pointer to data needed by matrix-vector multiplication routine(s)
102e51e0e81SBarry Smith 
103ff756334SLois Curfman McInnes    Output Parameter:
104e51e0e81SBarry Smith .  mat - the matrix
105e51e0e81SBarry Smith 
106ff756334SLois Curfman McInnes    Notes:
107ff756334SLois Curfman McInnes    The shell matrix type is intended to provide a simple class to use
108ff756334SLois Curfman McInnes    with KSP (such as, for use with matrix-free methods). You should not
109ff756334SLois Curfman McInnes    use the shell type if you plan to define a complete matrix class.
110e51e0e81SBarry Smith 
11120563c6bSBarry Smith   Usage:
112*052efed2SBarry Smith $   MatCreateShell(m,n,ctx,&mat);
113ff756334SLois Curfman McInnes $   MatShellSetMult(mat,mult);
114e51e0e81SBarry Smith 
1150b627109SLois Curfman McInnes .keywords: matrix, shell, create
1160b627109SLois Curfman McInnes 
1170b627109SLois Curfman McInnes .seealso: MatShellSetMult(), MatShellSetMultTransAdd()
118e51e0e81SBarry Smith @*/
119*052efed2SBarry Smith int MatCreateShell(MPI_Comm comm,int m,int n,void *ctx,Mat *mat)
120e51e0e81SBarry Smith {
12120563c6bSBarry Smith   Mat       newmat;
12288cf3e7dSBarry Smith   Mat_Shell *shell;
123ed3cc1f0SBarry Smith 
1240452661fSBarry Smith   PetscHeaderCreate(newmat,_Mat,MAT_COOKIE,MATSHELL,comm);
125a5a9c739SBarry Smith   PLogObjectCreate(newmat);
12620563c6bSBarry Smith   *mat           = newmat;
12720563c6bSBarry Smith   newmat->factor = 0;
12888cf3e7dSBarry Smith   newmat->destroy= MatDestroy_Shell;
129416022c9SBarry Smith   PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps));
1300452661fSBarry Smith   shell          = PetscNew(Mat_Shell); CHKPTRQ(shell);
131cddf8d76SBarry Smith   PetscMemzero(shell,sizeof(Mat_Shell));
13220563c6bSBarry Smith   newmat->data   = (void *) shell;
13320563c6bSBarry Smith   shell->mult    = 0;
13420563c6bSBarry Smith   shell->m       = m;
13520563c6bSBarry Smith   shell->n       = n;
13620563c6bSBarry Smith   shell->ctx     = ctx;
137e51e0e81SBarry Smith   return 0;
138e51e0e81SBarry Smith }
139e51e0e81SBarry Smith 
1404b828684SBarry Smith /*@C
1410b627109SLois Curfman McInnes    MatShellSetMult - Sets the routine for computing the matrix-vector product.
142e51e0e81SBarry Smith 
143e51e0e81SBarry Smith    Input Parameters:
1440b627109SLois Curfman McInnes .  mat - the matrix associated with this operation, created
145*052efed2SBarry Smith          with MatCreateShell()
1460b627109SLois Curfman McInnes .  mult - the user-defined routine
147e51e0e81SBarry Smith 
1480b627109SLois Curfman McInnes    Calling sequence of mult:
1490b627109SLois Curfman McInnes    int mult (void *ptr,Vec xin,Vec xout)
1500b627109SLois Curfman McInnes .  ptr - the application context for matrix data
1510b627109SLois Curfman McInnes .  xin - input vector
1520b627109SLois Curfman McInnes .  xout - output vector
1530b627109SLois Curfman McInnes 
1540b627109SLois Curfman McInnes .keywords: matrix, multiply, shell, set
1550b627109SLois Curfman McInnes 
156*052efed2SBarry Smith .seealso: MatCreateShell(), MatShellSetMultTransAdd()
157e51e0e81SBarry Smith @*/
15820563c6bSBarry Smith int MatShellSetMult(Mat mat,int (*mult)(void*,Vec,Vec))
159e51e0e81SBarry Smith {
16088cf3e7dSBarry Smith   Mat_Shell *shell;
1611a941147SBarry Smith   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
16288cf3e7dSBarry Smith   shell = (Mat_Shell *) mat->data;
16320563c6bSBarry Smith   shell->mult = mult;
16420563c6bSBarry Smith   return 0;
165e51e0e81SBarry Smith }
1664b828684SBarry Smith /*@C
1670b627109SLois Curfman McInnes    MatShellSetMultTransAdd - Sets the routine for computing v3 = v2 + A' * v1.
168f0479e8cSBarry Smith 
169f0479e8cSBarry Smith    Input Parameters:
1700b627109SLois Curfman McInnes .  mat - the matrix associated with this operation, created
171*052efed2SBarry Smith          with MatCreateShell()
1720b627109SLois Curfman McInnes .  mult - the user-defined routine
173f0479e8cSBarry Smith 
1740b627109SLois Curfman McInnes    Calling sequence of mult:
1750b627109SLois Curfman McInnes    int mult (void *ptr,Vec v1,Vec v2,Vec v3)
1760b627109SLois Curfman McInnes .  ptr - the application context for matrix data
1770b627109SLois Curfman McInnes .  v1, v2 - the input vectors
1780b627109SLois Curfman McInnes .  v3 - the result
1790b627109SLois Curfman McInnes 
1800b627109SLois Curfman McInnes .keywords: matrix, multiply, transpose
1810b627109SLois Curfman McInnes 
182*052efed2SBarry Smith .seealso: MatCreateShell(), MatShellSetMult()
183f0479e8cSBarry Smith @*/
184f0479e8cSBarry Smith int MatShellSetMultTransAdd(Mat mat,int (*mult)(void*,Vec,Vec,Vec))
185f0479e8cSBarry Smith {
18688cf3e7dSBarry Smith   Mat_Shell *shell;
1871a941147SBarry Smith   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
18888cf3e7dSBarry Smith   shell               = (Mat_Shell *) mat->data;
189f0479e8cSBarry Smith   shell->multtransadd = mult;
190f0479e8cSBarry Smith   return 0;
191f0479e8cSBarry Smith }
1924b828684SBarry Smith /*@C
193b9fa9cd0SBarry Smith    MatShellSetDestroy - Set the routine to use to destroy the
194b9fa9cd0SBarry Smith         private contents of your MatShell.
195b9fa9cd0SBarry Smith 
196b9fa9cd0SBarry Smith    Input Parameters:
197b9fa9cd0SBarry Smith .  mat - the matrix associated with this operation, created
198*052efed2SBarry Smith          with MatCreateShell()
199b9fa9cd0SBarry Smith .  destroy - the user-defined routine
200b9fa9cd0SBarry Smith 
201b9fa9cd0SBarry Smith    Calling sequence of mult:
202b9fa9cd0SBarry Smith    int destroy (void *ptr)
203b9fa9cd0SBarry Smith .  ptr - the application context for matrix data
204b9fa9cd0SBarry Smith 
205b9fa9cd0SBarry Smith .keywords: matrix, destroy, shell, set
206b9fa9cd0SBarry Smith 
207*052efed2SBarry Smith .seealso: MatCreateShell()
208b9fa9cd0SBarry Smith @*/
209b9fa9cd0SBarry Smith int MatShellSetDestroy(Mat mat,int (*destroy)(void*))
210b9fa9cd0SBarry Smith {
21188cf3e7dSBarry Smith   Mat_Shell *shell;
2121a941147SBarry Smith   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
21388cf3e7dSBarry Smith   shell = (Mat_Shell *) mat->data;
214b9fa9cd0SBarry Smith   shell->destroy = destroy;
215b9fa9cd0SBarry Smith   return 0;
216b9fa9cd0SBarry Smith }
217f0479e8cSBarry Smith 
218f0479e8cSBarry Smith 
219