173f4d377SMatthew Knepley /*$Id: shell.c,v 1.88 2001/09/07 20:09:41 bsmith Exp $*/ 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); 14ef66eb69SBarry Smith int (*mult)(Mat,Vec,Vec); 15ef66eb69SBarry Smith PetscTruth scale,shift; 16ef66eb69SBarry 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__ 71ef66eb69SBarry Smith #define __FUNCT__ "MatMult_Shell" 72ef66eb69SBarry Smith int MatMult_Shell(Mat A,Vec x,Vec y) 73ef66eb69SBarry Smith { 74ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)A->data; 75ef66eb69SBarry Smith int ierr; 76ef66eb69SBarry Smith 77ef66eb69SBarry Smith PetscFunctionBegin; 78ef66eb69SBarry Smith ierr = (*shell->mult)(A,x,y);CHKERRQ(ierr); 79ef66eb69SBarry Smith if (shell->shift && shell->scale) { 80ef66eb69SBarry Smith ierr = VecAXPBY(&shell->vshift,&shell->vscale,x,y);CHKERRQ(ierr); 81ef66eb69SBarry Smith } else if (shell->scale) { 82ef66eb69SBarry Smith ierr = VecScale(&shell->vscale,y);CHKERRQ(ierr); 83ef66eb69SBarry Smith } else { 84ef66eb69SBarry Smith ierr = VecAXPY(&shell->vshift,x,y);CHKERRQ(ierr); 85ef66eb69SBarry Smith } 86ef66eb69SBarry Smith PetscFunctionReturn(0); 87ef66eb69SBarry Smith } 88ef66eb69SBarry Smith 89ef66eb69SBarry Smith #undef __FUNCT__ 90ef66eb69SBarry Smith #define __FUNCT__ "MatShift_Shell" 91ef66eb69SBarry Smith int MatShift_Shell(PetscScalar *a,Mat Y) 92ef66eb69SBarry Smith { 93ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 94ef66eb69SBarry Smith PetscFunctionBegin; 95ef66eb69SBarry Smith if (shell->scale || shell->shift) { 96ef66eb69SBarry Smith shell->vshift += *a; 97ef66eb69SBarry Smith } else { 98ef66eb69SBarry Smith shell->mult = Y->ops->mult; 99ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 100ef66eb69SBarry Smith shell->vshift = *a; 101ef66eb69SBarry Smith } 102ef66eb69SBarry Smith shell->shift = PETSC_TRUE; 103ef66eb69SBarry Smith PetscFunctionReturn(0); 104ef66eb69SBarry Smith } 105ef66eb69SBarry Smith 106ef66eb69SBarry Smith #undef __FUNCT__ 107ef66eb69SBarry Smith #define __FUNCT__ "MatScale_Shell" 108ef66eb69SBarry Smith int MatScale_Shell(PetscScalar *a,Mat Y) 109ef66eb69SBarry Smith { 110ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 111ef66eb69SBarry Smith PetscFunctionBegin; 112ef66eb69SBarry Smith if (shell->scale || shell->shift) { 113ef66eb69SBarry Smith shell->vscale *= *a; 114ef66eb69SBarry Smith } else { 115ef66eb69SBarry Smith shell->mult = Y->ops->mult; 116ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 117ef66eb69SBarry Smith shell->vscale = *a; 118ef66eb69SBarry Smith } 119ef66eb69SBarry Smith shell->scale = PETSC_TRUE; 120ef66eb69SBarry Smith PetscFunctionReturn(0); 121ef66eb69SBarry Smith } 122ef66eb69SBarry Smith 123ef66eb69SBarry Smith #undef __FUNCT__ 124ef66eb69SBarry Smith #define __FUNCT__ "MatAssemblyEnd_Shell" 125ef66eb69SBarry Smith int MatAssemblyEnd_Shell(Mat Y,MatAssemblyType t) 126ef66eb69SBarry Smith { 127ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 128ef66eb69SBarry Smith 129ef66eb69SBarry Smith PetscFunctionBegin; 130ef66eb69SBarry Smith if ((shell->shift || shell->scale) && t == MAT_FINAL_ASSEMBLY) { 131ef66eb69SBarry Smith shell->scale = PETSC_FALSE; 132ef66eb69SBarry Smith shell->shift = PETSC_FALSE; 133ef66eb69SBarry Smith shell->vshift = 0.0; 134ef66eb69SBarry Smith shell->vscale = 1.0; 135ef66eb69SBarry Smith Y->ops->mult = shell->mult; 136ef66eb69SBarry Smith } 137ef66eb69SBarry Smith PetscFunctionReturn(0); 138ef66eb69SBarry Smith } 139ef66eb69SBarry Smith 140273d9f13SBarry Smith extern int MatConvert_Shell(Mat,MatType,Mat*); 141b951964fSBarry Smith 14209dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 14320563c6bSBarry Smith 0, 14420563c6bSBarry Smith 0, 14520563c6bSBarry Smith 0, 14620563c6bSBarry Smith 0, 147b951964fSBarry Smith 0, 148b951964fSBarry Smith 0, 149b951964fSBarry Smith 0, 150b951964fSBarry Smith 0, 151b951964fSBarry Smith 0, 152b951964fSBarry Smith 0, 153b951964fSBarry Smith 0, 154b951964fSBarry Smith 0, 155b951964fSBarry Smith 0, 156b951964fSBarry Smith 0, 157b951964fSBarry Smith 0, 158b951964fSBarry Smith 0, 159b951964fSBarry Smith 0, 160b951964fSBarry Smith 0, 161b951964fSBarry Smith 0, 162b951964fSBarry Smith 0, 163ef66eb69SBarry Smith MatAssemblyEnd_Shell, 164b951964fSBarry Smith 0, 165b951964fSBarry Smith 0, 166b951964fSBarry Smith 0, 167b951964fSBarry Smith 0, 168b951964fSBarry Smith 0, 169b951964fSBarry Smith 0, 170b951964fSBarry Smith 0, 171b951964fSBarry Smith 0, 172273d9f13SBarry Smith 0, 173b951964fSBarry Smith 0, 174b951964fSBarry Smith 0, 175b951964fSBarry Smith 0, 176b951964fSBarry Smith 0, 17709dc0095SBarry Smith 0, 17809dc0095SBarry Smith 0, 17909dc0095SBarry Smith 0, 18009dc0095SBarry Smith 0, 18109dc0095SBarry Smith 0, 18209dc0095SBarry Smith 0, 18309dc0095SBarry Smith 0, 18409dc0095SBarry Smith 0, 18509dc0095SBarry Smith 0, 18609dc0095SBarry Smith 0, 18709dc0095SBarry Smith 0, 18809dc0095SBarry Smith 0, 189ef66eb69SBarry Smith MatScale_Shell, 190ef66eb69SBarry Smith MatShift_Shell, 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, 203273d9f13SBarry Smith 0, 204b9b97703SBarry Smith MatDestroy_Shell, 20509dc0095SBarry Smith 0, 2068a124369SBarry Smith MatGetPetscMaps_Petsc, 207273d9f13SBarry Smith 0, 208273d9f13SBarry Smith 0, 209273d9f13SBarry Smith 0, 210273d9f13SBarry Smith 0, 211273d9f13SBarry Smith 0, 212273d9f13SBarry Smith 0, 213273d9f13SBarry Smith 0, 214273d9f13SBarry Smith MatConvert_Shell}; 215273d9f13SBarry Smith 216273d9f13SBarry Smith EXTERN_C_BEGIN 217711e205bSSatish Balay #undef __FUNCT__ 218711e205bSSatish Balay #define __FUNCT__ "MatCreate_Shell" 219273d9f13SBarry Smith int MatCreate_Shell(Mat A) 220273d9f13SBarry Smith { 221273d9f13SBarry Smith Mat_Shell *b; 222273d9f13SBarry Smith int ierr; 223273d9f13SBarry Smith 224273d9f13SBarry Smith PetscFunctionBegin; 225273d9f13SBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 226273d9f13SBarry Smith 227b0a32e0cSBarry Smith ierr = PetscNew(Mat_Shell,&b);CHKERRQ(ierr); 228b0a32e0cSBarry Smith PetscLogObjectMemory(A,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 229273d9f13SBarry Smith ierr = PetscMemzero(b,sizeof(Mat_Shell));CHKERRQ(ierr); 230273d9f13SBarry Smith A->data = (void*)b; 231273d9f13SBarry Smith 232273d9f13SBarry Smith if (A->m == PETSC_DECIDE || A->n == PETSC_DECIDE) { 233273d9f13SBarry Smith SETERRQ(1,"Must give local row and column count for matrix"); 234273d9f13SBarry Smith } 235273d9f13SBarry Smith 236273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->m,&A->M);CHKERRQ(ierr); 237273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->n,&A->N);CHKERRQ(ierr); 238273d9f13SBarry Smith 2398a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->m,A->M,&A->rmap);CHKERRQ(ierr); 2408a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->n,A->N,&A->cmap);CHKERRQ(ierr); 241273d9f13SBarry Smith 242273d9f13SBarry Smith b->ctx = 0; 243ef66eb69SBarry Smith b->scale = PETSC_FALSE; 244ef66eb69SBarry Smith b->shift = PETSC_FALSE; 245ef66eb69SBarry Smith b->vshift = 0.0; 246ef66eb69SBarry Smith b->vscale = 1.0; 247ef66eb69SBarry Smith b->mult = 0; 248273d9f13SBarry Smith A->assembled = PETSC_TRUE; 249273d9f13SBarry Smith A->preallocated = PETSC_TRUE; 250273d9f13SBarry Smith PetscFunctionReturn(0); 251273d9f13SBarry Smith } 252273d9f13SBarry Smith EXTERN_C_END 253e51e0e81SBarry Smith 254711e205bSSatish Balay #undef __FUNCT__ 255711e205bSSatish Balay #define __FUNCT__ "MatCreateShell" 2564b828684SBarry Smith /*@C 257052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 258ff756334SLois Curfman McInnes private data storage format. 259e51e0e81SBarry Smith 260c7fcc2eaSBarry Smith Collective on MPI_Comm 261c7fcc2eaSBarry Smith 262e51e0e81SBarry Smith Input Parameters: 263c7fcc2eaSBarry Smith + comm - MPI communicator 264c7fcc2eaSBarry Smith . m - number of local rows (must be given) 265c7fcc2eaSBarry Smith . n - number of local columns (must be given) 266c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 267c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 268c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 269e51e0e81SBarry Smith 270ff756334SLois Curfman McInnes Output Parameter: 27144cd7ae7SLois Curfman McInnes . A - the matrix 272e51e0e81SBarry Smith 273ff2fd236SBarry Smith Level: advanced 274ff2fd236SBarry Smith 275f39d1f56SLois Curfman McInnes Usage: 2767b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 277f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 278*c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 279f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 280f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 281f39d1f56SLois Curfman McInnes 282ff756334SLois Curfman McInnes Notes: 283ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 284ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 285ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 286e51e0e81SBarry Smith 287f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 288f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 289645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 290645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 291645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 292645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 293645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 294645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 295645985a0SLois Curfman McInnes For example, 296f39d1f56SLois Curfman McInnes 297f39d1f56SLois Curfman McInnes $ 298f39d1f56SLois Curfman McInnes $ Vec x, y 2997b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 300645985a0SLois Curfman McInnes $ Mat A 301f39d1f56SLois Curfman McInnes $ 302c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 303c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 304f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 305c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 306c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 307*c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 308645985a0SLois Curfman McInnes $ MatMult(A,x,y); 309645985a0SLois Curfman McInnes $ MatDestroy(A); 310f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 311645985a0SLois Curfman McInnes $ 312e51e0e81SBarry Smith 3130b627109SLois Curfman McInnes .keywords: matrix, shell, create 3140b627109SLois Curfman McInnes 3153a3eedf2SBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext() 316e51e0e81SBarry Smith @*/ 317f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A) 318e51e0e81SBarry Smith { 319c7fcc2eaSBarry Smith int ierr; 320ed3cc1f0SBarry Smith 3213a40ed3dSBarry Smith PetscFunctionBegin; 322273d9f13SBarry Smith ierr = MatCreate(comm,m,n,M,N,A);CHKERRQ(ierr); 323273d9f13SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 324273d9f13SBarry Smith ierr = MatShellSetContext(*A,ctx);CHKERRQ(ierr); 325273d9f13SBarry Smith PetscFunctionReturn(0); 326c7fcc2eaSBarry Smith } 327c7fcc2eaSBarry Smith 328711e205bSSatish Balay #undef __FUNCT__ 329711e205bSSatish Balay #define __FUNCT__ "MatShellSetContext" 330273d9f13SBarry Smith /*@C 331273d9f13SBarry Smith MatShellSetContext - sets the context for a shell matrix 332c7fcc2eaSBarry Smith 333273d9f13SBarry Smith Collective on Mat 334c7fcc2eaSBarry Smith 335273d9f13SBarry Smith Input Parameters: 336273d9f13SBarry Smith + mat - the shell matrix 337273d9f13SBarry Smith - ctx - the context 338273d9f13SBarry Smith 339273d9f13SBarry Smith Level: advanced 340273d9f13SBarry Smith 341273d9f13SBarry Smith 342273d9f13SBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 343273d9f13SBarry Smith @*/ 344273d9f13SBarry Smith int MatShellSetContext(Mat mat,void *ctx) 345273d9f13SBarry Smith { 346273d9f13SBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 347273d9f13SBarry Smith int ierr; 348273d9f13SBarry Smith PetscTruth flg; 349273d9f13SBarry Smith 350273d9f13SBarry Smith PetscFunctionBegin; 351273d9f13SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 352273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 353273d9f13SBarry Smith if (flg) { 354273d9f13SBarry Smith shell->ctx = ctx; 355273d9f13SBarry Smith } 3563a40ed3dSBarry Smith PetscFunctionReturn(0); 357e51e0e81SBarry Smith } 358e51e0e81SBarry Smith 359711e205bSSatish Balay #undef __FUNCT__ 360711e205bSSatish Balay #define __FUNCT__ "MatShellSetOperation" 361c16cb8f2SBarry Smith /*@C 3623a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 3633a3eedf2SBarry Smith a shell matrix. 364e51e0e81SBarry Smith 365fee21e36SBarry Smith Collective on Mat 366fee21e36SBarry Smith 367c7fcc2eaSBarry Smith Input Parameters: 368c7fcc2eaSBarry Smith + mat - the shell matrix 369c7fcc2eaSBarry Smith . op - the name of the operation 370c7fcc2eaSBarry Smith - f - the function that provides the operation. 371c7fcc2eaSBarry Smith 37215091d37SBarry Smith Level: advanced 37315091d37SBarry Smith 374fae171e0SBarry Smith Usage: 375a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 376f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 377*c134de8dSSatish Balay $ ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 3780b627109SLois Curfman McInnes 379a62d957aSLois Curfman McInnes Notes: 380e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 3811c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 382a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 3831c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 384a62d957aSLois Curfman McInnes 385a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 386deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 387deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 388deebb3c3SLois Curfman McInnes routines, e.g., 389a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 390a62d957aSLois Curfman McInnes 391a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 392a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 393a62d957aSLois Curfman McInnes set by MatCreateShell(). 394a62d957aSLois Curfman McInnes 395a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 396a62d957aSLois Curfman McInnes 397d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 398e51e0e81SBarry Smith @*/ 399*c134de8dSSatish Balay int MatShellSetOperation(Mat mat,MatOperation op,void (*f)(void)) 400e51e0e81SBarry Smith { 401273d9f13SBarry Smith int ierr; 402273d9f13SBarry Smith PetscTruth flg; 403273d9f13SBarry Smith 4043a40ed3dSBarry Smith PetscFunctionBegin; 40577c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 4061c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 407273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 408273d9f13SBarry Smith if (flg) { 409a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 4103a3eedf2SBarry Smith shell->destroy = (int (*)(Mat)) f; 4110c0c84c0SBarry Smith } else mat->ops->destroy = (int (*)(Mat)) f; 412a62d957aSLois Curfman McInnes } 413b0a32e0cSBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (int (*)(Mat,PetscViewer)) f; 414*c134de8dSSatish Balay else (((void(**)(void))mat->ops)[op]) = f; 415a62d957aSLois Curfman McInnes 4163a40ed3dSBarry Smith PetscFunctionReturn(0); 417e51e0e81SBarry Smith } 418f0479e8cSBarry Smith 419711e205bSSatish Balay #undef __FUNCT__ 420711e205bSSatish Balay #define __FUNCT__ "MatShellGetOperation" 421d4bb536fSBarry Smith /*@C 422d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 423d4bb536fSBarry Smith 424c7fcc2eaSBarry Smith Not Collective 425c7fcc2eaSBarry Smith 426d4bb536fSBarry Smith Input Parameters: 427c7fcc2eaSBarry Smith + mat - the shell matrix 428c7fcc2eaSBarry Smith - op - the name of the operation 429d4bb536fSBarry Smith 430d4bb536fSBarry Smith Output Parameter: 431d4bb536fSBarry Smith . f - the function that provides the operation. 432d4bb536fSBarry Smith 43315091d37SBarry Smith Level: advanced 43415091d37SBarry Smith 435d4bb536fSBarry Smith Notes: 436e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 437d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 438d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 439d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 440d4bb536fSBarry Smith 441d4bb536fSBarry Smith All user-provided functions have the same calling 442d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 443d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 444d4bb536fSBarry Smith routines, e.g., 445d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 446d4bb536fSBarry Smith 447d4bb536fSBarry Smith Within each user-defined routine, the user should call 448d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 449d4bb536fSBarry Smith set by MatCreateShell(). 450d4bb536fSBarry Smith 451d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 452d4bb536fSBarry Smith 453d4bb536fSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation() 454d4bb536fSBarry Smith @*/ 455*c134de8dSSatish Balay int MatShellGetOperation(Mat mat,MatOperation op,void(**f)(void)) 456d4bb536fSBarry Smith { 457273d9f13SBarry Smith int ierr; 458273d9f13SBarry Smith PetscTruth flg; 459273d9f13SBarry Smith 4603a40ed3dSBarry Smith PetscFunctionBegin; 461d4bb536fSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 462d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 463273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 464273d9f13SBarry Smith if (flg) { 465d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 466*c134de8dSSatish Balay *f = (void(*)(void))shell->destroy; 467c7fcc2eaSBarry Smith } else { 468*c134de8dSSatish Balay *f = (void(*)(void))mat->ops->destroy; 469d4bb536fSBarry Smith } 470c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 471*c134de8dSSatish Balay *f = (void(*)(void))mat->ops->view; 472c7fcc2eaSBarry Smith } else { 473*c134de8dSSatish Balay *f = (((void(**)(void))mat->ops)[op]); 474d4bb536fSBarry Smith } 475d4bb536fSBarry Smith 4763a40ed3dSBarry Smith PetscFunctionReturn(0); 477d4bb536fSBarry Smith } 478d4bb536fSBarry Smith 479