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