xref: /petsc/src/mat/impls/shell/shell.c (revision fae171e0928a68051052473fbd80ecaec6ec1e7e)
1357feee3SLois Curfman McInnes #ifndef lint
2*fae171e0SBarry Smith static char vcid[] = "$Id: shell.c,v 1.26 1996/03/19 21:26:12 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 */
17b9fa9cd0SBarry Smith   int  (*destroy)(void*);
1820563c6bSBarry Smith   void *ctx;
1988cf3e7dSBarry Smith } Mat_Shell;
20e51e0e81SBarry Smith 
21b4fd4287SBarry Smith /*@
22b4fd4287SBarry Smith     MatShellGetContext - Returns the user provided context associated
23b4fd4287SBarry Smith          with a MatShell.
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 
31b4fd4287SBarry Smith @*/
32b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx)
33b4fd4287SBarry Smith {
3477c4ece6SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
35b4fd4287SBarry Smith   if (mat->type != MATSHELL) *ctx = 0;
36b4fd4287SBarry Smith   else                       *ctx = ((Mat_Shell *) (mat->data))->ctx;
37b4fd4287SBarry Smith   return 0;
38b4fd4287SBarry Smith }
39b4fd4287SBarry Smith 
4071b459e3SLois Curfman McInnes static int MatGetSize_Shell(Mat mat,int *m,int *n)
4171b459e3SLois Curfman McInnes {
4271b459e3SLois Curfman McInnes   Mat_Shell *shell = (Mat_Shell *) mat->data;
4371b459e3SLois Curfman McInnes   *m = shell->m; *n = shell->n;
4471b459e3SLois Curfman McInnes   return 0;
4571b459e3SLois Curfman McInnes }
4671b459e3SLois Curfman McInnes 
4788cf3e7dSBarry Smith static int MatDestroy_Shell(PetscObject obj)
48e51e0e81SBarry Smith {
49b9fa9cd0SBarry Smith   int       ierr;
5020563c6bSBarry Smith   Mat       mat = (Mat) obj;
5188cf3e7dSBarry Smith   Mat_Shell *shell;
52ed3cc1f0SBarry Smith 
5388cf3e7dSBarry Smith   shell = (Mat_Shell *) mat->data;
54b9fa9cd0SBarry Smith   if (shell->destroy) {ierr = (*shell->destroy)(shell->ctx);CHKERRQ(ierr);}
550452661fSBarry Smith   PetscFree(shell);
56a5a9c739SBarry Smith   PLogObjectDestroy(mat);
570452661fSBarry Smith   PetscHeaderDestroy(mat);
58e51e0e81SBarry Smith   return 0;
59e51e0e81SBarry Smith }
60e51e0e81SBarry Smith 
6120563c6bSBarry Smith static struct _MatOps MatOps = {0,0,
6220563c6bSBarry Smith        0,
63*fae171e0SBarry Smith        0,0,0,0,
6420563c6bSBarry Smith        0,0,0,0,
6520563c6bSBarry Smith        0,0,
6620563c6bSBarry Smith        0,
6720563c6bSBarry Smith        0,
6820563c6bSBarry Smith        0,0,0,
6920563c6bSBarry Smith        0,
7020563c6bSBarry Smith        0,0,0,
7120563c6bSBarry Smith        0,0,
7220563c6bSBarry Smith        0,
7320563c6bSBarry Smith        0,0,0,0,
7471b459e3SLois Curfman McInnes        0,0,MatGetSize_Shell,
7571b459e3SLois Curfman McInnes        0,0,0,0,
7671b459e3SLois Curfman McInnes        0,0,0,0 };
77e51e0e81SBarry Smith 
784b828684SBarry Smith /*@C
79052efed2SBarry Smith    MatCreateShell - Creates a new matrix class for use with a user-defined
80ff756334SLois Curfman McInnes    private data storage format.
81e51e0e81SBarry Smith 
82e51e0e81SBarry Smith    Input Parameters:
836b5873e3SBarry Smith .  comm - MPI communicator
84ff756334SLois Curfman McInnes .  m - number of rows
85ff756334SLois Curfman McInnes .  n - number of columns
86*fae171e0SBarry Smith .  ctx - pointer to data needed by the matrix routines
87e51e0e81SBarry Smith 
88ff756334SLois Curfman McInnes    Output Parameter:
89e51e0e81SBarry Smith .  mat - the matrix
90e51e0e81SBarry Smith 
91ff756334SLois Curfman McInnes    Notes:
92ff756334SLois Curfman McInnes    The shell matrix type is intended to provide a simple class to use
93ff756334SLois Curfman McInnes    with KSP (such as, for use with matrix-free methods). You should not
94ff756334SLois Curfman McInnes    use the shell type if you plan to define a complete matrix class.
95e51e0e81SBarry Smith 
9620563c6bSBarry Smith   Usage:
97052efed2SBarry Smith $   MatCreateShell(m,n,ctx,&mat);
98*fae171e0SBarry Smith $   MatSetOperation(mat,MAT_MULT,mult);
99e51e0e81SBarry Smith 
1000b627109SLois Curfman McInnes .keywords: matrix, shell, create
1010b627109SLois Curfman McInnes 
102*fae171e0SBarry Smith .seealso: MatSetOperation(), MatHasOperation(), MatShellGetContext()
103e51e0e81SBarry Smith @*/
104052efed2SBarry Smith int MatCreateShell(MPI_Comm comm,int m,int n,void *ctx,Mat *mat)
105e51e0e81SBarry Smith {
10620563c6bSBarry Smith   Mat       newmat;
10788cf3e7dSBarry Smith   Mat_Shell *shell;
108ed3cc1f0SBarry Smith 
1090452661fSBarry Smith   PetscHeaderCreate(newmat,_Mat,MAT_COOKIE,MATSHELL,comm);
110a5a9c739SBarry Smith   PLogObjectCreate(newmat);
11120563c6bSBarry Smith   *mat              = newmat;
11220563c6bSBarry Smith   newmat->factor    = 0;
11388cf3e7dSBarry Smith   newmat->destroy   = MatDestroy_Shell;
114227d817aSBarry Smith   newmat->assembled = PETSC_TRUE;
115416022c9SBarry Smith   PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps));
116227d817aSBarry Smith 
1170452661fSBarry Smith   shell          = PetscNew(Mat_Shell); CHKPTRQ(shell);
118cddf8d76SBarry Smith   PetscMemzero(shell,sizeof(Mat_Shell));
11920563c6bSBarry Smith   newmat->data   = (void *) shell;
12020563c6bSBarry Smith   shell->m       = m;
12120563c6bSBarry Smith   shell->n       = n;
12220563c6bSBarry Smith   shell->ctx     = ctx;
123e51e0e81SBarry Smith   return 0;
124e51e0e81SBarry Smith }
125e51e0e81SBarry Smith 
126*fae171e0SBarry Smith /*@
127*fae171e0SBarry Smith     MatShellSetOperation - Allows use to set a matrix operation for a shell matrix.
128e51e0e81SBarry Smith 
129e51e0e81SBarry Smith   Input Parameters:
130*fae171e0SBarry Smith .   mat - the shell matrix
131*fae171e0SBarry Smith .   op - the name of the operation
132*fae171e0SBarry Smith .   f - the function that provides the operation.
133e51e0e81SBarry Smith 
134*fae171e0SBarry Smith   Usage:
135*fae171e0SBarry Smith    extern int mult(Mat,Vec,Vec);
136*fae171e0SBarry Smith    ierr = MatCreateShell(comm,m,m,ctx,&A);
137*fae171e0SBarry Smith    ierr = MatSetOperation(A,MAT_MULT,mult);
1380b627109SLois Curfman McInnes 
139*fae171e0SBarry Smith    In the user provided function, use MatShellGetContext() to obtain the
140*fae171e0SBarry Smith context passed into MatCreateShell().
141e51e0e81SBarry Smith @*/
142*fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op, void *f)
143e51e0e81SBarry Smith {
14477c4ece6SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
145*fae171e0SBarry Smith 
146*fae171e0SBarry Smith   if (op == MAT_DESTROY)   mat->destroy              = (int (*)(PetscObject)) f;
147*fae171e0SBarry Smith   else if (op == MAT_VIEW) mat->view                 = (int (*)(PetscObject,Viewer)) f;
148*fae171e0SBarry Smith   else                     (((void **)&mat->ops)[op])= f;
14920563c6bSBarry Smith   return 0;
150e51e0e81SBarry Smith }
151f0479e8cSBarry Smith 
152