xref: /petsc/src/mat/impls/shell/shell.c (revision 227d817a37c50a73d88aa8c031007e5b1fb2e4ec)
1357feee3SLois Curfman McInnes #ifndef lint
2*227d817aSBarry Smith static char vcid[] = "$Id: shell.c,v 1.24 1996/01/23 00:18:55 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;
53*227d817aSBarry Smith   if (!shell->mult) SETERRQ(1,"MatMult_Shell:You have not provided a multiply for\
54*227d817aSBarry Smith  your shell matrix");
5520563c6bSBarry Smith   return (*shell->mult)(shell->ctx,x,y);
56e51e0e81SBarry Smith }
5771b459e3SLois Curfman McInnes 
5888cf3e7dSBarry Smith static int MatMultTransAdd_Shell(Mat mat,Vec x,Vec y,Vec z)
59f0479e8cSBarry Smith {
6071b459e3SLois Curfman McInnes   Mat_Shell *shell = (Mat_Shell *) mat->data;
61f0479e8cSBarry Smith   return (*shell->multtransadd)(shell->ctx,x,y,z);
62f0479e8cSBarry Smith }
6371b459e3SLois Curfman McInnes 
6488cf3e7dSBarry Smith static int MatDestroy_Shell(PetscObject obj)
65e51e0e81SBarry Smith {
66b9fa9cd0SBarry Smith   int       ierr;
6720563c6bSBarry Smith   Mat       mat = (Mat) obj;
6888cf3e7dSBarry Smith   Mat_Shell *shell;
69ed3cc1f0SBarry Smith 
7088cf3e7dSBarry Smith   shell = (Mat_Shell *) mat->data;
71b9fa9cd0SBarry Smith   if (shell->destroy) {ierr = (*shell->destroy)(shell->ctx);CHKERRQ(ierr);}
720452661fSBarry Smith   PetscFree(shell);
73a5a9c739SBarry Smith   PLogObjectDestroy(mat);
740452661fSBarry Smith   PetscHeaderDestroy(mat);
75e51e0e81SBarry Smith   return 0;
76e51e0e81SBarry Smith }
77e51e0e81SBarry Smith 
7820563c6bSBarry Smith static struct _MatOps MatOps = {0,0,
7920563c6bSBarry Smith        0,
8088cf3e7dSBarry Smith        MatMult_Shell,0,0,MatMultTransAdd_Shell,
8120563c6bSBarry Smith        0,0,0,0,
8220563c6bSBarry Smith        0,0,
8320563c6bSBarry Smith        0,
8420563c6bSBarry Smith        0,
8520563c6bSBarry Smith        0,0,0,
8620563c6bSBarry Smith        0,
8720563c6bSBarry Smith        0,0,0,
8820563c6bSBarry Smith        0,0,
8920563c6bSBarry Smith        0,
9020563c6bSBarry Smith        0,0,0,0,
9171b459e3SLois Curfman McInnes        0,0,MatGetSize_Shell,
9271b459e3SLois Curfman McInnes        0,0,0,0,
9371b459e3SLois Curfman McInnes        0,0,0,0 };
94e51e0e81SBarry Smith 
954b828684SBarry Smith /*@C
96052efed2SBarry Smith    MatCreateShell - Creates a new matrix class for use with a user-defined
97ff756334SLois Curfman McInnes    private data storage format.
98e51e0e81SBarry Smith 
99e51e0e81SBarry Smith    Input Parameters:
1006b5873e3SBarry Smith .  comm - MPI communicator
101ff756334SLois Curfman McInnes .  m - number of rows
102ff756334SLois Curfman McInnes .  n - number of columns
1030b627109SLois Curfman McInnes .  ctx - pointer to data needed by matrix-vector multiplication routine(s)
104e51e0e81SBarry Smith 
105ff756334SLois Curfman McInnes    Output Parameter:
106e51e0e81SBarry Smith .  mat - the matrix
107e51e0e81SBarry Smith 
108ff756334SLois Curfman McInnes    Notes:
109ff756334SLois Curfman McInnes    The shell matrix type is intended to provide a simple class to use
110ff756334SLois Curfman McInnes    with KSP (such as, for use with matrix-free methods). You should not
111ff756334SLois Curfman McInnes    use the shell type if you plan to define a complete matrix class.
112e51e0e81SBarry Smith 
11320563c6bSBarry Smith   Usage:
114052efed2SBarry Smith $   MatCreateShell(m,n,ctx,&mat);
115ff756334SLois Curfman McInnes $   MatShellSetMult(mat,mult);
116e51e0e81SBarry Smith 
1170b627109SLois Curfman McInnes .keywords: matrix, shell, create
1180b627109SLois Curfman McInnes 
1190b627109SLois Curfman McInnes .seealso: MatShellSetMult(), MatShellSetMultTransAdd()
120e51e0e81SBarry Smith @*/
121052efed2SBarry Smith int MatCreateShell(MPI_Comm comm,int m,int n,void *ctx,Mat *mat)
122e51e0e81SBarry Smith {
12320563c6bSBarry Smith   Mat       newmat;
12488cf3e7dSBarry Smith   Mat_Shell *shell;
125ed3cc1f0SBarry Smith 
1260452661fSBarry Smith   PetscHeaderCreate(newmat,_Mat,MAT_COOKIE,MATSHELL,comm);
127a5a9c739SBarry Smith   PLogObjectCreate(newmat);
12820563c6bSBarry Smith   *mat              = newmat;
12920563c6bSBarry Smith   newmat->factor    = 0;
13088cf3e7dSBarry Smith   newmat->destroy   = MatDestroy_Shell;
131*227d817aSBarry Smith   newmat->assembled = PETSC_TRUE;
132416022c9SBarry Smith   PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps));
133*227d817aSBarry Smith 
1340452661fSBarry Smith   shell          = PetscNew(Mat_Shell); CHKPTRQ(shell);
135cddf8d76SBarry Smith   PetscMemzero(shell,sizeof(Mat_Shell));
13620563c6bSBarry Smith   newmat->data   = (void *) shell;
13720563c6bSBarry Smith   shell->mult    = 0;
13820563c6bSBarry Smith   shell->m       = m;
13920563c6bSBarry Smith   shell->n       = n;
14020563c6bSBarry Smith   shell->ctx     = ctx;
141e51e0e81SBarry Smith   return 0;
142e51e0e81SBarry Smith }
143e51e0e81SBarry Smith 
1444b828684SBarry Smith /*@C
1450b627109SLois Curfman McInnes    MatShellSetMult - Sets the routine for computing the matrix-vector product.
146e51e0e81SBarry Smith 
147e51e0e81SBarry Smith    Input Parameters:
1480b627109SLois Curfman McInnes .  mat - the matrix associated with this operation, created
149052efed2SBarry Smith          with MatCreateShell()
1500b627109SLois Curfman McInnes .  mult - the user-defined routine
151e51e0e81SBarry Smith 
1520b627109SLois Curfman McInnes    Calling sequence of mult:
1530b627109SLois Curfman McInnes    int mult (void *ptr,Vec xin,Vec xout)
1540b627109SLois Curfman McInnes .  ptr - the application context for matrix data
1550b627109SLois Curfman McInnes .  xin - input vector
1560b627109SLois Curfman McInnes .  xout - output vector
1570b627109SLois Curfman McInnes 
1580b627109SLois Curfman McInnes .keywords: matrix, multiply, shell, set
1590b627109SLois Curfman McInnes 
160052efed2SBarry Smith .seealso: MatCreateShell(), MatShellSetMultTransAdd()
161e51e0e81SBarry Smith @*/
16220563c6bSBarry Smith int MatShellSetMult(Mat mat,int (*mult)(void*,Vec,Vec))
163e51e0e81SBarry Smith {
16488cf3e7dSBarry Smith   Mat_Shell *shell;
1651a941147SBarry Smith   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
16688cf3e7dSBarry Smith   shell = (Mat_Shell *) mat->data;
16720563c6bSBarry Smith   shell->mult = mult;
16820563c6bSBarry Smith   return 0;
169e51e0e81SBarry Smith }
1704b828684SBarry Smith /*@C
1710b627109SLois Curfman McInnes    MatShellSetMultTransAdd - Sets the routine for computing v3 = v2 + A' * v1.
172f0479e8cSBarry Smith 
173f0479e8cSBarry Smith    Input Parameters:
1740b627109SLois Curfman McInnes .  mat - the matrix associated with this operation, created
175052efed2SBarry Smith          with MatCreateShell()
1760b627109SLois Curfman McInnes .  mult - the user-defined routine
177f0479e8cSBarry Smith 
1780b627109SLois Curfman McInnes    Calling sequence of mult:
1790b627109SLois Curfman McInnes    int mult (void *ptr,Vec v1,Vec v2,Vec v3)
1800b627109SLois Curfman McInnes .  ptr - the application context for matrix data
1810b627109SLois Curfman McInnes .  v1, v2 - the input vectors
1820b627109SLois Curfman McInnes .  v3 - the result
1830b627109SLois Curfman McInnes 
1840b627109SLois Curfman McInnes .keywords: matrix, multiply, transpose
1850b627109SLois Curfman McInnes 
186052efed2SBarry Smith .seealso: MatCreateShell(), MatShellSetMult()
187f0479e8cSBarry Smith @*/
188f0479e8cSBarry Smith int MatShellSetMultTransAdd(Mat mat,int (*mult)(void*,Vec,Vec,Vec))
189f0479e8cSBarry Smith {
19088cf3e7dSBarry Smith   Mat_Shell *shell;
1911a941147SBarry Smith   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
19288cf3e7dSBarry Smith   shell               = (Mat_Shell *) mat->data;
193f0479e8cSBarry Smith   shell->multtransadd = mult;
194f0479e8cSBarry Smith   return 0;
195f0479e8cSBarry Smith }
1964b828684SBarry Smith /*@C
197b9fa9cd0SBarry Smith    MatShellSetDestroy - Set the routine to use to destroy the
198b9fa9cd0SBarry Smith         private contents of your MatShell.
199b9fa9cd0SBarry Smith 
200b9fa9cd0SBarry Smith    Input Parameters:
201b9fa9cd0SBarry Smith .  mat - the matrix associated with this operation, created
202052efed2SBarry Smith          with MatCreateShell()
203b9fa9cd0SBarry Smith .  destroy - the user-defined routine
204b9fa9cd0SBarry Smith 
205b9fa9cd0SBarry Smith    Calling sequence of mult:
206b9fa9cd0SBarry Smith    int destroy (void *ptr)
207b9fa9cd0SBarry Smith .  ptr - the application context for matrix data
208b9fa9cd0SBarry Smith 
209b9fa9cd0SBarry Smith .keywords: matrix, destroy, shell, set
210b9fa9cd0SBarry Smith 
211052efed2SBarry Smith .seealso: MatCreateShell()
212b9fa9cd0SBarry Smith @*/
213b9fa9cd0SBarry Smith int MatShellSetDestroy(Mat mat,int (*destroy)(void*))
214b9fa9cd0SBarry Smith {
21588cf3e7dSBarry Smith   Mat_Shell *shell;
2161a941147SBarry Smith   PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE);
21788cf3e7dSBarry Smith   shell = (Mat_Shell *) mat->data;
218b9fa9cd0SBarry Smith   shell->destroy = destroy;
219b9fa9cd0SBarry Smith   return 0;
220b9fa9cd0SBarry Smith }
221f0479e8cSBarry Smith 
222f0479e8cSBarry Smith 
223