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