xref: /petsc/src/mat/impls/shell/shell.c (revision 3a3eedf2169b507b1efbdb3dd065481a2d2f2a88)
1357feee3SLois Curfman McInnes #ifndef lint
2*3a3eedf2SBarry Smith static char vcid[] = "$Id: shell.c,v 1.29 1996/03/28 22:51:51 curfman 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 */
17*3a3eedf2SBarry Smith   int  (*destroy)(Mat);
1820563c6bSBarry Smith   void *ctx;
1988cf3e7dSBarry Smith } Mat_Shell;
20e51e0e81SBarry Smith 
21b4fd4287SBarry Smith /*@
22a62d957aSLois Curfman McInnes     MatShellGetContext - Returns the user-provided context associated with a shell matrix.
23b4fd4287SBarry Smith 
24b4fd4287SBarry Smith     Input Parameter:
25b4fd4287SBarry Smith .   mat - the matrix, should have been created with MatCreateShell()
26b4fd4287SBarry Smith 
27b4fd4287SBarry Smith     Output Parameter:
28b4fd4287SBarry Smith .   ctx - the user provided context
29b4fd4287SBarry Smith 
30a62d957aSLois Curfman McInnes     Notes:
31a62d957aSLois Curfman McInnes     This routine is intended for use within various shell matrix routines,
32a62d957aSLois Curfman McInnes     as set with MatShellSetOperation().
33a62d957aSLois Curfman McInnes 
34a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context
35a62d957aSLois Curfman McInnes 
36a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellSetOperation()
37b4fd4287SBarry Smith @*/
38b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx)
39b4fd4287SBarry Smith {
4077c4ece6SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
41b4fd4287SBarry Smith   if (mat->type != MATSHELL) *ctx = 0;
42b4fd4287SBarry Smith   else                       *ctx = ((Mat_Shell *) (mat->data))->ctx;
43b4fd4287SBarry Smith   return 0;
44b4fd4287SBarry Smith }
45b4fd4287SBarry Smith 
4671b459e3SLois Curfman McInnes static int MatGetSize_Shell(Mat mat,int *m,int *n)
4771b459e3SLois Curfman McInnes {
4871b459e3SLois Curfman McInnes   Mat_Shell *shell = (Mat_Shell *) mat->data;
4971b459e3SLois Curfman McInnes   *m = shell->m; *n = shell->n;
5071b459e3SLois Curfman McInnes   return 0;
5171b459e3SLois Curfman McInnes }
5271b459e3SLois Curfman McInnes 
5388cf3e7dSBarry Smith static int MatDestroy_Shell(PetscObject obj)
54e51e0e81SBarry Smith {
55b9fa9cd0SBarry Smith   int       ierr;
5620563c6bSBarry Smith   Mat       mat = (Mat) obj;
5788cf3e7dSBarry Smith   Mat_Shell *shell;
58ed3cc1f0SBarry Smith 
5988cf3e7dSBarry Smith   shell = (Mat_Shell *) mat->data;
60*3a3eedf2SBarry Smith   if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);}
610452661fSBarry Smith   PetscFree(shell);
62*3a3eedf2SBarry Smith   PLogObjectDestroy(mat);
63*3a3eedf2SBarry Smith   PetscHeaderDestroy(mat);
64e51e0e81SBarry Smith   return 0;
65e51e0e81SBarry Smith }
66e51e0e81SBarry Smith 
6720563c6bSBarry Smith static struct _MatOps MatOps = {0,0,
6820563c6bSBarry Smith        0,
69fae171e0SBarry Smith        0,0,0,0,
7020563c6bSBarry Smith        0,0,0,0,
7120563c6bSBarry Smith        0,0,
7220563c6bSBarry Smith        0,
7320563c6bSBarry Smith        0,
7420563c6bSBarry Smith        0,0,0,
7520563c6bSBarry Smith        0,
7620563c6bSBarry Smith        0,0,0,
7720563c6bSBarry Smith        0,0,
7820563c6bSBarry Smith        0,
7920563c6bSBarry Smith        0,0,0,0,
8071b459e3SLois Curfman McInnes        0,0,MatGetSize_Shell,
8171b459e3SLois Curfman McInnes        0,0,0,0,
8271b459e3SLois Curfman McInnes        0,0,0,0 };
83e51e0e81SBarry Smith 
844b828684SBarry Smith /*@C
85052efed2SBarry Smith    MatCreateShell - Creates a new matrix class for use with a user-defined
86ff756334SLois Curfman McInnes    private data storage format.
87e51e0e81SBarry Smith 
88e51e0e81SBarry Smith    Input Parameters:
896b5873e3SBarry Smith .  comm - MPI communicator
90ff756334SLois Curfman McInnes .  m - number of rows
91ff756334SLois Curfman McInnes .  n - number of columns
92fae171e0SBarry Smith .  ctx - pointer to data needed by the matrix routines
93e51e0e81SBarry Smith 
94ff756334SLois Curfman McInnes    Output Parameter:
95e51e0e81SBarry Smith .  mat - the matrix
96e51e0e81SBarry Smith 
97ff756334SLois Curfman McInnes    Notes:
98ff756334SLois Curfman McInnes    The shell matrix type is intended to provide a simple class to use
99ff756334SLois Curfman McInnes    with KSP (such as, for use with matrix-free methods). You should not
100ff756334SLois Curfman McInnes    use the shell type if you plan to define a complete matrix class.
101e51e0e81SBarry Smith 
10220563c6bSBarry Smith    Usage:
103052efed2SBarry Smith $   MatCreateShell(m,n,ctx,&mat);
104a62d957aSLois Curfman McInnes $   MatShellSetOperation(mat,MAT_MULT,mult);
105a62d957aSLois Curfman McInnes $   [ Use matrix for operations that have been set ]
106a62d957aSLois Curfman McInnes $   MatDestroy(mat);
107e51e0e81SBarry Smith 
1080b627109SLois Curfman McInnes .keywords: matrix, shell, create
1090b627109SLois Curfman McInnes 
110*3a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext()
111e51e0e81SBarry Smith @*/
112052efed2SBarry Smith int MatCreateShell(MPI_Comm comm,int m,int n,void *ctx,Mat *mat)
113e51e0e81SBarry Smith {
11420563c6bSBarry Smith   Mat       newmat;
11588cf3e7dSBarry Smith   Mat_Shell *shell;
116ed3cc1f0SBarry Smith 
1170452661fSBarry Smith   PetscHeaderCreate(newmat,_Mat,MAT_COOKIE,MATSHELL,comm);
118a5a9c739SBarry Smith   PLogObjectCreate(newmat);
11920563c6bSBarry Smith   *mat              = newmat;
12020563c6bSBarry Smith   newmat->factor    = 0;
12188cf3e7dSBarry Smith   newmat->destroy   = MatDestroy_Shell;
122227d817aSBarry Smith   newmat->assembled = PETSC_TRUE;
123416022c9SBarry Smith   PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps));
124227d817aSBarry Smith 
1250452661fSBarry Smith   shell          = PetscNew(Mat_Shell); CHKPTRQ(shell);
126cddf8d76SBarry Smith   PetscMemzero(shell,sizeof(Mat_Shell));
12720563c6bSBarry Smith   newmat->data   = (void *) shell;
12820563c6bSBarry Smith   shell->m       = m;
12920563c6bSBarry Smith   shell->n       = n;
13020563c6bSBarry Smith   shell->ctx     = ctx;
131e51e0e81SBarry Smith   return 0;
132e51e0e81SBarry Smith }
133e51e0e81SBarry Smith 
134fae171e0SBarry Smith /*@
135*3a3eedf2SBarry Smith     MatShellSetOperation - Allows user to set a matrix operation for
136*3a3eedf2SBarry Smith                            a shell matrix.
137e51e0e81SBarry Smith 
138e51e0e81SBarry Smith     Input Parameters:
139fae171e0SBarry Smith .   mat - the shell matrix
140fae171e0SBarry Smith .   op - the name of the operation
141fae171e0SBarry Smith .   f - the function that provides the operation.
142e51e0e81SBarry Smith 
143fae171e0SBarry Smith     Usage:
144a62d957aSLois Curfman McInnes $      extern int usermult(Mat,Vec,Vec);
145a62d957aSLois Curfman McInnes $      ierr = MatCreateShell(comm,m,m,ctx,&A);
146a62d957aSLois Curfman McInnes $      ierr = MatShellSetOperation(A,MAT_MULT,usermult);
1470b627109SLois Curfman McInnes 
148a62d957aSLois Curfman McInnes     Notes:
149a62d957aSLois Curfman McInnes     See the file petsc/include/mat.h for a complete list of matrix
150a62d957aSLois Curfman McInnes     operations, which all have the form MAT_<OPERATION>, where
151a62d957aSLois Curfman McInnes     <OPERATION> is the name (in all capital letters) of the
152a62d957aSLois Curfman McInnes     user interface routine (e.g., MatMult() -> MAT_MULT).
153a62d957aSLois Curfman McInnes 
154a62d957aSLois Curfman McInnes     All user-provided functions should have the same calling
155a62d957aSLois Curfman McInnes     sequence as the usual matrix interface routines, e.g.,
156a62d957aSLois Curfman McInnes $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
157a62d957aSLois Curfman McInnes     since they are intended to be accessed via the usual
158a62d957aSLois Curfman McInnes     matrix interface routines.
159a62d957aSLois Curfman McInnes 
160a62d957aSLois Curfman McInnes     Within each user-defined routine, the user should call
161a62d957aSLois Curfman McInnes     MatShellGetContext() to obtain the user-defined context that was
162a62d957aSLois Curfman McInnes     set by MatCreateShell().
163a62d957aSLois Curfman McInnes 
164a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation
165a62d957aSLois Curfman McInnes 
166a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellGetContext()
167e51e0e81SBarry Smith @*/
168fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op, void *f)
169e51e0e81SBarry Smith {
17077c4ece6SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
171fae171e0SBarry Smith 
172a62d957aSLois Curfman McInnes   if (op == MAT_DESTROY) {
173a62d957aSLois Curfman McInnes     if (mat->type == MATSHELL) {
174a62d957aSLois Curfman McInnes        Mat_Shell *shell = (Mat_Shell *) mat->data;
175*3a3eedf2SBarry Smith        shell->destroy                                 = (int (*)(Mat)) f;
176a62d957aSLois Curfman McInnes     }
177a62d957aSLois Curfman McInnes     else mat->destroy                                 = (int (*)(PetscObject)) f;
178a62d957aSLois Curfman McInnes   }
179fae171e0SBarry Smith   else if (op == MAT_VIEW) mat->view                  = (int (*)(PetscObject,Viewer)) f;
180fae171e0SBarry Smith   else                     (((void **)&mat->ops)[op]) = f;
181a62d957aSLois Curfman McInnes 
18220563c6bSBarry Smith   return 0;
183e51e0e81SBarry Smith }
184f0479e8cSBarry Smith 
185*3a3eedf2SBarry Smith 
186*3a3eedf2SBarry Smith 
187*3a3eedf2SBarry Smith 
188*3a3eedf2SBarry Smith 
189*3a3eedf2SBarry Smith 
190