1be1d678aSKris Buschelman #define PETSCMAT_DLL 2be1d678aSKris Buschelman 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*/ 101d8d5f9aSSatish Balay #include "private/vecimpl.h" 11e51e0e81SBarry Smith 1220563c6bSBarry Smith typedef struct { 136849ba73SBarry Smith PetscErrorCode (*destroy)(Mat); 146849ba73SBarry Smith PetscErrorCode (*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 @*/ 43be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellGetContext(Mat mat,void **ctx) 44b4fd4287SBarry Smith { 45dfbe8321SBarry Smith PetscErrorCode ierr; 46273d9f13SBarry Smith PetscTruth flg; 47273d9f13SBarry Smith 483a40ed3dSBarry Smith PetscFunctionBegin; 494482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 504482741eSBarry Smith PetscValidPointer(ctx,2); 51273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 52273d9f13SBarry Smith if (!flg) *ctx = 0; 53b4fd4287SBarry Smith else *ctx = ((Mat_Shell*)(mat->data))->ctx; 543a40ed3dSBarry Smith PetscFunctionReturn(0); 55b4fd4287SBarry Smith } 56b4fd4287SBarry Smith 57711e205bSSatish Balay #undef __FUNCT__ 58711e205bSSatish Balay #define __FUNCT__ "MatDestroy_Shell" 59dfbe8321SBarry Smith PetscErrorCode MatDestroy_Shell(Mat mat) 60e51e0e81SBarry Smith { 61dfbe8321SBarry Smith PetscErrorCode ierr; 6288cf3e7dSBarry Smith Mat_Shell *shell; 63ed3cc1f0SBarry Smith 643a40ed3dSBarry Smith PetscFunctionBegin; 6588cf3e7dSBarry Smith shell = (Mat_Shell*)mat->data; 663a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 67606d414cSSatish Balay ierr = PetscFree(shell);CHKERRQ(ierr); 683a40ed3dSBarry Smith PetscFunctionReturn(0); 69e51e0e81SBarry Smith } 70e51e0e81SBarry Smith 71711e205bSSatish Balay #undef __FUNCT__ 72ef66eb69SBarry Smith #define __FUNCT__ "MatMult_Shell" 73dfbe8321SBarry Smith PetscErrorCode MatMult_Shell(Mat A,Vec x,Vec y) 74ef66eb69SBarry Smith { 75ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)A->data; 76dfbe8321SBarry Smith PetscErrorCode ierr; 77ef66eb69SBarry Smith 78ef66eb69SBarry Smith PetscFunctionBegin; 79ef66eb69SBarry Smith ierr = (*shell->mult)(A,x,y);CHKERRQ(ierr); 80ef66eb69SBarry Smith if (shell->shift && shell->scale) { 812dcb1b2aSMatthew Knepley ierr = VecAXPBY(y,shell->vshift,shell->vscale,x);CHKERRQ(ierr); 82ef66eb69SBarry Smith } else if (shell->scale) { 832dcb1b2aSMatthew Knepley ierr = VecScale(y,shell->vscale);CHKERRQ(ierr); 84ef66eb69SBarry Smith } else { 852dcb1b2aSMatthew Knepley ierr = VecAXPY(y,shell->vshift,x);CHKERRQ(ierr); 86ef66eb69SBarry Smith } 87ef66eb69SBarry Smith PetscFunctionReturn(0); 88ef66eb69SBarry Smith } 89ef66eb69SBarry Smith 90ef66eb69SBarry Smith #undef __FUNCT__ 91ef66eb69SBarry Smith #define __FUNCT__ "MatShift_Shell" 92f4df32b1SMatthew Knepley PetscErrorCode MatShift_Shell(Mat Y,PetscScalar a) 93ef66eb69SBarry Smith { 94ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 95b24ad042SBarry Smith 96ef66eb69SBarry Smith PetscFunctionBegin; 97ef66eb69SBarry Smith if (shell->scale || shell->shift) { 98f4df32b1SMatthew Knepley shell->vshift += a; 99ef66eb69SBarry Smith } else { 100ef66eb69SBarry Smith shell->mult = Y->ops->mult; 101ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 102f4df32b1SMatthew Knepley shell->vshift = a; 103ef66eb69SBarry Smith } 104ef66eb69SBarry Smith shell->shift = PETSC_TRUE; 105ef66eb69SBarry Smith PetscFunctionReturn(0); 106ef66eb69SBarry Smith } 107ef66eb69SBarry Smith 108ef66eb69SBarry Smith #undef __FUNCT__ 109ef66eb69SBarry Smith #define __FUNCT__ "MatScale_Shell" 110f4df32b1SMatthew Knepley PetscErrorCode MatScale_Shell(Mat Y,PetscScalar a) 111ef66eb69SBarry Smith { 112ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 113b24ad042SBarry Smith 114ef66eb69SBarry Smith PetscFunctionBegin; 115ef66eb69SBarry Smith if (shell->scale || shell->shift) { 116f4df32b1SMatthew Knepley shell->vscale *= a; 117ef66eb69SBarry Smith } else { 118ef66eb69SBarry Smith shell->mult = Y->ops->mult; 119ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 120f4df32b1SMatthew Knepley shell->vscale = a; 121ef66eb69SBarry Smith } 122ef66eb69SBarry Smith shell->scale = PETSC_TRUE; 123ef66eb69SBarry Smith PetscFunctionReturn(0); 124ef66eb69SBarry Smith } 125ef66eb69SBarry Smith 126ef66eb69SBarry Smith #undef __FUNCT__ 127ef66eb69SBarry Smith #define __FUNCT__ "MatAssemblyEnd_Shell" 128dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Shell(Mat Y,MatAssemblyType t) 129ef66eb69SBarry Smith { 130ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 131ef66eb69SBarry Smith 132ef66eb69SBarry Smith PetscFunctionBegin; 133ef66eb69SBarry Smith if ((shell->shift || shell->scale) && t == MAT_FINAL_ASSEMBLY) { 134ef66eb69SBarry Smith shell->scale = PETSC_FALSE; 135ef66eb69SBarry Smith shell->shift = PETSC_FALSE; 136ef66eb69SBarry Smith shell->vshift = 0.0; 137ef66eb69SBarry Smith shell->vscale = 1.0; 138ef66eb69SBarry Smith Y->ops->mult = shell->mult; 139ef66eb69SBarry Smith } 140ef66eb69SBarry Smith PetscFunctionReturn(0); 141ef66eb69SBarry Smith } 142ef66eb69SBarry Smith 143f69a0ea3SMatthew Knepley EXTERN PetscErrorCode MatConvert_Shell(Mat, MatType,MatReuse,Mat*); 144b951964fSBarry Smith 145521d7252SBarry Smith #undef __FUNCT__ 146521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_Shell" 147521d7252SBarry Smith PetscErrorCode MatSetBlockSize_Shell(Mat A,PetscInt bs) 148521d7252SBarry Smith { 149521d7252SBarry Smith PetscFunctionBegin; 150521d7252SBarry Smith PetscFunctionReturn(0); 151521d7252SBarry Smith } 152521d7252SBarry Smith 15309dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 15420563c6bSBarry Smith 0, 15520563c6bSBarry Smith 0, 15620563c6bSBarry Smith 0, 15797304618SKris Buschelman /* 4*/ 0, 15820563c6bSBarry Smith 0, 159b951964fSBarry Smith 0, 160b951964fSBarry Smith 0, 161b951964fSBarry Smith 0, 162b951964fSBarry Smith 0, 16397304618SKris Buschelman /*10*/ 0, 164b951964fSBarry Smith 0, 165b951964fSBarry Smith 0, 166b951964fSBarry Smith 0, 167b951964fSBarry Smith 0, 16897304618SKris Buschelman /*15*/ 0, 169b951964fSBarry Smith 0, 170b951964fSBarry Smith 0, 171b951964fSBarry Smith 0, 172b951964fSBarry Smith 0, 17397304618SKris Buschelman /*20*/ 0, 174ef66eb69SBarry Smith MatAssemblyEnd_Shell, 175b951964fSBarry Smith 0, 176b951964fSBarry Smith 0, 177b951964fSBarry Smith 0, 17897304618SKris Buschelman /*25*/ 0, 179b951964fSBarry Smith 0, 180b951964fSBarry Smith 0, 181b951964fSBarry Smith 0, 182b951964fSBarry Smith 0, 18397304618SKris Buschelman /*30*/ 0, 184b951964fSBarry Smith 0, 185273d9f13SBarry Smith 0, 186b951964fSBarry Smith 0, 187b951964fSBarry Smith 0, 18897304618SKris Buschelman /*35*/ 0, 189b951964fSBarry Smith 0, 190b951964fSBarry Smith 0, 19109dc0095SBarry Smith 0, 19209dc0095SBarry Smith 0, 19397304618SKris Buschelman /*40*/ 0, 19409dc0095SBarry Smith 0, 19509dc0095SBarry Smith 0, 19609dc0095SBarry Smith 0, 19709dc0095SBarry Smith 0, 19897304618SKris Buschelman /*45*/ 0, 199ef66eb69SBarry Smith MatScale_Shell, 200ef66eb69SBarry Smith MatShift_Shell, 20109dc0095SBarry Smith 0, 20209dc0095SBarry Smith 0, 203521d7252SBarry Smith /*50*/ MatSetBlockSize_Shell, 20409dc0095SBarry Smith 0, 20509dc0095SBarry Smith 0, 20609dc0095SBarry Smith 0, 20709dc0095SBarry Smith 0, 20897304618SKris Buschelman /*55*/ 0, 20909dc0095SBarry Smith 0, 21009dc0095SBarry Smith 0, 21109dc0095SBarry Smith 0, 21209dc0095SBarry Smith 0, 21397304618SKris Buschelman /*60*/ 0, 214b9b97703SBarry Smith MatDestroy_Shell, 21509dc0095SBarry Smith 0, 2168a124369SBarry Smith MatGetPetscMaps_Petsc, 217273d9f13SBarry Smith 0, 21897304618SKris Buschelman /*65*/ 0, 219273d9f13SBarry Smith 0, 220273d9f13SBarry Smith 0, 221273d9f13SBarry Smith 0, 222273d9f13SBarry Smith 0, 22397304618SKris Buschelman /*70*/ 0, 22497304618SKris Buschelman MatConvert_Shell, 225273d9f13SBarry Smith 0, 226273d9f13SBarry Smith 0, 22797304618SKris Buschelman 0, 22897304618SKris Buschelman /*75*/ 0, 22997304618SKris Buschelman 0, 23097304618SKris Buschelman 0, 23197304618SKris Buschelman 0, 23297304618SKris Buschelman 0, 23397304618SKris Buschelman /*80*/ 0, 23497304618SKris Buschelman 0, 23597304618SKris Buschelman 0, 23697304618SKris Buschelman 0, 237865e5f61SKris Buschelman 0, 238865e5f61SKris Buschelman /*85*/ 0, 239865e5f61SKris Buschelman 0, 240865e5f61SKris Buschelman 0, 241865e5f61SKris Buschelman 0, 242865e5f61SKris Buschelman 0, 243865e5f61SKris Buschelman /*90*/ 0, 244865e5f61SKris Buschelman 0, 245865e5f61SKris Buschelman 0, 246865e5f61SKris Buschelman 0, 247865e5f61SKris Buschelman 0, 248865e5f61SKris Buschelman /*95*/ 0, 249865e5f61SKris Buschelman 0, 250865e5f61SKris Buschelman 0, 251865e5f61SKris Buschelman 0}; 252273d9f13SBarry Smith 2530bad9183SKris Buschelman /*MC 254fafad747SKris Buschelman MATSHELL - MATSHELL = "shell" - A matrix type to be used to define your own matrix type -- perhaps matrix free. 2550bad9183SKris Buschelman 2560bad9183SKris Buschelman Level: advanced 2570bad9183SKris Buschelman 2580bad9183SKris Buschelman .seealso: MatCreateShell 2590bad9183SKris Buschelman M*/ 2600bad9183SKris Buschelman 261273d9f13SBarry Smith EXTERN_C_BEGIN 262711e205bSSatish Balay #undef __FUNCT__ 263711e205bSSatish Balay #define __FUNCT__ "MatCreate_Shell" 264be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Shell(Mat A) 265273d9f13SBarry Smith { 266273d9f13SBarry Smith Mat_Shell *b; 267dfbe8321SBarry Smith PetscErrorCode ierr; 268273d9f13SBarry Smith 269273d9f13SBarry Smith PetscFunctionBegin; 270273d9f13SBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 271273d9f13SBarry Smith 272b0a32e0cSBarry Smith ierr = PetscNew(Mat_Shell,&b);CHKERRQ(ierr); 27352e6d16bSBarry Smith ierr = PetscLogObjectMemory(A,sizeof(struct _p_Mat)+sizeof(Mat_Shell));CHKERRQ(ierr); 274273d9f13SBarry Smith A->data = (void*)b; 275273d9f13SBarry Smith 276273d9f13SBarry Smith if (A->m == PETSC_DECIDE || A->n == PETSC_DECIDE) { 277e005ede5SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Must give local row and column count for matrix"); 278273d9f13SBarry Smith } 279273d9f13SBarry Smith 280273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->m,&A->M);CHKERRQ(ierr); 281273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->n,&A->N);CHKERRQ(ierr); 282273d9f13SBarry Smith 2838a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->m,A->M,&A->rmap);CHKERRQ(ierr); 2848a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->n,A->N,&A->cmap);CHKERRQ(ierr); 285273d9f13SBarry Smith 286273d9f13SBarry Smith b->ctx = 0; 287ef66eb69SBarry Smith b->scale = PETSC_FALSE; 288ef66eb69SBarry Smith b->shift = PETSC_FALSE; 289ef66eb69SBarry Smith b->vshift = 0.0; 290ef66eb69SBarry Smith b->vscale = 1.0; 291ef66eb69SBarry Smith b->mult = 0; 292273d9f13SBarry Smith A->assembled = PETSC_TRUE; 293273d9f13SBarry Smith A->preallocated = PETSC_TRUE; 294273d9f13SBarry Smith PetscFunctionReturn(0); 295273d9f13SBarry Smith } 296273d9f13SBarry Smith EXTERN_C_END 297e51e0e81SBarry Smith 298711e205bSSatish Balay #undef __FUNCT__ 299711e205bSSatish Balay #define __FUNCT__ "MatCreateShell" 3004b828684SBarry Smith /*@C 301052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 302ff756334SLois Curfman McInnes private data storage format. 303e51e0e81SBarry Smith 304c7fcc2eaSBarry Smith Collective on MPI_Comm 305c7fcc2eaSBarry Smith 306e51e0e81SBarry Smith Input Parameters: 307c7fcc2eaSBarry Smith + comm - MPI communicator 308c7fcc2eaSBarry Smith . m - number of local rows (must be given) 309c7fcc2eaSBarry Smith . n - number of local columns (must be given) 310c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 311c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 312c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 313e51e0e81SBarry Smith 314ff756334SLois Curfman McInnes Output Parameter: 31544cd7ae7SLois Curfman McInnes . A - the matrix 316e51e0e81SBarry Smith 317ff2fd236SBarry Smith Level: advanced 318ff2fd236SBarry Smith 319f39d1f56SLois Curfman McInnes Usage: 3207b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 321f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 322c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 323f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 324f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 325f39d1f56SLois Curfman McInnes 326ff756334SLois Curfman McInnes Notes: 327ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 328ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 329ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 330e51e0e81SBarry Smith 331f38a8d56SBarry Smith Fortran Notes: The context can only be an integer or a PetscObject 332f38a8d56SBarry Smith unfortunately it cannot be a Fortran array or derived type. 333f38a8d56SBarry Smith 334f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 335f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 336645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 337645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 338645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 339645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 340645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 341645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 342645985a0SLois Curfman McInnes For example, 343f39d1f56SLois Curfman McInnes 344f39d1f56SLois Curfman McInnes $ 345f39d1f56SLois Curfman McInnes $ Vec x, y 3467b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 347645985a0SLois Curfman McInnes $ Mat A 348f39d1f56SLois Curfman McInnes $ 349c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 350c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 351f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 352c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 353c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 354c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 355645985a0SLois Curfman McInnes $ MatMult(A,x,y); 356645985a0SLois Curfman McInnes $ MatDestroy(A); 357f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 358645985a0SLois Curfman McInnes $ 359e51e0e81SBarry Smith 3600b627109SLois Curfman McInnes .keywords: matrix, shell, create 3610b627109SLois Curfman McInnes 362ab50ec6bSBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext(), MatShellSetContext() 363e51e0e81SBarry Smith @*/ 364be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateShell(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,void *ctx,Mat *A) 365e51e0e81SBarry Smith { 366dfbe8321SBarry Smith PetscErrorCode ierr; 367ed3cc1f0SBarry Smith 3683a40ed3dSBarry Smith PetscFunctionBegin; 369f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 370f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 371273d9f13SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 372273d9f13SBarry Smith ierr = MatShellSetContext(*A,ctx);CHKERRQ(ierr); 373273d9f13SBarry Smith PetscFunctionReturn(0); 374c7fcc2eaSBarry Smith } 375c7fcc2eaSBarry Smith 376711e205bSSatish Balay #undef __FUNCT__ 377711e205bSSatish Balay #define __FUNCT__ "MatShellSetContext" 37805869f15SSatish Balay /*@ 379273d9f13SBarry Smith MatShellSetContext - sets the context for a shell matrix 380c7fcc2eaSBarry Smith 381273d9f13SBarry Smith Collective on Mat 382c7fcc2eaSBarry Smith 383273d9f13SBarry Smith Input Parameters: 384273d9f13SBarry Smith + mat - the shell matrix 385273d9f13SBarry Smith - ctx - the context 386273d9f13SBarry Smith 387273d9f13SBarry Smith Level: advanced 388273d9f13SBarry Smith 389f38a8d56SBarry Smith Fortran Notes: The context can only be an integer or a PetscObject 390f38a8d56SBarry Smith unfortunately it cannot be a Fortran array or derived type. 391273d9f13SBarry Smith 392273d9f13SBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 393273d9f13SBarry Smith @*/ 394be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellSetContext(Mat mat,void *ctx) 395273d9f13SBarry Smith { 396273d9f13SBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 397dfbe8321SBarry Smith PetscErrorCode ierr; 398273d9f13SBarry Smith PetscTruth flg; 399273d9f13SBarry Smith 400273d9f13SBarry Smith PetscFunctionBegin; 4014482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 402273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 403273d9f13SBarry Smith if (flg) { 404273d9f13SBarry Smith shell->ctx = ctx; 405273d9f13SBarry Smith } 4063a40ed3dSBarry Smith PetscFunctionReturn(0); 407e51e0e81SBarry Smith } 408e51e0e81SBarry Smith 409711e205bSSatish Balay #undef __FUNCT__ 410711e205bSSatish Balay #define __FUNCT__ "MatShellSetOperation" 411c16cb8f2SBarry Smith /*@C 4123a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 4133a3eedf2SBarry Smith a shell matrix. 414e51e0e81SBarry Smith 415fee21e36SBarry Smith Collective on Mat 416fee21e36SBarry Smith 417c7fcc2eaSBarry Smith Input Parameters: 418c7fcc2eaSBarry Smith + mat - the shell matrix 419c7fcc2eaSBarry Smith . op - the name of the operation 420c7fcc2eaSBarry Smith - f - the function that provides the operation. 421c7fcc2eaSBarry Smith 42215091d37SBarry Smith Level: advanced 42315091d37SBarry Smith 424fae171e0SBarry Smith Usage: 425*e93bc3c1Svictor $ extern PetscErrorCode usermult(Mat,Vec,Vec); 426f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 427c134de8dSSatish Balay $ ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 4280b627109SLois Curfman McInnes 429a62d957aSLois Curfman McInnes Notes: 430e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 4311c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 432a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 4331c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 434a62d957aSLois Curfman McInnes 435a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 436deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 437deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 438deebb3c3SLois Curfman McInnes routines, e.g., 439a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 440a62d957aSLois Curfman McInnes 441a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 442a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 443a62d957aSLois Curfman McInnes set by MatCreateShell(). 444a62d957aSLois Curfman McInnes 445a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 446a62d957aSLois Curfman McInnes 447ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellSetContext() 448e51e0e81SBarry Smith @*/ 449be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellSetOperation(Mat mat,MatOperation op,void (*f)(void)) 450e51e0e81SBarry Smith { 451dfbe8321SBarry Smith PetscErrorCode ierr; 452273d9f13SBarry Smith PetscTruth flg; 453273d9f13SBarry Smith 4543a40ed3dSBarry Smith PetscFunctionBegin; 4554482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 4561c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 457273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 458273d9f13SBarry Smith if (flg) { 459a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 4606849ba73SBarry Smith shell->destroy = (PetscErrorCode (*)(Mat)) f; 4616849ba73SBarry Smith } else mat->ops->destroy = (PetscErrorCode (*)(Mat)) f; 462a62d957aSLois Curfman McInnes } 4636849ba73SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (PetscErrorCode (*)(Mat,PetscViewer)) f; 464c134de8dSSatish Balay else (((void(**)(void))mat->ops)[op]) = f; 465a62d957aSLois Curfman McInnes 4663a40ed3dSBarry Smith PetscFunctionReturn(0); 467e51e0e81SBarry Smith } 468f0479e8cSBarry Smith 469711e205bSSatish Balay #undef __FUNCT__ 470711e205bSSatish Balay #define __FUNCT__ "MatShellGetOperation" 471d4bb536fSBarry Smith /*@C 472d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 473d4bb536fSBarry Smith 474c7fcc2eaSBarry Smith Not Collective 475c7fcc2eaSBarry Smith 476d4bb536fSBarry Smith Input Parameters: 477c7fcc2eaSBarry Smith + mat - the shell matrix 478c7fcc2eaSBarry Smith - op - the name of the operation 479d4bb536fSBarry Smith 480d4bb536fSBarry Smith Output Parameter: 481d4bb536fSBarry Smith . f - the function that provides the operation. 482d4bb536fSBarry Smith 48315091d37SBarry Smith Level: advanced 48415091d37SBarry Smith 485d4bb536fSBarry Smith Notes: 486e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 487d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 488d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 489d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 490d4bb536fSBarry Smith 491d4bb536fSBarry Smith All user-provided functions have the same calling 492d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 493d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 494d4bb536fSBarry Smith routines, e.g., 495d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 496d4bb536fSBarry Smith 497d4bb536fSBarry Smith Within each user-defined routine, the user should call 498d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 499d4bb536fSBarry Smith set by MatCreateShell(). 500d4bb536fSBarry Smith 501d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 502d4bb536fSBarry Smith 503ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation(), MatShellSetContext() 504d4bb536fSBarry Smith @*/ 505be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellGetOperation(Mat mat,MatOperation op,void(**f)(void)) 506d4bb536fSBarry Smith { 507dfbe8321SBarry Smith PetscErrorCode ierr; 508273d9f13SBarry Smith PetscTruth flg; 509273d9f13SBarry Smith 5103a40ed3dSBarry Smith PetscFunctionBegin; 5114482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 512d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 513273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 514273d9f13SBarry Smith if (flg) { 515d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 516c134de8dSSatish Balay *f = (void(*)(void))shell->destroy; 517c7fcc2eaSBarry Smith } else { 518c134de8dSSatish Balay *f = (void(*)(void))mat->ops->destroy; 519d4bb536fSBarry Smith } 520c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 521c134de8dSSatish Balay *f = (void(*)(void))mat->ops->view; 522c7fcc2eaSBarry Smith } else { 523c134de8dSSatish Balay *f = (((void(**)(void))mat->ops)[op]); 524d4bb536fSBarry Smith } 525d4bb536fSBarry Smith 5263a40ed3dSBarry Smith PetscFunctionReturn(0); 527d4bb536fSBarry Smith } 528d4bb536fSBarry Smith 529