xref: /petsc/src/mat/impls/shell/shell.c (revision a62d957ae685a2070aaf3345f4f6f1b8f7cef2e2)
1357feee3SLois Curfman McInnes #ifndef lint
2*a62d957aSLois Curfman McInnes static char vcid[] = "$Id: shell.c,v 1.28 1996/03/28 22:00:13 curfman Exp curfman $";
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 */
17b9fa9cd0SBarry Smith   int  (*destroy)(void*);
1820563c6bSBarry Smith   void *ctx;
1988cf3e7dSBarry Smith } Mat_Shell;
20e51e0e81SBarry Smith 
21b4fd4287SBarry Smith /*@
22*a62d957aSLois 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 
30*a62d957aSLois Curfman McInnes     Notes:
31*a62d957aSLois Curfman McInnes     This routine is intended for use within various shell matrix routines,
32*a62d957aSLois Curfman McInnes     as set with MatShellSetOperation().
33*a62d957aSLois Curfman McInnes 
34*a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context
35*a62d957aSLois Curfman McInnes 
36*a62d957aSLois 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*a62d957aSLois Curfman McInnes   if (shell->destroy) {ierr = (*shell->destroy)(obj);CHKERRQ(ierr);}
610452661fSBarry Smith   PetscFree(shell);
62e51e0e81SBarry Smith   return 0;
63e51e0e81SBarry Smith }
64e51e0e81SBarry Smith 
6520563c6bSBarry Smith static struct _MatOps MatOps = {0,0,
6620563c6bSBarry Smith        0,
67fae171e0SBarry Smith        0,0,0,0,
6820563c6bSBarry Smith        0,0,0,0,
6920563c6bSBarry Smith        0,0,
7020563c6bSBarry Smith        0,
7120563c6bSBarry Smith        0,
7220563c6bSBarry Smith        0,0,0,
7320563c6bSBarry Smith        0,
7420563c6bSBarry Smith        0,0,0,
7520563c6bSBarry Smith        0,0,
7620563c6bSBarry Smith        0,
7720563c6bSBarry Smith        0,0,0,0,
7871b459e3SLois Curfman McInnes        0,0,MatGetSize_Shell,
7971b459e3SLois Curfman McInnes        0,0,0,0,
8071b459e3SLois Curfman McInnes        0,0,0,0 };
81e51e0e81SBarry Smith 
824b828684SBarry Smith /*@C
83052efed2SBarry Smith    MatCreateShell - Creates a new matrix class for use with a user-defined
84ff756334SLois Curfman McInnes    private data storage format.
85e51e0e81SBarry Smith 
86e51e0e81SBarry Smith    Input Parameters:
876b5873e3SBarry Smith .  comm - MPI communicator
88ff756334SLois Curfman McInnes .  m - number of rows
89ff756334SLois Curfman McInnes .  n - number of columns
90fae171e0SBarry Smith .  ctx - pointer to data needed by the matrix routines
91e51e0e81SBarry Smith 
92ff756334SLois Curfman McInnes    Output Parameter:
93e51e0e81SBarry Smith .  mat - the matrix
94e51e0e81SBarry Smith 
95ff756334SLois Curfman McInnes    Notes:
96ff756334SLois Curfman McInnes    The shell matrix type is intended to provide a simple class to use
97ff756334SLois Curfman McInnes    with KSP (such as, for use with matrix-free methods). You should not
98ff756334SLois Curfman McInnes    use the shell type if you plan to define a complete matrix class.
99e51e0e81SBarry Smith 
10020563c6bSBarry Smith    Usage:
101052efed2SBarry Smith $   MatCreateShell(m,n,ctx,&mat);
102*a62d957aSLois Curfman McInnes $   MatShellSetOperation(mat,MAT_MULT,mult);
103*a62d957aSLois Curfman McInnes $   [ Use matrix for operations that have been set ]
104*a62d957aSLois Curfman McInnes $   MatDestroy(mat);
105e51e0e81SBarry Smith 
1060b627109SLois Curfman McInnes .keywords: matrix, shell, create
1070b627109SLois Curfman McInnes 
108fae171e0SBarry Smith .seealso: MatSetOperation(), MatHasOperation(), MatShellGetContext()
109e51e0e81SBarry Smith @*/
110052efed2SBarry Smith int MatCreateShell(MPI_Comm comm,int m,int n,void *ctx,Mat *mat)
111e51e0e81SBarry Smith {
11220563c6bSBarry Smith   Mat       newmat;
11388cf3e7dSBarry Smith   Mat_Shell *shell;
114ed3cc1f0SBarry Smith 
1150452661fSBarry Smith   PetscHeaderCreate(newmat,_Mat,MAT_COOKIE,MATSHELL,comm);
116a5a9c739SBarry Smith   PLogObjectCreate(newmat);
11720563c6bSBarry Smith   *mat              = newmat;
11820563c6bSBarry Smith   newmat->factor    = 0;
11988cf3e7dSBarry Smith   newmat->destroy   = MatDestroy_Shell;
120227d817aSBarry Smith   newmat->assembled = PETSC_TRUE;
121416022c9SBarry Smith   PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps));
122227d817aSBarry Smith 
1230452661fSBarry Smith   shell          = PetscNew(Mat_Shell); CHKPTRQ(shell);
124cddf8d76SBarry Smith   PetscMemzero(shell,sizeof(Mat_Shell));
12520563c6bSBarry Smith   newmat->data   = (void *) shell;
12620563c6bSBarry Smith   shell->m       = m;
12720563c6bSBarry Smith   shell->n       = n;
12820563c6bSBarry Smith   shell->ctx     = ctx;
129e51e0e81SBarry Smith   return 0;
130e51e0e81SBarry Smith }
131e51e0e81SBarry Smith 
132fae171e0SBarry Smith /*@
133*a62d957aSLois Curfman McInnes     MatShellSetOperation - Allows user to set a matrix operation for a shell matrix.
134e51e0e81SBarry Smith 
135e51e0e81SBarry Smith     Input Parameters:
136fae171e0SBarry Smith .   mat - the shell matrix
137fae171e0SBarry Smith .   op - the name of the operation
138fae171e0SBarry Smith .   f - the function that provides the operation.
139e51e0e81SBarry Smith 
140fae171e0SBarry Smith     Usage:
141*a62d957aSLois Curfman McInnes $      extern int usermult(Mat,Vec,Vec);
142*a62d957aSLois Curfman McInnes $      ierr = MatCreateShell(comm,m,m,ctx,&A);
143*a62d957aSLois Curfman McInnes $      ierr = MatShellSetOperation(A,MAT_MULT,usermult);
1440b627109SLois Curfman McInnes 
145*a62d957aSLois Curfman McInnes     Notes:
146*a62d957aSLois Curfman McInnes     See the file petsc/include/mat.h for a complete list of matrix
147*a62d957aSLois Curfman McInnes     operations, which all have the form MAT_<OPERATION>, where
148*a62d957aSLois Curfman McInnes     <OPERATION> is the name (in all capital letters) of the
149*a62d957aSLois Curfman McInnes     user interface routine (e.g., MatMult() -> MAT_MULT).
150*a62d957aSLois Curfman McInnes 
151*a62d957aSLois Curfman McInnes     All user-provided functions should have the same calling
152*a62d957aSLois Curfman McInnes     sequence as the usual matrix interface routines, e.g.,
153*a62d957aSLois Curfman McInnes $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
154*a62d957aSLois Curfman McInnes     since they are intended to be accessed via the usual
155*a62d957aSLois Curfman McInnes     matrix interface routines.
156*a62d957aSLois Curfman McInnes 
157*a62d957aSLois Curfman McInnes     Within each user-defined routine, the user should call
158*a62d957aSLois Curfman McInnes     MatShellGetContext() to obtain the user-defined context that was
159*a62d957aSLois Curfman McInnes     set by MatCreateShell().
160*a62d957aSLois Curfman McInnes 
161*a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation
162*a62d957aSLois Curfman McInnes 
163*a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellGetContext()
164e51e0e81SBarry Smith @*/
165fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op, void *f)
166e51e0e81SBarry Smith {
16777c4ece6SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
168fae171e0SBarry Smith 
169*a62d957aSLois Curfman McInnes   if (op == MAT_DESTROY) {
170*a62d957aSLois Curfman McInnes     if (mat->type == MATSHELL) {
171*a62d957aSLois Curfman McInnes        Mat_Shell *shell = (Mat_Shell *) mat->data;
172*a62d957aSLois Curfman McInnes        shell->destroy                                 = (int (*)(void*)) f;
173*a62d957aSLois Curfman McInnes     }
174*a62d957aSLois Curfman McInnes     else mat->destroy                                 = (int (*)(PetscObject)) f;
175*a62d957aSLois Curfman McInnes   }
176fae171e0SBarry Smith   else if (op == MAT_VIEW) mat->view                  = (int (*)(PetscObject,Viewer)) f;
177fae171e0SBarry Smith   else                     (((void **)&mat->ops)[op]) = f;
178*a62d957aSLois Curfman McInnes 
17920563c6bSBarry Smith   return 0;
180e51e0e81SBarry Smith }
181f0479e8cSBarry Smith 
182