1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*e1311b90SBarry Smith static char vcid[] = "$Id: shell.c,v 1.54 1998/03/12 23:18:43 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" 1270f55243SBarry Smith #include "src/mat/matimpl.h" /*I "mat.h" I*/ 13f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 14e51e0e81SBarry Smith 1520563c6bSBarry Smith typedef struct { 16f39d1f56SLois Curfman McInnes int M, N; /* number of global rows, columns */ 17f39d1f56SLois Curfman McInnes int m, n; /* number of local rows, columns */ 183a3eedf2SBarry Smith int (*destroy)(Mat); 1920563c6bSBarry Smith void *ctx; 2088cf3e7dSBarry Smith } Mat_Shell; 21e51e0e81SBarry Smith 225615d1e5SSatish Balay #undef __FUNC__ 23d4bb536fSBarry Smith #define __FUNC__ "MatShellGetContext" 24b4fd4287SBarry Smith /*@ 25a62d957aSLois Curfman McInnes MatShellGetContext - Returns the user-provided context associated with a shell matrix. 26b4fd4287SBarry Smith 27b4fd4287SBarry Smith Input Parameter: 28b4fd4287SBarry Smith . mat - the matrix, should have been created with MatCreateShell() 29b4fd4287SBarry Smith 30b4fd4287SBarry Smith Output Parameter: 31b4fd4287SBarry Smith . ctx - the user provided context 32b4fd4287SBarry Smith 33a62d957aSLois Curfman McInnes Notes: 34a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 35a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 36a62d957aSLois Curfman McInnes 37a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 38a62d957aSLois Curfman McInnes 39a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellSetOperation() 40b4fd4287SBarry Smith @*/ 41b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx) 42b4fd4287SBarry Smith { 433a40ed3dSBarry Smith PetscFunctionBegin; 4477c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 45b4fd4287SBarry Smith if (mat->type != MATSHELL) *ctx = 0; 46b4fd4287SBarry Smith else *ctx = ((Mat_Shell *) (mat->data))->ctx; 473a40ed3dSBarry Smith PetscFunctionReturn(0); 48b4fd4287SBarry Smith } 49b4fd4287SBarry Smith 505615d1e5SSatish Balay #undef __FUNC__ 51d4bb536fSBarry Smith #define __FUNC__ "MatGetSize_Shell" 528f6be9afSLois Curfman McInnes int MatGetSize_Shell(Mat mat,int *M,int *N) 5371b459e3SLois Curfman McInnes { 5471b459e3SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 553a40ed3dSBarry Smith 563a40ed3dSBarry Smith PetscFunctionBegin; 57f830108cSBarry Smith if (M) *M = shell->M; 58f830108cSBarry Smith if (N) *N = shell->N; 593a40ed3dSBarry Smith PetscFunctionReturn(0); 60f39d1f56SLois Curfman McInnes } 61f39d1f56SLois Curfman McInnes 625615d1e5SSatish Balay #undef __FUNC__ 63d4bb536fSBarry Smith #define __FUNC__ "MatGetLocalSize_Shell" 648f6be9afSLois Curfman McInnes int MatGetLocalSize_Shell(Mat mat,int *m,int *n) 65f39d1f56SLois Curfman McInnes { 66f39d1f56SLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 673a40ed3dSBarry Smith 683a40ed3dSBarry Smith PetscFunctionBegin; 69f830108cSBarry Smith if (m) *m = shell->m; 70f830108cSBarry Smith if (n) *n = shell->n; 713a40ed3dSBarry Smith PetscFunctionReturn(0); 7271b459e3SLois Curfman McInnes } 7371b459e3SLois Curfman McInnes 745615d1e5SSatish Balay #undef __FUNC__ 75d4bb536fSBarry Smith #define __FUNC__ "MatDestroy_Shell" 76*e1311b90SBarry Smith int MatDestroy_Shell(Mat mat) 77e51e0e81SBarry Smith { 78b9fa9cd0SBarry Smith int ierr; 7988cf3e7dSBarry Smith Mat_Shell *shell; 80ed3cc1f0SBarry Smith 813a40ed3dSBarry Smith PetscFunctionBegin; 8288cf3e7dSBarry Smith shell = (Mat_Shell *) mat->data; 833a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 840452661fSBarry Smith PetscFree(shell); 853a3eedf2SBarry Smith PLogObjectDestroy(mat); 863a3eedf2SBarry Smith PetscHeaderDestroy(mat); 873a40ed3dSBarry Smith PetscFunctionReturn(0); 88e51e0e81SBarry Smith } 89e51e0e81SBarry Smith 908f6be9afSLois Curfman McInnes int MatGetOwnershipRange_Shell(Mat mat, int *rstart,int *rend) 91b951964fSBarry Smith { 92ca161407SBarry Smith int ierr; 93ca161407SBarry Smith 94ca161407SBarry Smith PetscFunctionBegin; 95ca161407SBarry Smith ierr = MPI_Scan(&mat->m,rend,1,MPI_INT,MPI_SUM,mat->comm);CHKERRQ(ierr); 96b951964fSBarry Smith *rstart = *rend - mat->m; 973a40ed3dSBarry Smith PetscFunctionReturn(0); 98b951964fSBarry Smith } 99b951964fSBarry Smith 100b951964fSBarry Smith 101b951964fSBarry Smith 102b951964fSBarry Smith 103b951964fSBarry Smith static struct _MatOps MatOps = {0, 10420563c6bSBarry Smith 0, 10520563c6bSBarry Smith 0, 10620563c6bSBarry Smith 0, 10720563c6bSBarry Smith 0, 108b951964fSBarry Smith 0, 109b951964fSBarry Smith 0, 110b951964fSBarry Smith 0, 111b951964fSBarry Smith 0, 112b951964fSBarry Smith 0, 113b951964fSBarry Smith 0, 114b951964fSBarry Smith 0, 115b951964fSBarry Smith 0, 116b951964fSBarry Smith 0, 117b951964fSBarry Smith 0, 118b951964fSBarry Smith 0, 119b951964fSBarry Smith 0, 120b951964fSBarry Smith 0, 121b951964fSBarry Smith 0, 122b951964fSBarry Smith 0, 123b951964fSBarry Smith 0, 124b951964fSBarry Smith 0, 125b951964fSBarry Smith 0, 126b951964fSBarry Smith 0, 127b951964fSBarry Smith 0, 128b951964fSBarry Smith 0, 129b951964fSBarry Smith 0, 130b951964fSBarry Smith 0, 131b951964fSBarry Smith 0, 132b951964fSBarry Smith 0, 133b951964fSBarry Smith MatGetSize_Shell, 134b951964fSBarry Smith MatGetLocalSize_Shell, 135b951964fSBarry Smith MatGetOwnershipRange_Shell, 136b951964fSBarry Smith 0, 137b951964fSBarry Smith 0, 138b951964fSBarry Smith 0, 139b951964fSBarry Smith 0, 140b951964fSBarry Smith 0 }; 141e51e0e81SBarry Smith 1425615d1e5SSatish Balay #undef __FUNC__ 143d4bb536fSBarry Smith #define __FUNC__ "MatCreateShell" 1444b828684SBarry Smith /*@C 145052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 146ff756334SLois Curfman McInnes private data storage format. 147e51e0e81SBarry Smith 148e51e0e81SBarry Smith Input Parameters: 1496b5873e3SBarry Smith . comm - MPI communicator 150f39d1f56SLois Curfman McInnes . m - number of local rows 151f39d1f56SLois Curfman McInnes . n - number of local columns 152f39d1f56SLois Curfman McInnes . M - number of global rows 153f39d1f56SLois Curfman McInnes . N - number of global columns 154deebb3c3SLois Curfman McInnes . ctx - pointer to data needed by the shell matrix routines 155e51e0e81SBarry Smith 156ff756334SLois Curfman McInnes Output Parameter: 15744cd7ae7SLois Curfman McInnes . A - the matrix 158e51e0e81SBarry Smith 159f39d1f56SLois Curfman McInnes Usage: 160f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 1611c1c02c0SLois Curfman McInnes $ MatShellSetOperation(mat,MATOP_MULT,mult); 162f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 163f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 164f39d1f56SLois Curfman McInnes 165ff756334SLois Curfman McInnes Notes: 166ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 167ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 168ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 169e51e0e81SBarry Smith 170f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 171f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 172645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 173645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 174645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 175645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 176645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 177645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 178645985a0SLois Curfman McInnes For example, 179f39d1f56SLois Curfman McInnes 180f39d1f56SLois Curfman McInnes $ 181f39d1f56SLois Curfman McInnes $ Vec x, y 182645985a0SLois Curfman McInnes $ Mat A 183f39d1f56SLois Curfman McInnes $ 184522c5e43SBarry Smith $ VecCreate(comm,PETSC_DECIDE,M,&y); 185522c5e43SBarry Smith $ VecCreate(comm,PETSC_DECIDE,N,&x); 186f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 187645985a0SLois Curfman McInnes $ MatCreateShell(comm,m,N,M,N,ctx,&A); 1881c1c02c0SLois Curfman McInnes $ MatShellSetOperation(mat,MATOP_MULT,mult); 189645985a0SLois Curfman McInnes $ MatMult(A,x,y); 190645985a0SLois Curfman McInnes $ MatDestroy(A); 191f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 192645985a0SLois Curfman McInnes $ 193e51e0e81SBarry Smith 1940b627109SLois Curfman McInnes .keywords: matrix, shell, create 1950b627109SLois Curfman McInnes 1963a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext() 197e51e0e81SBarry Smith @*/ 198f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A) 199e51e0e81SBarry Smith { 20044cd7ae7SLois Curfman McInnes Mat B; 20144cd7ae7SLois Curfman McInnes Mat_Shell *b; 202ed3cc1f0SBarry Smith 2033a40ed3dSBarry Smith PetscFunctionBegin; 204f830108cSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSHELL,comm,MatDestroy,MatView); 20544cd7ae7SLois Curfman McInnes PLogObjectCreate(B); 20644cd7ae7SLois Curfman McInnes B->factor = 0; 20744cd7ae7SLois Curfman McInnes B->assembled = PETSC_TRUE; 208f830108cSBarry Smith PetscMemcpy(B->ops,&MatOps,sizeof(struct _MatOps)); 209*e1311b90SBarry Smith B->ops->destroy = MatDestroy_Shell; 210227d817aSBarry Smith 21144cd7ae7SLois Curfman McInnes b = PetscNew(Mat_Shell); CHKPTRQ(b); 212eed86810SBarry Smith PLogObjectMemory(B,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 21344cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_Shell)); 21444cd7ae7SLois Curfman McInnes B->data = (void *) b; 215f39d1f56SLois Curfman McInnes b->M = M; B->M = M; 216f39d1f56SLois Curfman McInnes b->N = N; B->N = N; 217f39d1f56SLois Curfman McInnes b->m = m; B->m = m; 218f39d1f56SLois Curfman McInnes b->n = n; B->n = n; 21944cd7ae7SLois Curfman McInnes b->ctx = ctx; 22044cd7ae7SLois Curfman McInnes *A = B; 2213a40ed3dSBarry Smith PetscFunctionReturn(0); 222e51e0e81SBarry Smith } 223e51e0e81SBarry Smith 2245615d1e5SSatish Balay #undef __FUNC__ 225d4bb536fSBarry Smith #define __FUNC__ "MatShellSetOperation" 226c16cb8f2SBarry Smith /*@C 2273a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 2283a3eedf2SBarry Smith a shell matrix. 229e51e0e81SBarry Smith 230e51e0e81SBarry Smith Input Parameters: 231fae171e0SBarry Smith . mat - the shell matrix 232fae171e0SBarry Smith . op - the name of the operation 233fae171e0SBarry Smith . f - the function that provides the operation. 234e51e0e81SBarry Smith 235fae171e0SBarry Smith Usage: 236a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 237f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 2381c1c02c0SLois Curfman McInnes $ ierr = MatShellSetOperation(A,MATOP_MULT,usermult); 2390b627109SLois Curfman McInnes 240a62d957aSLois Curfman McInnes Notes: 241a62d957aSLois Curfman McInnes See the file petsc/include/mat.h for a complete list of matrix 2421c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 243a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 2441c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 245a62d957aSLois Curfman McInnes 246a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 247deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 248deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 249deebb3c3SLois Curfman McInnes routines, e.g., 250a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 251a62d957aSLois Curfman McInnes 252a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 253a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 254a62d957aSLois Curfman McInnes set by MatCreateShell(). 255a62d957aSLois Curfman McInnes 256a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 257a62d957aSLois Curfman McInnes 258d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 259e51e0e81SBarry Smith @*/ 260fae171e0SBarry Smith int MatShellSetOperation(Mat mat,MatOperation op, void *f) 261e51e0e81SBarry Smith { 2623a40ed3dSBarry Smith PetscFunctionBegin; 26377c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 264fae171e0SBarry Smith 2651c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 266a62d957aSLois Curfman McInnes if (mat->type == MATSHELL) { 267a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell *) mat->data; 2683a3eedf2SBarry Smith shell->destroy = (int (*)(Mat)) f; 269a62d957aSLois Curfman McInnes } 270*e1311b90SBarry Smith else mat->ops->destroy = (int (*)(Mat)) f; 271a62d957aSLois Curfman McInnes } 272*e1311b90SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (int (*)(Mat,Viewer)) f; 273f830108cSBarry Smith else (((void**)mat->ops)[op]) = f; 274a62d957aSLois Curfman McInnes 2753a40ed3dSBarry Smith PetscFunctionReturn(0); 276e51e0e81SBarry Smith } 277f0479e8cSBarry Smith 278d4bb536fSBarry Smith #undef __FUNC__ 279d4bb536fSBarry Smith #define __FUNC__ "MatShellGetOperation" 280d4bb536fSBarry Smith /*@C 281d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 282d4bb536fSBarry Smith 283d4bb536fSBarry Smith Input Parameters: 284d4bb536fSBarry Smith . mat - the shell matrix 285d4bb536fSBarry Smith . op - the name of the operation 286d4bb536fSBarry Smith 287d4bb536fSBarry Smith Output Parameter: 288d4bb536fSBarry Smith . f - the function that provides the operation. 289d4bb536fSBarry Smith 290d4bb536fSBarry Smith Notes: 291d4bb536fSBarry Smith See the file petsc/include/mat.h for a complete list of matrix 292d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 293d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 294d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 295d4bb536fSBarry Smith 296d4bb536fSBarry Smith All user-provided functions have the same calling 297d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 298d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 299d4bb536fSBarry Smith routines, e.g., 300d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 301d4bb536fSBarry Smith 302d4bb536fSBarry Smith Within each user-defined routine, the user should call 303d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 304d4bb536fSBarry Smith set by MatCreateShell(). 305d4bb536fSBarry Smith 306d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 307d4bb536fSBarry Smith 308d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation() 309d4bb536fSBarry Smith @*/ 310d4bb536fSBarry Smith int MatShellGetOperation(Mat mat,MatOperation op, void **f) 311d4bb536fSBarry Smith { 3123a40ed3dSBarry Smith PetscFunctionBegin; 313d4bb536fSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 314d4bb536fSBarry Smith 315d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 316d4bb536fSBarry Smith if (mat->type == MATSHELL) { 317d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell *) mat->data; 318d4bb536fSBarry Smith *f = (void *) shell->destroy; 319d4bb536fSBarry Smith } 320*e1311b90SBarry Smith else *f = (void *) mat->ops->destroy; 321d4bb536fSBarry Smith } 322*e1311b90SBarry Smith else if (op == MATOP_VIEW) *f = (void *) mat->ops->view; 323d4bb536fSBarry Smith else *f = (((void**)&mat->ops)[op]); 324d4bb536fSBarry Smith 3253a40ed3dSBarry Smith PetscFunctionReturn(0); 326d4bb536fSBarry Smith } 327d4bb536fSBarry Smith 328