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 41ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellSetOperation(), MatShellSetContext() 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" 91*268466fbSBarry Smith int MatShift_Shell(const 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" 108*268466fbSBarry Smith int MatScale_Shell(const 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, 188ef66eb69SBarry Smith MatScale_Shell, 189ef66eb69SBarry Smith MatShift_Shell, 19009dc0095SBarry 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, 202273d9f13SBarry Smith 0, 203b9b97703SBarry Smith MatDestroy_Shell, 20409dc0095SBarry Smith 0, 2058a124369SBarry Smith MatGetPetscMaps_Petsc, 206273d9f13SBarry Smith 0, 207273d9f13SBarry Smith 0, 208273d9f13SBarry Smith 0, 209273d9f13SBarry Smith 0, 210273d9f13SBarry Smith 0, 211273d9f13SBarry Smith 0, 212273d9f13SBarry Smith 0, 213273d9f13SBarry Smith MatConvert_Shell}; 214273d9f13SBarry Smith 215273d9f13SBarry Smith EXTERN_C_BEGIN 216711e205bSSatish Balay #undef __FUNCT__ 217711e205bSSatish Balay #define __FUNCT__ "MatCreate_Shell" 218273d9f13SBarry Smith int MatCreate_Shell(Mat A) 219273d9f13SBarry Smith { 220273d9f13SBarry Smith Mat_Shell *b; 221273d9f13SBarry Smith int ierr; 222273d9f13SBarry Smith 223273d9f13SBarry Smith PetscFunctionBegin; 224273d9f13SBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 225273d9f13SBarry Smith 226b0a32e0cSBarry Smith ierr = PetscNew(Mat_Shell,&b);CHKERRQ(ierr); 227b0a32e0cSBarry Smith PetscLogObjectMemory(A,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 228273d9f13SBarry Smith ierr = PetscMemzero(b,sizeof(Mat_Shell));CHKERRQ(ierr); 229273d9f13SBarry Smith A->data = (void*)b; 230273d9f13SBarry Smith 231273d9f13SBarry Smith if (A->m == PETSC_DECIDE || A->n == PETSC_DECIDE) { 232273d9f13SBarry Smith SETERRQ(1,"Must give local row and column count for matrix"); 233273d9f13SBarry Smith } 234273d9f13SBarry Smith 235273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->m,&A->M);CHKERRQ(ierr); 236273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->n,&A->N);CHKERRQ(ierr); 237273d9f13SBarry Smith 2388a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->m,A->M,&A->rmap);CHKERRQ(ierr); 2398a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->n,A->N,&A->cmap);CHKERRQ(ierr); 240273d9f13SBarry Smith 241273d9f13SBarry Smith b->ctx = 0; 242ef66eb69SBarry Smith b->scale = PETSC_FALSE; 243ef66eb69SBarry Smith b->shift = PETSC_FALSE; 244ef66eb69SBarry Smith b->vshift = 0.0; 245ef66eb69SBarry Smith b->vscale = 1.0; 246ef66eb69SBarry Smith b->mult = 0; 247273d9f13SBarry Smith A->assembled = PETSC_TRUE; 248273d9f13SBarry Smith A->preallocated = PETSC_TRUE; 249273d9f13SBarry Smith PetscFunctionReturn(0); 250273d9f13SBarry Smith } 251273d9f13SBarry Smith EXTERN_C_END 252e51e0e81SBarry Smith 253711e205bSSatish Balay #undef __FUNCT__ 254711e205bSSatish Balay #define __FUNCT__ "MatCreateShell" 2554b828684SBarry Smith /*@C 256052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 257ff756334SLois Curfman McInnes private data storage format. 258e51e0e81SBarry Smith 259c7fcc2eaSBarry Smith Collective on MPI_Comm 260c7fcc2eaSBarry Smith 261e51e0e81SBarry Smith Input Parameters: 262c7fcc2eaSBarry Smith + comm - MPI communicator 263c7fcc2eaSBarry Smith . m - number of local rows (must be given) 264c7fcc2eaSBarry Smith . n - number of local columns (must be given) 265c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 266c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 267c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 268e51e0e81SBarry Smith 269ff756334SLois Curfman McInnes Output Parameter: 27044cd7ae7SLois Curfman McInnes . A - the matrix 271e51e0e81SBarry Smith 272ff2fd236SBarry Smith Level: advanced 273ff2fd236SBarry Smith 274f39d1f56SLois Curfman McInnes Usage: 2757b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 276f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 277c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 278f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 279f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 280f39d1f56SLois Curfman McInnes 281ff756334SLois Curfman McInnes Notes: 282ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 283ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 284ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 285e51e0e81SBarry Smith 286f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 287f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 288645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 289645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 290645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 291645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 292645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 293645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 294645985a0SLois Curfman McInnes For example, 295f39d1f56SLois Curfman McInnes 296f39d1f56SLois Curfman McInnes $ 297f39d1f56SLois Curfman McInnes $ Vec x, y 2987b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 299645985a0SLois Curfman McInnes $ Mat A 300f39d1f56SLois Curfman McInnes $ 301c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 302c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 303f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 304c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 305c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 306c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 307645985a0SLois Curfman McInnes $ MatMult(A,x,y); 308645985a0SLois Curfman McInnes $ MatDestroy(A); 309f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 310645985a0SLois Curfman McInnes $ 311e51e0e81SBarry Smith 3120b627109SLois Curfman McInnes .keywords: matrix, shell, create 3130b627109SLois Curfman McInnes 314ab50ec6bSBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext(), MatShellSetContext() 315e51e0e81SBarry Smith @*/ 316f39d1f56SLois Curfman McInnes int MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A) 317e51e0e81SBarry Smith { 318c7fcc2eaSBarry Smith int ierr; 319ed3cc1f0SBarry Smith 3203a40ed3dSBarry Smith PetscFunctionBegin; 321273d9f13SBarry Smith ierr = MatCreate(comm,m,n,M,N,A);CHKERRQ(ierr); 322273d9f13SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 323273d9f13SBarry Smith ierr = MatShellSetContext(*A,ctx);CHKERRQ(ierr); 324273d9f13SBarry Smith PetscFunctionReturn(0); 325c7fcc2eaSBarry Smith } 326c7fcc2eaSBarry Smith 327711e205bSSatish Balay #undef __FUNCT__ 328711e205bSSatish Balay #define __FUNCT__ "MatShellSetContext" 329273d9f13SBarry Smith /*@C 330273d9f13SBarry Smith MatShellSetContext - sets the context for a shell matrix 331c7fcc2eaSBarry Smith 332273d9f13SBarry Smith Collective on Mat 333c7fcc2eaSBarry Smith 334273d9f13SBarry Smith Input Parameters: 335273d9f13SBarry Smith + mat - the shell matrix 336273d9f13SBarry Smith - ctx - the context 337273d9f13SBarry Smith 338273d9f13SBarry Smith Level: advanced 339273d9f13SBarry Smith 340273d9f13SBarry Smith 341273d9f13SBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 342273d9f13SBarry Smith @*/ 343273d9f13SBarry Smith int MatShellSetContext(Mat mat,void *ctx) 344273d9f13SBarry Smith { 345273d9f13SBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 346273d9f13SBarry Smith int ierr; 347273d9f13SBarry Smith PetscTruth flg; 348273d9f13SBarry Smith 349273d9f13SBarry Smith PetscFunctionBegin; 350273d9f13SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 351273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 352273d9f13SBarry Smith if (flg) { 353273d9f13SBarry Smith shell->ctx = ctx; 354273d9f13SBarry Smith } 3553a40ed3dSBarry Smith PetscFunctionReturn(0); 356e51e0e81SBarry Smith } 357e51e0e81SBarry Smith 358711e205bSSatish Balay #undef __FUNCT__ 359711e205bSSatish Balay #define __FUNCT__ "MatShellSetOperation" 360c16cb8f2SBarry Smith /*@C 3613a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 3623a3eedf2SBarry Smith a shell matrix. 363e51e0e81SBarry Smith 364fee21e36SBarry Smith Collective on Mat 365fee21e36SBarry Smith 366c7fcc2eaSBarry Smith Input Parameters: 367c7fcc2eaSBarry Smith + mat - the shell matrix 368c7fcc2eaSBarry Smith . op - the name of the operation 369c7fcc2eaSBarry Smith - f - the function that provides the operation. 370c7fcc2eaSBarry Smith 37115091d37SBarry Smith Level: advanced 37215091d37SBarry Smith 373fae171e0SBarry Smith Usage: 374a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 375f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 376c134de8dSSatish Balay $ ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 3770b627109SLois Curfman McInnes 378a62d957aSLois Curfman McInnes Notes: 379e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 3801c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 381a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 3821c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 383a62d957aSLois Curfman McInnes 384a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 385deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 386deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 387deebb3c3SLois Curfman McInnes routines, e.g., 388a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 389a62d957aSLois Curfman McInnes 390a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 391a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 392a62d957aSLois Curfman McInnes set by MatCreateShell(). 393a62d957aSLois Curfman McInnes 394a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 395a62d957aSLois Curfman McInnes 396ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellSetContext() 397e51e0e81SBarry Smith @*/ 398c134de8dSSatish Balay int MatShellSetOperation(Mat mat,MatOperation op,void (*f)(void)) 399e51e0e81SBarry Smith { 400273d9f13SBarry Smith int ierr; 401273d9f13SBarry Smith PetscTruth flg; 402273d9f13SBarry Smith 4033a40ed3dSBarry Smith PetscFunctionBegin; 40477c4ece6SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 4051c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 406273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 407273d9f13SBarry Smith if (flg) { 408a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 4093a3eedf2SBarry Smith shell->destroy = (int (*)(Mat)) f; 4100c0c84c0SBarry Smith } else mat->ops->destroy = (int (*)(Mat)) f; 411a62d957aSLois Curfman McInnes } 412b0a32e0cSBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (int (*)(Mat,PetscViewer)) f; 413c134de8dSSatish Balay else (((void(**)(void))mat->ops)[op]) = f; 414a62d957aSLois Curfman McInnes 4153a40ed3dSBarry Smith PetscFunctionReturn(0); 416e51e0e81SBarry Smith } 417f0479e8cSBarry Smith 418711e205bSSatish Balay #undef __FUNCT__ 419711e205bSSatish Balay #define __FUNCT__ "MatShellGetOperation" 420d4bb536fSBarry Smith /*@C 421d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 422d4bb536fSBarry Smith 423c7fcc2eaSBarry Smith Not Collective 424c7fcc2eaSBarry Smith 425d4bb536fSBarry Smith Input Parameters: 426c7fcc2eaSBarry Smith + mat - the shell matrix 427c7fcc2eaSBarry Smith - op - the name of the operation 428d4bb536fSBarry Smith 429d4bb536fSBarry Smith Output Parameter: 430d4bb536fSBarry Smith . f - the function that provides the operation. 431d4bb536fSBarry Smith 43215091d37SBarry Smith Level: advanced 43315091d37SBarry Smith 434d4bb536fSBarry Smith Notes: 435e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 436d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 437d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 438d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 439d4bb536fSBarry Smith 440d4bb536fSBarry Smith All user-provided functions have the same calling 441d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 442d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 443d4bb536fSBarry Smith routines, e.g., 444d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 445d4bb536fSBarry Smith 446d4bb536fSBarry Smith Within each user-defined routine, the user should call 447d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 448d4bb536fSBarry Smith set by MatCreateShell(). 449d4bb536fSBarry Smith 450d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 451d4bb536fSBarry Smith 452ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation(), MatShellSetContext() 453d4bb536fSBarry Smith @*/ 454c134de8dSSatish Balay int MatShellGetOperation(Mat mat,MatOperation op,void(**f)(void)) 455d4bb536fSBarry Smith { 456273d9f13SBarry Smith int ierr; 457273d9f13SBarry Smith PetscTruth flg; 458273d9f13SBarry Smith 4593a40ed3dSBarry Smith PetscFunctionBegin; 460d4bb536fSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 461d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 462273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 463273d9f13SBarry Smith if (flg) { 464d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 465c134de8dSSatish Balay *f = (void(*)(void))shell->destroy; 466c7fcc2eaSBarry Smith } else { 467c134de8dSSatish Balay *f = (void(*)(void))mat->ops->destroy; 468d4bb536fSBarry Smith } 469c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 470c134de8dSSatish Balay *f = (void(*)(void))mat->ops->view; 471c7fcc2eaSBarry Smith } else { 472c134de8dSSatish Balay *f = (((void(**)(void))mat->ops)[op]); 473d4bb536fSBarry Smith } 474d4bb536fSBarry Smith 4753a40ed3dSBarry Smith PetscFunctionReturn(0); 476d4bb536fSBarry Smith } 477d4bb536fSBarry Smith 478