1357feee3SLois Curfman McInnes #ifndef lint 2*416022c9SBarry Smith static char vcid[] = "$Id: shell.c,v 1.18 1995/09/21 20:10:33 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 820563c6bSBarry Smith mush 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 */ 1720563c6bSBarry Smith int (*mult)(void*,Vec,Vec); 18f0479e8cSBarry Smith int (*multtransadd)(void*,Vec,Vec,Vec); 19b9fa9cd0SBarry Smith int (*destroy)(void*); 2071b459e3SLois Curfman McInnes int (*getsize)(void*,int*,int*); 2120563c6bSBarry Smith void *ctx; 2288cf3e7dSBarry Smith } Mat_Shell; 23e51e0e81SBarry Smith 2471b459e3SLois Curfman McInnes static int MatGetSize_Shell(Mat mat,int *m,int *n) 2571b459e3SLois Curfman McInnes { 2671b459e3SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 2771b459e3SLois Curfman McInnes *m = shell->m; *n = shell->n; 2871b459e3SLois Curfman McInnes return 0; 2971b459e3SLois Curfman McInnes } 3071b459e3SLois Curfman McInnes 3188cf3e7dSBarry Smith static int MatMult_Shell(Mat mat,Vec x,Vec y) 32e51e0e81SBarry Smith { 3371b459e3SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 3420563c6bSBarry Smith return (*shell->mult)(shell->ctx,x,y); 35e51e0e81SBarry Smith } 3671b459e3SLois Curfman McInnes 3788cf3e7dSBarry Smith static int MatMultTransAdd_Shell(Mat mat,Vec x,Vec y,Vec z) 38f0479e8cSBarry Smith { 3971b459e3SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 40f0479e8cSBarry Smith return (*shell->multtransadd)(shell->ctx,x,y,z); 41f0479e8cSBarry Smith } 4271b459e3SLois Curfman McInnes 4388cf3e7dSBarry Smith static int MatDestroy_Shell(PetscObject obj) 44e51e0e81SBarry Smith { 45b9fa9cd0SBarry Smith int ierr; 4620563c6bSBarry Smith Mat mat = (Mat) obj; 4788cf3e7dSBarry Smith Mat_Shell *shell; 4888cf3e7dSBarry Smith shell = (Mat_Shell *) mat->data; 49b9fa9cd0SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(shell->ctx);CHKERRQ(ierr);} 5078b31e54SBarry Smith PETSCFREE(shell); 51a5a9c739SBarry Smith PLogObjectDestroy(mat); 529e25ed09SBarry Smith PETSCHEADERDESTROY(mat); 53e51e0e81SBarry Smith return 0; 54e51e0e81SBarry Smith } 55e51e0e81SBarry Smith 5620563c6bSBarry Smith static struct _MatOps MatOps = {0,0, 5720563c6bSBarry Smith 0, 5888cf3e7dSBarry Smith MatMult_Shell,0,0,MatMultTransAdd_Shell, 5920563c6bSBarry Smith 0,0,0,0, 6020563c6bSBarry Smith 0,0, 6120563c6bSBarry Smith 0, 6220563c6bSBarry Smith 0, 6320563c6bSBarry Smith 0,0,0, 6420563c6bSBarry Smith 0, 6520563c6bSBarry Smith 0,0,0, 6620563c6bSBarry Smith 0,0, 6720563c6bSBarry Smith 0, 6820563c6bSBarry Smith 0,0,0,0, 6971b459e3SLois Curfman McInnes 0,0,MatGetSize_Shell, 7071b459e3SLois Curfman McInnes 0,0,0,0, 7171b459e3SLois Curfman McInnes 0,0,0,0 }; 72e51e0e81SBarry Smith 734b828684SBarry Smith /*@C 74c01c455dSBarry Smith MatShellCreate - Creates a new matrix class for use with a user-defined 75ff756334SLois Curfman McInnes private data storage format. 76e51e0e81SBarry Smith 77e51e0e81SBarry Smith Input Parameters: 786b5873e3SBarry Smith . comm - MPI communicator 79ff756334SLois Curfman McInnes . m - number of rows 80ff756334SLois Curfman McInnes . n - number of columns 810b627109SLois Curfman McInnes . ctx - pointer to data needed by matrix-vector multiplication routine(s) 82e51e0e81SBarry Smith 83ff756334SLois Curfman McInnes Output Parameter: 84e51e0e81SBarry Smith . mat - the matrix 85e51e0e81SBarry Smith 86ff756334SLois Curfman McInnes Notes: 87ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 88ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 89ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 90e51e0e81SBarry Smith 9120563c6bSBarry Smith Usage: 92ff756334SLois Curfman McInnes $ MatShellCreate(m,n,ctx,&mat); 93ff756334SLois Curfman McInnes $ MatShellSetMult(mat,mult); 94e51e0e81SBarry Smith 950b627109SLois Curfman McInnes .keywords: matrix, shell, create 960b627109SLois Curfman McInnes 970b627109SLois Curfman McInnes .seealso: MatShellSetMult(), MatShellSetMultTransAdd() 98e51e0e81SBarry Smith @*/ 996b5873e3SBarry Smith int MatShellCreate(MPI_Comm comm,int m,int n,void *ctx,Mat *mat) 100e51e0e81SBarry Smith { 10120563c6bSBarry Smith Mat newmat; 10288cf3e7dSBarry Smith Mat_Shell *shell; 1036b5873e3SBarry Smith PETSCHEADERCREATE(newmat,_Mat,MAT_COOKIE,MATSHELL,comm); 104a5a9c739SBarry Smith PLogObjectCreate(newmat); 10520563c6bSBarry Smith *mat = newmat; 10620563c6bSBarry Smith newmat->factor = 0; 10788cf3e7dSBarry Smith newmat->destroy= MatDestroy_Shell; 108*416022c9SBarry Smith PetscMemcpy(&newmat->ops,&MatOps,sizeof(struct _MatOps)); 10988cf3e7dSBarry Smith shell = PETSCNEW(Mat_Shell); CHKPTRQ(shell); 110*416022c9SBarry Smith PetscZero(shell,sizeof(Mat_Shell)); 11120563c6bSBarry Smith newmat->data = (void *) shell; 11220563c6bSBarry Smith shell->mult = 0; 11320563c6bSBarry Smith shell->m = m; 11420563c6bSBarry Smith shell->n = n; 11520563c6bSBarry Smith shell->ctx = ctx; 116e51e0e81SBarry Smith return 0; 117e51e0e81SBarry Smith } 118e51e0e81SBarry Smith 1194b828684SBarry Smith /*@C 1200b627109SLois Curfman McInnes MatShellSetMult - Sets the routine for computing the matrix-vector product. 121e51e0e81SBarry Smith 122e51e0e81SBarry Smith Input Parameters: 1230b627109SLois Curfman McInnes . mat - the matrix associated with this operation, created 1240b627109SLois Curfman McInnes with MatShellCreate() 1250b627109SLois Curfman McInnes . mult - the user-defined routine 126e51e0e81SBarry Smith 1270b627109SLois Curfman McInnes Calling sequence of mult: 1280b627109SLois Curfman McInnes int mult (void *ptr,Vec xin,Vec xout) 1290b627109SLois Curfman McInnes . ptr - the application context for matrix data 1300b627109SLois Curfman McInnes . xin - input vector 1310b627109SLois Curfman McInnes . xout - output vector 1320b627109SLois Curfman McInnes 1330b627109SLois Curfman McInnes .keywords: matrix, multiply, shell, set 1340b627109SLois Curfman McInnes 1350b627109SLois Curfman McInnes .seealso: MatShellCreate(), MatShellSetMultTransAdd() 136e51e0e81SBarry Smith @*/ 13720563c6bSBarry Smith int MatShellSetMult(Mat mat,int (*mult)(void*,Vec,Vec)) 138e51e0e81SBarry Smith { 13988cf3e7dSBarry Smith Mat_Shell *shell; 1401a941147SBarry Smith PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE); 14188cf3e7dSBarry Smith shell = (Mat_Shell *) mat->data; 14220563c6bSBarry Smith shell->mult = mult; 14320563c6bSBarry Smith return 0; 144e51e0e81SBarry Smith } 1454b828684SBarry Smith /*@C 1460b627109SLois Curfman McInnes MatShellSetMultTransAdd - Sets the routine for computing v3 = v2 + A' * v1. 147f0479e8cSBarry Smith 148f0479e8cSBarry Smith Input Parameters: 1490b627109SLois Curfman McInnes . mat - the matrix associated with this operation, created 1500b627109SLois Curfman McInnes with MatShellCreate() 1510b627109SLois Curfman McInnes . mult - the user-defined routine 152f0479e8cSBarry Smith 1530b627109SLois Curfman McInnes Calling sequence of mult: 1540b627109SLois Curfman McInnes int mult (void *ptr,Vec v1,Vec v2,Vec v3) 1550b627109SLois Curfman McInnes . ptr - the application context for matrix data 1560b627109SLois Curfman McInnes . v1, v2 - the input vectors 1570b627109SLois Curfman McInnes . v3 - the result 1580b627109SLois Curfman McInnes 1590b627109SLois Curfman McInnes .keywords: matrix, multiply, transpose 1600b627109SLois Curfman McInnes 1610b627109SLois Curfman McInnes .seealso: MatShellCreate(), MatShellSetMult() 162f0479e8cSBarry Smith @*/ 163f0479e8cSBarry Smith int MatShellSetMultTransAdd(Mat mat,int (*mult)(void*,Vec,Vec,Vec)) 164f0479e8cSBarry Smith { 16588cf3e7dSBarry Smith Mat_Shell *shell; 1661a941147SBarry Smith PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE); 16788cf3e7dSBarry Smith shell = (Mat_Shell *) mat->data; 168f0479e8cSBarry Smith shell->multtransadd = mult; 169f0479e8cSBarry Smith return 0; 170f0479e8cSBarry Smith } 1714b828684SBarry Smith /*@C 172b9fa9cd0SBarry Smith MatShellSetDestroy - Set the routine to use to destroy the 173b9fa9cd0SBarry Smith private contents of your MatShell. 174b9fa9cd0SBarry Smith 175b9fa9cd0SBarry Smith Input Parameters: 176b9fa9cd0SBarry Smith . mat - the matrix associated with this operation, created 177b9fa9cd0SBarry Smith with MatShellCreate() 178b9fa9cd0SBarry Smith . destroy - the user-defined routine 179b9fa9cd0SBarry Smith 180b9fa9cd0SBarry Smith Calling sequence of mult: 181b9fa9cd0SBarry Smith int destroy (void *ptr) 182b9fa9cd0SBarry Smith . ptr - the application context for matrix data 183b9fa9cd0SBarry Smith 184b9fa9cd0SBarry Smith .keywords: matrix, destroy, shell, set 185b9fa9cd0SBarry Smith 186b9fa9cd0SBarry Smith .seealso: MatShellCreate() 187b9fa9cd0SBarry Smith @*/ 188b9fa9cd0SBarry Smith int MatShellSetDestroy(Mat mat,int (*destroy)(void*)) 189b9fa9cd0SBarry Smith { 19088cf3e7dSBarry Smith Mat_Shell *shell; 1911a941147SBarry Smith PETSCVALIDHEADERSPECIFIC(mat,MAT_COOKIE); 19288cf3e7dSBarry Smith shell = (Mat_Shell *) mat->data; 193b9fa9cd0SBarry Smith shell->destroy = destroy; 194b9fa9cd0SBarry Smith return 0; 195b9fa9cd0SBarry Smith } 196f0479e8cSBarry Smith 197f0479e8cSBarry Smith 198