xref: /petsc/src/mat/impls/shell/shell.c (revision f5eb4b8140e51d60f0c4bc35d8fe3d9a5fa43604)
1357feee3SLois Curfman McInnes #ifndef lint
2*f5eb4b81SSatish Balay static char vcid[] = "$Id: shell.c,v 1.35 1996/04/20 04:20:06 bsmith Exp balay $";
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*/
13*f5eb4b81SSatish Balay #include "src/vec/vecimpl.h"
14e51e0e81SBarry Smith 
1520563c6bSBarry Smith typedef struct {
16f39d1f56SLois Curfman McInnes   int  M, N;                  /* number of global rows, columns */
17f39d1f56SLois Curfman McInnes   int  m, n;                  /* number of local rows, columns */
183a3eedf2SBarry Smith   int  (*destroy)(Mat);
1920563c6bSBarry Smith   void *ctx;
2088cf3e7dSBarry Smith } Mat_Shell;
21e51e0e81SBarry Smith 
22b4fd4287SBarry Smith /*@
23a62d957aSLois Curfman McInnes     MatShellGetContext - Returns the user-provided context associated with a shell matrix.
24b4fd4287SBarry Smith 
25b4fd4287SBarry Smith     Input Parameter:
26b4fd4287SBarry Smith .   mat - the matrix, should have been created with MatCreateShell()
27b4fd4287SBarry Smith 
28b4fd4287SBarry Smith     Output Parameter:
29b4fd4287SBarry Smith .   ctx - the user provided context
30b4fd4287SBarry Smith 
31a62d957aSLois Curfman McInnes     Notes:
32a62d957aSLois Curfman McInnes     This routine is intended for use within various shell matrix routines,
33a62d957aSLois Curfman McInnes     as set with MatShellSetOperation().
34a62d957aSLois Curfman McInnes 
35a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context
36a62d957aSLois Curfman McInnes 
37a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellSetOperation()
38b4fd4287SBarry Smith @*/
39b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx)
40b4fd4287SBarry Smith {
4177c4ece6SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
42b4fd4287SBarry Smith   if (mat->type != MATSHELL) *ctx = 0;
43b4fd4287SBarry Smith   else                       *ctx = ((Mat_Shell *) (mat->data))->ctx;
44b4fd4287SBarry Smith   return 0;
45b4fd4287SBarry Smith }
46b4fd4287SBarry Smith 
47f39d1f56SLois Curfman McInnes static int MatGetSize_Shell(Mat mat,int *M,int *N)
4871b459e3SLois Curfman McInnes {
4971b459e3SLois Curfman McInnes   Mat_Shell *shell = (Mat_Shell *) mat->data;
50f39d1f56SLois Curfman McInnes   *M = shell->M; *N = shell->N;
51f39d1f56SLois Curfman McInnes   return 0;
52f39d1f56SLois Curfman McInnes }
53f39d1f56SLois Curfman McInnes 
54f39d1f56SLois Curfman McInnes static int MatGetLocalSize_Shell(Mat mat,int *m,int *n)
55f39d1f56SLois Curfman McInnes {
56f39d1f56SLois Curfman McInnes   Mat_Shell *shell = (Mat_Shell *) mat->data;
57f39d1f56SLois Curfman McInnes   *m = shell->n; *n = shell->n;
5871b459e3SLois Curfman McInnes   return 0;
5971b459e3SLois Curfman McInnes }
6071b459e3SLois Curfman McInnes 
6188cf3e7dSBarry Smith static int MatDestroy_Shell(PetscObject obj)
62e51e0e81SBarry Smith {
63b9fa9cd0SBarry Smith   int       ierr;
6420563c6bSBarry Smith   Mat       mat = (Mat) obj;
6588cf3e7dSBarry Smith   Mat_Shell *shell;
66ed3cc1f0SBarry Smith 
6788cf3e7dSBarry Smith   shell = (Mat_Shell *) mat->data;
683a3eedf2SBarry Smith   if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);}
690452661fSBarry Smith   PetscFree(shell);
703a3eedf2SBarry Smith   PLogObjectDestroy(mat);
713a3eedf2SBarry Smith   PetscHeaderDestroy(mat);
72e51e0e81SBarry Smith   return 0;
73e51e0e81SBarry Smith }
74e51e0e81SBarry Smith 
7520563c6bSBarry Smith static struct _MatOps MatOps = {0,0,
7620563c6bSBarry Smith        0,
77fae171e0SBarry Smith        0,0,0,0,
7820563c6bSBarry Smith        0,0,0,0,
7920563c6bSBarry Smith        0,0,
8020563c6bSBarry Smith        0,
8120563c6bSBarry Smith        0,
8220563c6bSBarry Smith        0,0,0,
8320563c6bSBarry Smith        0,
8420563c6bSBarry Smith        0,0,0,
8520563c6bSBarry Smith        0,0,
8620563c6bSBarry Smith        0,
8720563c6bSBarry Smith        0,0,0,0,
88f39d1f56SLois Curfman McInnes        0,0,MatGetSize_Shell,MatGetLocalSize_Shell,
89f39d1f56SLois Curfman McInnes        0,0,0,
9071b459e3SLois Curfman McInnes        0,0,0,0 };
91e51e0e81SBarry Smith 
924b828684SBarry Smith /*@C
93052efed2SBarry Smith    MatCreateShell - Creates a new matrix class for use with a user-defined
94ff756334SLois Curfman McInnes    private data storage format.
95e51e0e81SBarry Smith 
96e51e0e81SBarry Smith    Input Parameters:
976b5873e3SBarry Smith .  comm - MPI communicator
98f39d1f56SLois Curfman McInnes .  m - number of local rows
99f39d1f56SLois Curfman McInnes .  n - number of local columns
100f39d1f56SLois Curfman McInnes .  M - number of global rows
101f39d1f56SLois Curfman McInnes .  N - number of global columns
102deebb3c3SLois Curfman McInnes .  ctx - pointer to data needed by the shell matrix routines
103e51e0e81SBarry Smith 
104ff756334SLois Curfman McInnes    Output Parameter:
10544cd7ae7SLois Curfman McInnes .  A - the matrix
106e51e0e81SBarry Smith 
107f39d1f56SLois Curfman McInnes    Usage:
108f39d1f56SLois Curfman McInnes $    MatCreateShell(comm,m,n,M,N,ctx,&mat);
109f39d1f56SLois Curfman McInnes $    MatShellSetOperation(mat,MAT_MULT,mult);
110f39d1f56SLois Curfman McInnes $    [ Use matrix for operations that have been set ]
111f39d1f56SLois Curfman McInnes $    MatDestroy(mat);
112f39d1f56SLois Curfman McInnes 
113ff756334SLois Curfman McInnes    Notes:
114ff756334SLois Curfman McInnes    The shell matrix type is intended to provide a simple class to use
115ff756334SLois Curfman McInnes    with KSP (such as, for use with matrix-free methods). You should not
116ff756334SLois Curfman McInnes    use the shell type if you plan to define a complete matrix class.
117e51e0e81SBarry Smith 
118f39d1f56SLois Curfman McInnes    PETSc requires that matrices and vectors being used for certain
119f39d1f56SLois Curfman McInnes    operations are partitioned accordingly.  For example, when
120645985a0SLois Curfman McInnes    creating a shell matrix, A, that supports parallel matrix-vector
121645985a0SLois Curfman McInnes    products using MatMult(A,x,y) the user should set the number
122645985a0SLois Curfman McInnes    of local matrix rows to be the number of local elements of the
123645985a0SLois Curfman McInnes    corresponding result vector, y. Note that this is information is
124645985a0SLois Curfman McInnes    required for use of the matrix interface routines, even though
125645985a0SLois Curfman McInnes    the shell matrix may not actually be physically partitioned.
126645985a0SLois Curfman McInnes    For example,
127f39d1f56SLois Curfman McInnes 
128f39d1f56SLois Curfman McInnes $
129f39d1f56SLois Curfman McInnes $     Vec x, y
130645985a0SLois Curfman McInnes $     Mat A
131f39d1f56SLois Curfman McInnes $
132f39d1f56SLois Curfman McInnes $     VecCreate(comm,M,&y);
133f39d1f56SLois Curfman McInnes $     VecCreate(comm,N,&x);
134f39d1f56SLois Curfman McInnes $     VecGetLocalSize(y,&m);
135645985a0SLois Curfman McInnes $     MatCreateShell(comm,m,N,M,N,ctx,&A);
136a62d957aSLois Curfman McInnes $     MatShellSetOperation(mat,MAT_MULT,mult);
137645985a0SLois Curfman McInnes $     MatMult(A,x,y);
138645985a0SLois Curfman McInnes $     MatDestroy(A);
139f39d1f56SLois Curfman McInnes $     VecDestroy(y); VecDestroy(x);
140645985a0SLois Curfman McInnes $
141e51e0e81SBarry Smith 
1420b627109SLois Curfman McInnes .keywords: matrix, shell, create
1430b627109SLois Curfman McInnes 
1443a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext()
145e51e0e81SBarry Smith @*/
146f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A)
147e51e0e81SBarry Smith {
14844cd7ae7SLois Curfman McInnes   Mat       B;
14944cd7ae7SLois Curfman McInnes   Mat_Shell *b;
150ed3cc1f0SBarry Smith 
15144cd7ae7SLois Curfman McInnes   PetscHeaderCreate(B,_Mat,MAT_COOKIE,MATSHELL,comm);
15244cd7ae7SLois Curfman McInnes   PLogObjectCreate(B);
15344cd7ae7SLois Curfman McInnes   B->factor    = 0;
15444cd7ae7SLois Curfman McInnes   B->destroy   = MatDestroy_Shell;
15544cd7ae7SLois Curfman McInnes   B->assembled = PETSC_TRUE;
15644cd7ae7SLois Curfman McInnes   PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps));
157227d817aSBarry Smith 
15844cd7ae7SLois Curfman McInnes   b          = PetscNew(Mat_Shell); CHKPTRQ(b);
15944cd7ae7SLois Curfman McInnes   PetscMemzero(b,sizeof(Mat_Shell));
16044cd7ae7SLois Curfman McInnes   B->data   = (void *) b;
161f39d1f56SLois Curfman McInnes   b->M = M; B->M = M;
162f39d1f56SLois Curfman McInnes   b->N = N; B->N = N;
163f39d1f56SLois Curfman McInnes   b->m = m; B->m = m;
164f39d1f56SLois Curfman McInnes   b->n = n; B->n = n;
16544cd7ae7SLois Curfman McInnes   b->ctx     = ctx;
16644cd7ae7SLois Curfman McInnes   *A = B;
167e51e0e81SBarry Smith   return 0;
168e51e0e81SBarry Smith }
169e51e0e81SBarry Smith 
170fae171e0SBarry Smith /*@
1713a3eedf2SBarry Smith     MatShellSetOperation - Allows user to set a matrix operation for
1723a3eedf2SBarry Smith                            a shell matrix.
173e51e0e81SBarry Smith 
174e51e0e81SBarry Smith     Input Parameters:
175fae171e0SBarry Smith .   mat - the shell matrix
176fae171e0SBarry Smith .   op - the name of the operation
177fae171e0SBarry Smith .   f - the function that provides the operation.
178e51e0e81SBarry Smith 
179fae171e0SBarry Smith     Usage:
180a62d957aSLois Curfman McInnes $      extern int usermult(Mat,Vec,Vec);
181f39d1f56SLois Curfman McInnes $      ierr = MatCreateShell(comm,m,n,M,N,ctx,&A);
182a62d957aSLois Curfman McInnes $      ierr = MatShellSetOperation(A,MAT_MULT,usermult);
1830b627109SLois Curfman McInnes 
184a62d957aSLois Curfman McInnes     Notes:
185a62d957aSLois Curfman McInnes     See the file petsc/include/mat.h for a complete list of matrix
186a62d957aSLois Curfman McInnes     operations, which all have the form MAT_<OPERATION>, where
187a62d957aSLois Curfman McInnes     <OPERATION> is the name (in all capital letters) of the
188a62d957aSLois Curfman McInnes     user interface routine (e.g., MatMult() -> MAT_MULT).
189a62d957aSLois Curfman McInnes 
190a62d957aSLois Curfman McInnes     All user-provided functions should have the same calling
191deebb3c3SLois Curfman McInnes     sequence as the usual matrix interface routines, since they
192deebb3c3SLois Curfman McInnes     are intended to be accessed via the usual matrix interface
193deebb3c3SLois Curfman McInnes     routines, e.g.,
194a62d957aSLois Curfman McInnes $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
195a62d957aSLois Curfman McInnes 
196a62d957aSLois Curfman McInnes     Within each user-defined routine, the user should call
197a62d957aSLois Curfman McInnes     MatShellGetContext() to obtain the user-defined context that was
198a62d957aSLois Curfman McInnes     set by MatCreateShell().
199a62d957aSLois Curfman McInnes 
200a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation
201a62d957aSLois Curfman McInnes 
202a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellGetContext()
203e51e0e81SBarry Smith @*/
204fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op, void *f)
205e51e0e81SBarry Smith {
20677c4ece6SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
207fae171e0SBarry Smith 
208a62d957aSLois Curfman McInnes   if (op == MAT_DESTROY) {
209a62d957aSLois Curfman McInnes     if (mat->type == MATSHELL) {
210a62d957aSLois Curfman McInnes        Mat_Shell *shell = (Mat_Shell *) mat->data;
2113a3eedf2SBarry Smith        shell->destroy                 = (int (*)(Mat)) f;
212a62d957aSLois Curfman McInnes     }
213a62d957aSLois Curfman McInnes     else mat->destroy                 = (int (*)(PetscObject)) f;
214a62d957aSLois Curfman McInnes   }
215fae171e0SBarry Smith   else if (op == MAT_VIEW) mat->view  = (int (*)(PetscObject,Viewer)) f;
216fae171e0SBarry Smith   else      (((void**)&mat->ops)[op]) = f;
217a62d957aSLois Curfman McInnes 
21820563c6bSBarry Smith   return 0;
219e51e0e81SBarry Smith }
220f0479e8cSBarry Smith 
2213a3eedf2SBarry Smith 
2223a3eedf2SBarry Smith 
2233a3eedf2SBarry Smith 
2243a3eedf2SBarry Smith 
2253a3eedf2SBarry Smith 
226