1*ef66eb69SBarry Smith /*$Id: shell.c,v 1.87 2001/07/20 21:20:12 bsmith Exp bsmith $*/ 2e51e0e81SBarry Smith 3e51e0e81SBarry Smith /* 420563c6bSBarry Smith This provides a simple shell for Fortran (and C programmers) to 520563c6bSBarry Smith create a very simple matrix class for use with KSP without coding 6ed3cc1f0SBarry Smith much of anything. 7e51e0e81SBarry Smith */ 8e51e0e81SBarry Smith 9e090d566SSatish Balay #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 10f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 11e51e0e81SBarry Smith 1220563c6bSBarry Smith typedef struct { 133a3eedf2SBarry Smith int (*destroy)(Mat); 14*ef66eb69SBarry Smith int (*mult)(Mat,Vec,Vec); 15*ef66eb69SBarry Smith PetscTruth scale,shift; 16*ef66eb69SBarry Smith PetscScalar vscale,vshift; 1720563c6bSBarry Smith void *ctx; 1888cf3e7dSBarry Smith } Mat_Shell; 19e51e0e81SBarry Smith 20711e205bSSatish Balay #undef __FUNCT__ 21711e205bSSatish Balay #define __FUNCT__ "MatShellGetContext" 22b4fd4287SBarry Smith /*@ 23a62d957aSLois Curfman McInnes MatShellGetContext - Returns the user-provided context associated with a shell matrix. 24b4fd4287SBarry Smith 25c7fcc2eaSBarry Smith Not Collective 26c7fcc2eaSBarry 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 3315091d37SBarry Smith Level: advanced 3415091d37SBarry Smith 35a62d957aSLois Curfman McInnes Notes: 36a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 37a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 38a62d957aSLois Curfman McInnes 39a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 40a62d957aSLois Curfman McInnes 41a62d957aSLois Curfman McInnes .seealso: MatCreateShell(), MatShellSetOperation() 42b4fd4287SBarry Smith @*/ 43b4fd4287SBarry Smith int MatShellGetContext(Mat mat,void **ctx) 44b4fd4287SBarry Smith { 45273d9f13SBarry Smith int ierr; 46273d9f13SBarry Smith PetscTruth flg; 47273d9f13SBarry Smith 483a40ed3dSBarry Smith PetscFunctionBegin; 4977c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 50273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 51273d9f13SBarry Smith if (!flg) *ctx = 0; 52b4fd4287SBarry Smith else *ctx = ((Mat_Shell*)(mat->data))->ctx; 533a40ed3dSBarry Smith PetscFunctionReturn(0); 54b4fd4287SBarry Smith } 55b4fd4287SBarry Smith 56711e205bSSatish Balay #undef __FUNCT__ 57711e205bSSatish Balay #define __FUNCT__ "MatDestroy_Shell" 58e1311b90SBarry Smith int MatDestroy_Shell(Mat mat) 59e51e0e81SBarry Smith { 60b9fa9cd0SBarry Smith int ierr; 6188cf3e7dSBarry Smith Mat_Shell *shell; 62ed3cc1f0SBarry Smith 633a40ed3dSBarry Smith PetscFunctionBegin; 6488cf3e7dSBarry Smith shell = (Mat_Shell*)mat->data; 653a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 66606d414cSSatish Balay ierr = PetscFree(shell);CHKERRQ(ierr); 673a40ed3dSBarry Smith PetscFunctionReturn(0); 68e51e0e81SBarry Smith } 69e51e0e81SBarry Smith 70711e205bSSatish Balay #undef __FUNCT__ 71711e205bSSatish Balay #define __FUNCT__ "MatGetOwnershipRange_Shell" 728f6be9afSLois Curfman McInnes int MatGetOwnershipRange_Shell(Mat mat,int *rstart,int *rend) 73b951964fSBarry Smith { 744c49b128SBarry Smith int ierr,tmp; 75ca161407SBarry Smith 76ca161407SBarry Smith PetscFunctionBegin; 774c49b128SBarry Smith ierr = MPI_Scan(&mat->m,&tmp,1,MPI_INT,MPI_SUM,mat->comm);CHKERRQ(ierr); 784c49b128SBarry Smith if (rstart) *rstart = tmp - mat->m; 794c49b128SBarry Smith if (rend) *rend = tmp; 803a40ed3dSBarry Smith PetscFunctionReturn(0); 81b951964fSBarry Smith } 82*ef66eb69SBarry Smith 83*ef66eb69SBarry Smith #undef __FUNCT__ 84*ef66eb69SBarry Smith #define __FUNCT__ "MatMult_Shell" 85*ef66eb69SBarry Smith int MatMult_Shell(Mat A,Vec x,Vec y) 86*ef66eb69SBarry Smith { 87*ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)A->data; 88*ef66eb69SBarry Smith int ierr; 89*ef66eb69SBarry Smith 90*ef66eb69SBarry Smith PetscFunctionBegin; 91*ef66eb69SBarry Smith ierr = (*shell->mult)(A,x,y);CHKERRQ(ierr); 92*ef66eb69SBarry Smith if (shell->shift && shell->scale) { 93*ef66eb69SBarry Smith ierr = VecAXPBY(&shell->vshift,&shell->vscale,x,y);CHKERRQ(ierr); 94*ef66eb69SBarry Smith } else if (shell->scale) { 95*ef66eb69SBarry Smith ierr = VecScale(&shell->vscale,y);CHKERRQ(ierr); 96*ef66eb69SBarry Smith } else { 97*ef66eb69SBarry Smith ierr = VecAXPY(&shell->vshift,x,y);CHKERRQ(ierr); 98*ef66eb69SBarry Smith } 99*ef66eb69SBarry Smith PetscFunctionReturn(0); 100*ef66eb69SBarry Smith } 101*ef66eb69SBarry Smith 102*ef66eb69SBarry Smith #undef __FUNCT__ 103*ef66eb69SBarry Smith #define __FUNCT__ "MatShift_Shell" 104*ef66eb69SBarry Smith int MatShift_Shell(PetscScalar *a,Mat Y) 105*ef66eb69SBarry Smith { 106*ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 107*ef66eb69SBarry Smith PetscFunctionBegin; 108*ef66eb69SBarry Smith if (shell->scale || shell->shift) { 109*ef66eb69SBarry Smith shell->vshift += *a; 110*ef66eb69SBarry Smith } else { 111*ef66eb69SBarry Smith shell->mult = Y->ops->mult; 112*ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 113*ef66eb69SBarry Smith shell->vshift = *a; 114*ef66eb69SBarry Smith } 115*ef66eb69SBarry Smith shell->shift = PETSC_TRUE; 116*ef66eb69SBarry Smith PetscFunctionReturn(0); 117*ef66eb69SBarry Smith } 118*ef66eb69SBarry Smith 119*ef66eb69SBarry Smith #undef __FUNCT__ 120*ef66eb69SBarry Smith #define __FUNCT__ "MatScale_Shell" 121*ef66eb69SBarry Smith int MatScale_Shell(PetscScalar *a,Mat Y) 122*ef66eb69SBarry Smith { 123*ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 124*ef66eb69SBarry Smith PetscFunctionBegin; 125*ef66eb69SBarry Smith if (shell->scale || shell->shift) { 126*ef66eb69SBarry Smith shell->vscale *= *a; 127*ef66eb69SBarry Smith } else { 128*ef66eb69SBarry Smith shell->mult = Y->ops->mult; 129*ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 130*ef66eb69SBarry Smith shell->vscale = *a; 131*ef66eb69SBarry Smith } 132*ef66eb69SBarry Smith shell->scale = PETSC_TRUE; 133*ef66eb69SBarry Smith PetscFunctionReturn(0); 134*ef66eb69SBarry Smith } 135*ef66eb69SBarry Smith 136*ef66eb69SBarry Smith #undef __FUNCT__ 137*ef66eb69SBarry Smith #define __FUNCT__ "MatAssemblyEnd_Shell" 138*ef66eb69SBarry Smith int MatAssemblyEnd_Shell(Mat Y,MatAssemblyType t) 139*ef66eb69SBarry Smith { 140*ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 141*ef66eb69SBarry Smith 142*ef66eb69SBarry Smith PetscFunctionBegin; 143*ef66eb69SBarry Smith if ((shell->shift || shell->scale) && t == MAT_FINAL_ASSEMBLY) { 144*ef66eb69SBarry Smith shell->scale = PETSC_FALSE; 145*ef66eb69SBarry Smith shell->shift = PETSC_FALSE; 146*ef66eb69SBarry Smith shell->vshift = 0.0; 147*ef66eb69SBarry Smith shell->vscale = 1.0; 148*ef66eb69SBarry Smith Y->ops->mult = shell->mult; 149*ef66eb69SBarry Smith } 150*ef66eb69SBarry Smith PetscFunctionReturn(0); 151*ef66eb69SBarry Smith } 152*ef66eb69SBarry Smith 153273d9f13SBarry Smith extern int MatConvert_Shell(Mat,MatType,Mat*); 154b951964fSBarry Smith 15509dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 15620563c6bSBarry Smith 0, 15720563c6bSBarry Smith 0, 15820563c6bSBarry Smith 0, 15920563c6bSBarry Smith 0, 160b951964fSBarry Smith 0, 161b951964fSBarry Smith 0, 162b951964fSBarry Smith 0, 163b951964fSBarry Smith 0, 164b951964fSBarry Smith 0, 165b951964fSBarry Smith 0, 166b951964fSBarry Smith 0, 167b951964fSBarry Smith 0, 168b951964fSBarry Smith 0, 169b951964fSBarry Smith 0, 170b951964fSBarry Smith 0, 171b951964fSBarry Smith 0, 172b951964fSBarry Smith 0, 173b951964fSBarry Smith 0, 174b951964fSBarry Smith 0, 175b951964fSBarry Smith 0, 176*ef66eb69SBarry Smith MatAssemblyEnd_Shell, 177b951964fSBarry Smith 0, 178b951964fSBarry Smith 0, 179b951964fSBarry Smith 0, 180b951964fSBarry Smith 0, 181b951964fSBarry Smith 0, 182b951964fSBarry Smith 0, 183b951964fSBarry Smith 0, 184b951964fSBarry Smith 0, 185273d9f13SBarry Smith 0, 186b951964fSBarry Smith MatGetOwnershipRange_Shell, 187b951964fSBarry Smith 0, 188b951964fSBarry Smith 0, 189b951964fSBarry Smith 0, 190b951964fSBarry Smith 0, 19109dc0095SBarry Smith 0, 19209dc0095SBarry Smith 0, 19309dc0095SBarry Smith 0, 19409dc0095SBarry Smith 0, 19509dc0095SBarry Smith 0, 19609dc0095SBarry Smith 0, 19709dc0095SBarry Smith 0, 19809dc0095SBarry Smith 0, 19909dc0095SBarry Smith 0, 20009dc0095SBarry Smith 0, 20109dc0095SBarry Smith 0, 20209dc0095SBarry Smith 0, 203*ef66eb69SBarry Smith MatScale_Shell, 204*ef66eb69SBarry Smith MatShift_Shell, 20509dc0095SBarry Smith 0, 20609dc0095SBarry Smith 0, 20709dc0095SBarry Smith 0, 20809dc0095SBarry Smith 0, 20909dc0095SBarry Smith 0, 21009dc0095SBarry Smith 0, 21109dc0095SBarry Smith 0, 21209dc0095SBarry Smith 0, 21309dc0095SBarry Smith 0, 21409dc0095SBarry Smith 0, 21509dc0095SBarry Smith 0, 21609dc0095SBarry Smith 0, 217273d9f13SBarry Smith 0, 218b9b97703SBarry Smith MatDestroy_Shell, 21909dc0095SBarry Smith 0, 2208a124369SBarry Smith MatGetPetscMaps_Petsc, 221273d9f13SBarry Smith 0, 222273d9f13SBarry Smith 0, 223273d9f13SBarry Smith 0, 224273d9f13SBarry Smith 0, 225273d9f13SBarry Smith 0, 226273d9f13SBarry Smith 0, 227273d9f13SBarry Smith 0, 228273d9f13SBarry Smith MatConvert_Shell}; 229273d9f13SBarry Smith 230273d9f13SBarry Smith EXTERN_C_BEGIN 231711e205bSSatish Balay #undef __FUNCT__ 232711e205bSSatish Balay #define __FUNCT__ "MatCreate_Shell" 233273d9f13SBarry Smith int MatCreate_Shell(Mat A) 234273d9f13SBarry Smith { 235273d9f13SBarry Smith Mat_Shell *b; 236273d9f13SBarry Smith int ierr; 237273d9f13SBarry Smith 238273d9f13SBarry Smith PetscFunctionBegin; 239273d9f13SBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 240273d9f13SBarry Smith 241b0a32e0cSBarry Smith ierr = PetscNew(Mat_Shell,&b);CHKERRQ(ierr); 242b0a32e0cSBarry Smith PetscLogObjectMemory(A,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 243273d9f13SBarry Smith ierr = PetscMemzero(b,sizeof(Mat_Shell));CHKERRQ(ierr); 244273d9f13SBarry Smith A->data = (void*)b; 245273d9f13SBarry Smith 246273d9f13SBarry Smith if (A->m == PETSC_DECIDE || A->n == PETSC_DECIDE) { 247273d9f13SBarry Smith SETERRQ(1,"Must give local row and column count for matrix"); 248273d9f13SBarry Smith } 249273d9f13SBarry Smith 250273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->m,&A->M);CHKERRQ(ierr); 251273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->n,&A->N);CHKERRQ(ierr); 252273d9f13SBarry Smith 2538a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->m,A->M,&A->rmap);CHKERRQ(ierr); 2548a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->n,A->N,&A->cmap);CHKERRQ(ierr); 255273d9f13SBarry Smith 256273d9f13SBarry Smith b->ctx = 0; 257*ef66eb69SBarry Smith b->scale = PETSC_FALSE; 258*ef66eb69SBarry Smith b->shift = PETSC_FALSE; 259*ef66eb69SBarry Smith b->vshift = 0.0; 260*ef66eb69SBarry Smith b->vscale = 1.0; 261*ef66eb69SBarry Smith b->mult = 0; 262273d9f13SBarry Smith A->assembled = PETSC_TRUE; 263273d9f13SBarry Smith A->preallocated = PETSC_TRUE; 264273d9f13SBarry Smith PetscFunctionReturn(0); 265273d9f13SBarry Smith } 266273d9f13SBarry Smith EXTERN_C_END 267e51e0e81SBarry Smith 268711e205bSSatish Balay #undef __FUNCT__ 269711e205bSSatish Balay #define __FUNCT__ "MatCreateShell" 2704b828684SBarry Smith /*@C 271052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 272ff756334SLois Curfman McInnes private data storage format. 273e51e0e81SBarry Smith 274c7fcc2eaSBarry Smith Collective on MPI_Comm 275c7fcc2eaSBarry Smith 276e51e0e81SBarry Smith Input Parameters: 277c7fcc2eaSBarry Smith + comm - MPI communicator 278c7fcc2eaSBarry Smith . m - number of local rows (must be given) 279c7fcc2eaSBarry Smith . n - number of local columns (must be given) 280c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 281c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 282c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 283e51e0e81SBarry Smith 284ff756334SLois Curfman McInnes Output Parameter: 28544cd7ae7SLois Curfman McInnes . A - the matrix 286e51e0e81SBarry Smith 287ff2fd236SBarry Smith Level: advanced 288ff2fd236SBarry Smith 289f39d1f56SLois Curfman McInnes Usage: 2907b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 291f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 29237bd1cefSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)())mult); 293f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 294f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 295f39d1f56SLois Curfman McInnes 296ff756334SLois Curfman McInnes Notes: 297ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 298ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 299ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 300e51e0e81SBarry Smith 301f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 302f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 303645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 304645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 305645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 306645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 307645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 308645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 309645985a0SLois Curfman McInnes For example, 310f39d1f56SLois Curfman McInnes 311f39d1f56SLois Curfman McInnes $ 312f39d1f56SLois Curfman McInnes $ Vec x, y 3137b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 314645985a0SLois Curfman McInnes $ Mat A 315f39d1f56SLois Curfman McInnes $ 316c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 317c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 318f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 319c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 320c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 32137bd1cefSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)())mult); 322645985a0SLois Curfman McInnes $ MatMult(A,x,y); 323645985a0SLois Curfman McInnes $ MatDestroy(A); 324f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 325645985a0SLois Curfman McInnes $ 326e51e0e81SBarry Smith 3270b627109SLois Curfman McInnes .keywords: matrix, shell, create 3280b627109SLois Curfman McInnes 3293a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext() 330e51e0e81SBarry Smith @*/ 331f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A) 332e51e0e81SBarry Smith { 333c7fcc2eaSBarry Smith int ierr; 334ed3cc1f0SBarry Smith 3353a40ed3dSBarry Smith PetscFunctionBegin; 336273d9f13SBarry Smith ierr = MatCreate(comm,m,n,M,N,A);CHKERRQ(ierr); 337273d9f13SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 338273d9f13SBarry Smith ierr = MatShellSetContext(*A,ctx);CHKERRQ(ierr); 339273d9f13SBarry Smith PetscFunctionReturn(0); 340c7fcc2eaSBarry Smith } 341c7fcc2eaSBarry Smith 342711e205bSSatish Balay #undef __FUNCT__ 343711e205bSSatish Balay #define __FUNCT__ "MatShellSetContext" 344273d9f13SBarry Smith /*@C 345273d9f13SBarry Smith MatShellSetContext - sets the context for a shell matrix 346c7fcc2eaSBarry Smith 347273d9f13SBarry Smith Collective on Mat 348c7fcc2eaSBarry Smith 349273d9f13SBarry Smith Input Parameters: 350273d9f13SBarry Smith + mat - the shell matrix 351273d9f13SBarry Smith - ctx - the context 352273d9f13SBarry Smith 353273d9f13SBarry Smith Level: advanced 354273d9f13SBarry Smith 355273d9f13SBarry Smith 356273d9f13SBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 357273d9f13SBarry Smith @*/ 358273d9f13SBarry Smith int MatShellSetContext(Mat mat,void *ctx) 359273d9f13SBarry Smith { 360273d9f13SBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 361273d9f13SBarry Smith int ierr; 362273d9f13SBarry Smith PetscTruth flg; 363273d9f13SBarry Smith 364273d9f13SBarry Smith PetscFunctionBegin; 365273d9f13SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 366273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 367273d9f13SBarry Smith if (flg) { 368273d9f13SBarry Smith shell->ctx = ctx; 369273d9f13SBarry Smith } 3703a40ed3dSBarry Smith PetscFunctionReturn(0); 371e51e0e81SBarry Smith } 372e51e0e81SBarry Smith 373711e205bSSatish Balay #undef __FUNCT__ 374711e205bSSatish Balay #define __FUNCT__ "MatShellSetOperation" 375c16cb8f2SBarry Smith /*@C 3763a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 3773a3eedf2SBarry Smith a shell matrix. 378e51e0e81SBarry Smith 379fee21e36SBarry Smith Collective on Mat 380fee21e36SBarry Smith 381c7fcc2eaSBarry Smith Input Parameters: 382c7fcc2eaSBarry Smith + mat - the shell matrix 383c7fcc2eaSBarry Smith . op - the name of the operation 384c7fcc2eaSBarry Smith - f - the function that provides the operation. 385c7fcc2eaSBarry Smith 38615091d37SBarry Smith Level: advanced 38715091d37SBarry Smith 388fae171e0SBarry Smith Usage: 389a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 390f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 39137bd1cefSSatish Balay $ ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)())usermult); 3920b627109SLois Curfman McInnes 393a62d957aSLois Curfman McInnes Notes: 394e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 3951c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 396a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 3971c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 398a62d957aSLois Curfman McInnes 399a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 400deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 401deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 402deebb3c3SLois Curfman McInnes routines, e.g., 403a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 404a62d957aSLois Curfman McInnes 405a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 406a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 407a62d957aSLois Curfman McInnes set by MatCreateShell(). 408a62d957aSLois Curfman McInnes 409a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 410a62d957aSLois Curfman McInnes 411d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 412e51e0e81SBarry Smith @*/ 41337bd1cefSSatish Balay int MatShellSetOperation(Mat mat,MatOperation op,void (*f)()) 414e51e0e81SBarry Smith { 415273d9f13SBarry Smith int ierr; 416273d9f13SBarry Smith PetscTruth flg; 417273d9f13SBarry Smith 4183a40ed3dSBarry Smith PetscFunctionBegin; 41977c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 4201c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 421273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 422273d9f13SBarry Smith if (flg) { 423a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 4243a3eedf2SBarry Smith shell->destroy = (int (*)(Mat)) f; 4250c0c84c0SBarry Smith } else mat->ops->destroy = (int (*)(Mat)) f; 426a62d957aSLois Curfman McInnes } 427b0a32e0cSBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (int (*)(Mat,PetscViewer)) f; 42837bd1cefSSatish Balay else (((void(**)())mat->ops)[op]) = f; 429a62d957aSLois Curfman McInnes 4303a40ed3dSBarry Smith PetscFunctionReturn(0); 431e51e0e81SBarry Smith } 432f0479e8cSBarry Smith 433711e205bSSatish Balay #undef __FUNCT__ 434711e205bSSatish Balay #define __FUNCT__ "MatShellGetOperation" 435d4bb536fSBarry Smith /*@C 436d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 437d4bb536fSBarry Smith 438c7fcc2eaSBarry Smith Not Collective 439c7fcc2eaSBarry Smith 440d4bb536fSBarry Smith Input Parameters: 441c7fcc2eaSBarry Smith + mat - the shell matrix 442c7fcc2eaSBarry Smith - op - the name of the operation 443d4bb536fSBarry Smith 444d4bb536fSBarry Smith Output Parameter: 445d4bb536fSBarry Smith . f - the function that provides the operation. 446d4bb536fSBarry Smith 44715091d37SBarry Smith Level: advanced 44815091d37SBarry Smith 449d4bb536fSBarry Smith Notes: 450e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 451d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 452d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 453d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 454d4bb536fSBarry Smith 455d4bb536fSBarry Smith All user-provided functions have the same calling 456d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 457d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 458d4bb536fSBarry Smith routines, e.g., 459d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 460d4bb536fSBarry Smith 461d4bb536fSBarry Smith Within each user-defined routine, the user should call 462d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 463d4bb536fSBarry Smith set by MatCreateShell(). 464d4bb536fSBarry Smith 465d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 466d4bb536fSBarry Smith 467d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation() 468d4bb536fSBarry Smith @*/ 46937bd1cefSSatish Balay int MatShellGetOperation(Mat mat,MatOperation op,void(**f)()) 470d4bb536fSBarry Smith { 471273d9f13SBarry Smith int ierr; 472273d9f13SBarry Smith PetscTruth flg; 473273d9f13SBarry Smith 4743a40ed3dSBarry Smith PetscFunctionBegin; 475d4bb536fSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 476d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 477273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 478273d9f13SBarry Smith if (flg) { 479d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 48037bd1cefSSatish Balay *f = (void(*)())shell->destroy; 481c7fcc2eaSBarry Smith } else { 48237bd1cefSSatish Balay *f = (void(*)())mat->ops->destroy; 483d4bb536fSBarry Smith } 484c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 48537bd1cefSSatish Balay *f = (void(*)())mat->ops->view; 486c7fcc2eaSBarry Smith } else { 48737bd1cefSSatish Balay *f = (((void(**)())mat->ops)[op]); 488d4bb536fSBarry Smith } 489d4bb536fSBarry Smith 4903a40ed3dSBarry Smith PetscFunctionReturn(0); 491d4bb536fSBarry Smith } 492d4bb536fSBarry Smith 493