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