1e51e0e81SBarry Smith /* 220563c6bSBarry Smith This provides a simple shell for Fortran (and C programmers) to 320563c6bSBarry Smith create a very simple matrix class for use with KSP without coding 4ed3cc1f0SBarry Smith much of anything. 5e51e0e81SBarry Smith */ 6e51e0e81SBarry Smith 7e090d566SSatish Balay #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 83c94ec11SBarry Smith #include "vecimpl.h" 9e51e0e81SBarry Smith 1020563c6bSBarry Smith typedef struct { 11*6849ba73SBarry Smith PetscErrorCode (*destroy)(Mat); 12*6849ba73SBarry Smith PetscErrorCode (*mult)(Mat,Vec,Vec); 13ef66eb69SBarry Smith PetscTruth scale,shift; 14ef66eb69SBarry Smith PetscScalar vscale,vshift; 1520563c6bSBarry Smith void *ctx; 1688cf3e7dSBarry Smith } Mat_Shell; 17e51e0e81SBarry Smith 18711e205bSSatish Balay #undef __FUNCT__ 19711e205bSSatish Balay #define __FUNCT__ "MatShellGetContext" 20b4fd4287SBarry Smith /*@ 21a62d957aSLois Curfman McInnes MatShellGetContext - Returns the user-provided context associated with a shell matrix. 22b4fd4287SBarry Smith 23c7fcc2eaSBarry Smith Not Collective 24c7fcc2eaSBarry Smith 25b4fd4287SBarry Smith Input Parameter: 26b4fd4287SBarry Smith . mat - the matrix, should have been created with MatCreateShell() 27b4fd4287SBarry Smith 28b4fd4287SBarry Smith Output Parameter: 29b4fd4287SBarry Smith . ctx - the user provided context 30b4fd4287SBarry Smith 3115091d37SBarry Smith Level: advanced 3215091d37SBarry Smith 33a62d957aSLois Curfman McInnes Notes: 34a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 35a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 36a62d957aSLois Curfman McInnes 37a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 38a62d957aSLois Curfman McInnes 39ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellSetOperation(), MatShellSetContext() 40b4fd4287SBarry Smith @*/ 41dfbe8321SBarry Smith PetscErrorCode MatShellGetContext(Mat mat,void **ctx) 42b4fd4287SBarry Smith { 43dfbe8321SBarry Smith PetscErrorCode ierr; 44273d9f13SBarry Smith PetscTruth flg; 45273d9f13SBarry Smith 463a40ed3dSBarry Smith PetscFunctionBegin; 474482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 484482741eSBarry Smith PetscValidPointer(ctx,2); 49273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 50273d9f13SBarry Smith if (!flg) *ctx = 0; 51b4fd4287SBarry Smith else *ctx = ((Mat_Shell*)(mat->data))->ctx; 523a40ed3dSBarry Smith PetscFunctionReturn(0); 53b4fd4287SBarry Smith } 54b4fd4287SBarry Smith 55711e205bSSatish Balay #undef __FUNCT__ 56711e205bSSatish Balay #define __FUNCT__ "MatDestroy_Shell" 57dfbe8321SBarry Smith PetscErrorCode MatDestroy_Shell(Mat mat) 58e51e0e81SBarry Smith { 59dfbe8321SBarry Smith PetscErrorCode ierr; 6088cf3e7dSBarry Smith Mat_Shell *shell; 61ed3cc1f0SBarry Smith 623a40ed3dSBarry Smith PetscFunctionBegin; 6388cf3e7dSBarry Smith shell = (Mat_Shell*)mat->data; 643a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 65606d414cSSatish Balay ierr = PetscFree(shell);CHKERRQ(ierr); 663a40ed3dSBarry Smith PetscFunctionReturn(0); 67e51e0e81SBarry Smith } 68e51e0e81SBarry Smith 69711e205bSSatish Balay #undef __FUNCT__ 70ef66eb69SBarry Smith #define __FUNCT__ "MatMult_Shell" 71dfbe8321SBarry Smith PetscErrorCode MatMult_Shell(Mat A,Vec x,Vec y) 72ef66eb69SBarry Smith { 73ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)A->data; 74dfbe8321SBarry Smith PetscErrorCode ierr; 75ef66eb69SBarry Smith 76ef66eb69SBarry Smith PetscFunctionBegin; 77ef66eb69SBarry Smith ierr = (*shell->mult)(A,x,y);CHKERRQ(ierr); 78ef66eb69SBarry Smith if (shell->shift && shell->scale) { 79ef66eb69SBarry Smith ierr = VecAXPBY(&shell->vshift,&shell->vscale,x,y);CHKERRQ(ierr); 80ef66eb69SBarry Smith } else if (shell->scale) { 81ef66eb69SBarry Smith ierr = VecScale(&shell->vscale,y);CHKERRQ(ierr); 82ef66eb69SBarry Smith } else { 83ef66eb69SBarry Smith ierr = VecAXPY(&shell->vshift,x,y);CHKERRQ(ierr); 84ef66eb69SBarry Smith } 85ef66eb69SBarry Smith PetscFunctionReturn(0); 86ef66eb69SBarry Smith } 87ef66eb69SBarry Smith 88ef66eb69SBarry Smith #undef __FUNCT__ 89ef66eb69SBarry Smith #define __FUNCT__ "MatShift_Shell" 90dfbe8321SBarry Smith PetscErrorCode MatShift_Shell(const PetscScalar *a,Mat Y) 91ef66eb69SBarry Smith { 92ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 93ef66eb69SBarry Smith PetscFunctionBegin; 94ef66eb69SBarry Smith if (shell->scale || shell->shift) { 95ef66eb69SBarry Smith shell->vshift += *a; 96ef66eb69SBarry Smith } else { 97ef66eb69SBarry Smith shell->mult = Y->ops->mult; 98ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 99ef66eb69SBarry Smith shell->vshift = *a; 100ef66eb69SBarry Smith } 101ef66eb69SBarry Smith shell->shift = PETSC_TRUE; 102ef66eb69SBarry Smith PetscFunctionReturn(0); 103ef66eb69SBarry Smith } 104ef66eb69SBarry Smith 105ef66eb69SBarry Smith #undef __FUNCT__ 106ef66eb69SBarry Smith #define __FUNCT__ "MatScale_Shell" 107dfbe8321SBarry Smith PetscErrorCode MatScale_Shell(const PetscScalar *a,Mat Y) 108ef66eb69SBarry Smith { 109ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 110ef66eb69SBarry Smith PetscFunctionBegin; 111ef66eb69SBarry Smith if (shell->scale || shell->shift) { 112ef66eb69SBarry Smith shell->vscale *= *a; 113ef66eb69SBarry Smith } else { 114ef66eb69SBarry Smith shell->mult = Y->ops->mult; 115ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 116ef66eb69SBarry Smith shell->vscale = *a; 117ef66eb69SBarry Smith } 118ef66eb69SBarry Smith shell->scale = PETSC_TRUE; 119ef66eb69SBarry Smith PetscFunctionReturn(0); 120ef66eb69SBarry Smith } 121ef66eb69SBarry Smith 122ef66eb69SBarry Smith #undef __FUNCT__ 123ef66eb69SBarry Smith #define __FUNCT__ "MatAssemblyEnd_Shell" 124dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Shell(Mat Y,MatAssemblyType t) 125ef66eb69SBarry Smith { 126ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 127ef66eb69SBarry Smith 128ef66eb69SBarry Smith PetscFunctionBegin; 129ef66eb69SBarry Smith if ((shell->shift || shell->scale) && t == MAT_FINAL_ASSEMBLY) { 130ef66eb69SBarry Smith shell->scale = PETSC_FALSE; 131ef66eb69SBarry Smith shell->shift = PETSC_FALSE; 132ef66eb69SBarry Smith shell->vshift = 0.0; 133ef66eb69SBarry Smith shell->vscale = 1.0; 134ef66eb69SBarry Smith Y->ops->mult = shell->mult; 135ef66eb69SBarry Smith } 136ef66eb69SBarry Smith PetscFunctionReturn(0); 137ef66eb69SBarry Smith } 138ef66eb69SBarry Smith 139dfbe8321SBarry Smith EXTERN PetscErrorCode MatConvert_Shell(Mat,const MatType,Mat*); 140b951964fSBarry Smith 14109dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 14220563c6bSBarry Smith 0, 14320563c6bSBarry Smith 0, 14420563c6bSBarry Smith 0, 14597304618SKris Buschelman /* 4*/ 0, 14620563c6bSBarry Smith 0, 147b951964fSBarry Smith 0, 148b951964fSBarry Smith 0, 149b951964fSBarry Smith 0, 150b951964fSBarry Smith 0, 15197304618SKris Buschelman /*10*/ 0, 152b951964fSBarry Smith 0, 153b951964fSBarry Smith 0, 154b951964fSBarry Smith 0, 155b951964fSBarry Smith 0, 15697304618SKris Buschelman /*15*/ 0, 157b951964fSBarry Smith 0, 158b951964fSBarry Smith 0, 159b951964fSBarry Smith 0, 160b951964fSBarry Smith 0, 16197304618SKris Buschelman /*20*/ 0, 162ef66eb69SBarry Smith MatAssemblyEnd_Shell, 163b951964fSBarry Smith 0, 164b951964fSBarry Smith 0, 165b951964fSBarry Smith 0, 16697304618SKris Buschelman /*25*/ 0, 167b951964fSBarry Smith 0, 168b951964fSBarry Smith 0, 169b951964fSBarry Smith 0, 170b951964fSBarry Smith 0, 17197304618SKris Buschelman /*30*/ 0, 172b951964fSBarry Smith 0, 173273d9f13SBarry Smith 0, 174b951964fSBarry Smith 0, 175b951964fSBarry Smith 0, 17697304618SKris Buschelman /*35*/ 0, 177b951964fSBarry Smith 0, 178b951964fSBarry Smith 0, 17909dc0095SBarry Smith 0, 18009dc0095SBarry Smith 0, 18197304618SKris Buschelman /*40*/ 0, 18209dc0095SBarry Smith 0, 18309dc0095SBarry Smith 0, 18409dc0095SBarry Smith 0, 18509dc0095SBarry Smith 0, 18697304618SKris Buschelman /*45*/ 0, 187ef66eb69SBarry Smith MatScale_Shell, 188ef66eb69SBarry Smith MatShift_Shell, 18909dc0095SBarry Smith 0, 19009dc0095SBarry Smith 0, 19197304618SKris Buschelman /*50*/ 0, 19209dc0095SBarry Smith 0, 19309dc0095SBarry Smith 0, 19409dc0095SBarry Smith 0, 19509dc0095SBarry Smith 0, 19697304618SKris Buschelman /*55*/ 0, 19709dc0095SBarry Smith 0, 19809dc0095SBarry Smith 0, 19909dc0095SBarry Smith 0, 20009dc0095SBarry Smith 0, 20197304618SKris Buschelman /*60*/ 0, 202b9b97703SBarry Smith MatDestroy_Shell, 20309dc0095SBarry Smith 0, 2048a124369SBarry Smith MatGetPetscMaps_Petsc, 205273d9f13SBarry Smith 0, 20697304618SKris Buschelman /*65*/ 0, 207273d9f13SBarry Smith 0, 208273d9f13SBarry Smith 0, 209273d9f13SBarry Smith 0, 210273d9f13SBarry Smith 0, 21197304618SKris Buschelman /*70*/ 0, 21297304618SKris Buschelman MatConvert_Shell, 213273d9f13SBarry Smith 0, 214273d9f13SBarry Smith 0, 21597304618SKris Buschelman 0, 21697304618SKris Buschelman /*75*/ 0, 21797304618SKris Buschelman 0, 21897304618SKris Buschelman 0, 21997304618SKris Buschelman 0, 22097304618SKris Buschelman 0, 22197304618SKris Buschelman /*80*/ 0, 22297304618SKris Buschelman 0, 22397304618SKris Buschelman 0, 22497304618SKris Buschelman 0, 22597304618SKris Buschelman /*85*/ 0 22697304618SKris Buschelman }; 227273d9f13SBarry Smith 2280bad9183SKris Buschelman /*MC 229fafad747SKris Buschelman MATSHELL - MATSHELL = "shell" - A matrix type to be used to define your own matrix type -- perhaps matrix free. 2300bad9183SKris Buschelman 2310bad9183SKris Buschelman Level: advanced 2320bad9183SKris Buschelman 2330bad9183SKris Buschelman .seealso: MatCreateShell 2340bad9183SKris Buschelman M*/ 2350bad9183SKris Buschelman 236273d9f13SBarry Smith EXTERN_C_BEGIN 237711e205bSSatish Balay #undef __FUNCT__ 238711e205bSSatish Balay #define __FUNCT__ "MatCreate_Shell" 239dfbe8321SBarry Smith PetscErrorCode MatCreate_Shell(Mat A) 240273d9f13SBarry Smith { 241273d9f13SBarry Smith Mat_Shell *b; 242dfbe8321SBarry Smith PetscErrorCode ierr; 243273d9f13SBarry Smith 244273d9f13SBarry Smith PetscFunctionBegin; 245273d9f13SBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 246273d9f13SBarry Smith 247b0a32e0cSBarry Smith ierr = PetscNew(Mat_Shell,&b);CHKERRQ(ierr); 248b0a32e0cSBarry Smith PetscLogObjectMemory(A,sizeof(struct _p_Mat)+sizeof(Mat_Shell)); 249273d9f13SBarry Smith ierr = PetscMemzero(b,sizeof(Mat_Shell));CHKERRQ(ierr); 250273d9f13SBarry Smith A->data = (void*)b; 251273d9f13SBarry Smith 252273d9f13SBarry Smith if (A->m == PETSC_DECIDE || A->n == PETSC_DECIDE) { 253273d9f13SBarry Smith SETERRQ(1,"Must give local row and column count for matrix"); 254273d9f13SBarry Smith } 255273d9f13SBarry Smith 256273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->m,&A->M);CHKERRQ(ierr); 257273d9f13SBarry Smith ierr = PetscSplitOwnership(A->comm,&A->n,&A->N);CHKERRQ(ierr); 258273d9f13SBarry Smith 2598a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->m,A->M,&A->rmap);CHKERRQ(ierr); 2608a124369SBarry Smith ierr = PetscMapCreateMPI(A->comm,A->n,A->N,&A->cmap);CHKERRQ(ierr); 261273d9f13SBarry Smith 262273d9f13SBarry Smith b->ctx = 0; 263ef66eb69SBarry Smith b->scale = PETSC_FALSE; 264ef66eb69SBarry Smith b->shift = PETSC_FALSE; 265ef66eb69SBarry Smith b->vshift = 0.0; 266ef66eb69SBarry Smith b->vscale = 1.0; 267ef66eb69SBarry Smith b->mult = 0; 268273d9f13SBarry Smith A->assembled = PETSC_TRUE; 269273d9f13SBarry Smith A->preallocated = PETSC_TRUE; 270273d9f13SBarry Smith PetscFunctionReturn(0); 271273d9f13SBarry Smith } 272273d9f13SBarry Smith EXTERN_C_END 273e51e0e81SBarry Smith 274711e205bSSatish Balay #undef __FUNCT__ 275711e205bSSatish Balay #define __FUNCT__ "MatCreateShell" 2764b828684SBarry Smith /*@C 277052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 278ff756334SLois Curfman McInnes private data storage format. 279e51e0e81SBarry Smith 280c7fcc2eaSBarry Smith Collective on MPI_Comm 281c7fcc2eaSBarry Smith 282e51e0e81SBarry Smith Input Parameters: 283c7fcc2eaSBarry Smith + comm - MPI communicator 284c7fcc2eaSBarry Smith . m - number of local rows (must be given) 285c7fcc2eaSBarry Smith . n - number of local columns (must be given) 286c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 287c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 288c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 289e51e0e81SBarry Smith 290ff756334SLois Curfman McInnes Output Parameter: 29144cd7ae7SLois Curfman McInnes . A - the matrix 292e51e0e81SBarry Smith 293ff2fd236SBarry Smith Level: advanced 294ff2fd236SBarry Smith 295f39d1f56SLois Curfman McInnes Usage: 2967b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 297f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 298c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 299f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 300f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 301f39d1f56SLois Curfman McInnes 302ff756334SLois Curfman McInnes Notes: 303ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 304ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 305ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 306e51e0e81SBarry Smith 307f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 308f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 309645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 310645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 311645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 312645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 313645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 314645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 315645985a0SLois Curfman McInnes For example, 316f39d1f56SLois Curfman McInnes 317f39d1f56SLois Curfman McInnes $ 318f39d1f56SLois Curfman McInnes $ Vec x, y 3197b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 320645985a0SLois Curfman McInnes $ Mat A 321f39d1f56SLois Curfman McInnes $ 322c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 323c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 324f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 325c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 326c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 327c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 328645985a0SLois Curfman McInnes $ MatMult(A,x,y); 329645985a0SLois Curfman McInnes $ MatDestroy(A); 330f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 331645985a0SLois Curfman McInnes $ 332e51e0e81SBarry Smith 3330b627109SLois Curfman McInnes .keywords: matrix, shell, create 3340b627109SLois Curfman McInnes 335ab50ec6bSBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext(), MatShellSetContext() 336e51e0e81SBarry Smith @*/ 337dfbe8321SBarry Smith PetscErrorCode MatCreateShell(MPI_Comm comm,int m,int n,int M,int N,void *ctx,Mat *A) 338e51e0e81SBarry Smith { 339dfbe8321SBarry Smith PetscErrorCode ierr; 340ed3cc1f0SBarry Smith 3413a40ed3dSBarry Smith PetscFunctionBegin; 342273d9f13SBarry Smith ierr = MatCreate(comm,m,n,M,N,A);CHKERRQ(ierr); 343273d9f13SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 344273d9f13SBarry Smith ierr = MatShellSetContext(*A,ctx);CHKERRQ(ierr); 345273d9f13SBarry Smith PetscFunctionReturn(0); 346c7fcc2eaSBarry Smith } 347c7fcc2eaSBarry Smith 348711e205bSSatish Balay #undef __FUNCT__ 349711e205bSSatish Balay #define __FUNCT__ "MatShellSetContext" 350273d9f13SBarry Smith /*@C 351273d9f13SBarry Smith MatShellSetContext - sets the context for a shell matrix 352c7fcc2eaSBarry Smith 353273d9f13SBarry Smith Collective on Mat 354c7fcc2eaSBarry Smith 355273d9f13SBarry Smith Input Parameters: 356273d9f13SBarry Smith + mat - the shell matrix 357273d9f13SBarry Smith - ctx - the context 358273d9f13SBarry Smith 359273d9f13SBarry Smith Level: advanced 360273d9f13SBarry Smith 361273d9f13SBarry Smith 362273d9f13SBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 363273d9f13SBarry Smith @*/ 364dfbe8321SBarry Smith PetscErrorCode MatShellSetContext(Mat mat,void *ctx) 365273d9f13SBarry Smith { 366273d9f13SBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 367dfbe8321SBarry Smith PetscErrorCode ierr; 368273d9f13SBarry Smith PetscTruth flg; 369273d9f13SBarry Smith 370273d9f13SBarry Smith PetscFunctionBegin; 3714482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 372273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 373273d9f13SBarry Smith if (flg) { 374273d9f13SBarry Smith shell->ctx = ctx; 375273d9f13SBarry Smith } 3763a40ed3dSBarry Smith PetscFunctionReturn(0); 377e51e0e81SBarry Smith } 378e51e0e81SBarry Smith 379711e205bSSatish Balay #undef __FUNCT__ 380711e205bSSatish Balay #define __FUNCT__ "MatShellSetOperation" 381c16cb8f2SBarry Smith /*@C 3823a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 3833a3eedf2SBarry Smith a shell matrix. 384e51e0e81SBarry Smith 385fee21e36SBarry Smith Collective on Mat 386fee21e36SBarry Smith 387c7fcc2eaSBarry Smith Input Parameters: 388c7fcc2eaSBarry Smith + mat - the shell matrix 389c7fcc2eaSBarry Smith . op - the name of the operation 390c7fcc2eaSBarry Smith - f - the function that provides the operation. 391c7fcc2eaSBarry Smith 39215091d37SBarry Smith Level: advanced 39315091d37SBarry Smith 394fae171e0SBarry Smith Usage: 395a62d957aSLois Curfman McInnes $ extern int usermult(Mat,Vec,Vec); 396f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 397c134de8dSSatish Balay $ ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 3980b627109SLois Curfman McInnes 399a62d957aSLois Curfman McInnes Notes: 400e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 4011c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 402a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 4031c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 404a62d957aSLois Curfman McInnes 405a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 406deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 407deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 408deebb3c3SLois Curfman McInnes routines, e.g., 409a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 410a62d957aSLois Curfman McInnes 411a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 412a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 413a62d957aSLois Curfman McInnes set by MatCreateShell(). 414a62d957aSLois Curfman McInnes 415a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 416a62d957aSLois Curfman McInnes 417ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellSetContext() 418e51e0e81SBarry Smith @*/ 419dfbe8321SBarry Smith PetscErrorCode MatShellSetOperation(Mat mat,MatOperation op,void (*f)(void)) 420e51e0e81SBarry Smith { 421dfbe8321SBarry Smith PetscErrorCode ierr; 422273d9f13SBarry Smith PetscTruth flg; 423273d9f13SBarry Smith 4243a40ed3dSBarry Smith PetscFunctionBegin; 4254482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 4261c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 427273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 428273d9f13SBarry Smith if (flg) { 429a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 430*6849ba73SBarry Smith shell->destroy = (PetscErrorCode (*)(Mat)) f; 431*6849ba73SBarry Smith } else mat->ops->destroy = (PetscErrorCode (*)(Mat)) f; 432a62d957aSLois Curfman McInnes } 433*6849ba73SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (PetscErrorCode (*)(Mat,PetscViewer)) f; 434c134de8dSSatish Balay else (((void(**)(void))mat->ops)[op]) = f; 435a62d957aSLois Curfman McInnes 4363a40ed3dSBarry Smith PetscFunctionReturn(0); 437e51e0e81SBarry Smith } 438f0479e8cSBarry Smith 439711e205bSSatish Balay #undef __FUNCT__ 440711e205bSSatish Balay #define __FUNCT__ "MatShellGetOperation" 441d4bb536fSBarry Smith /*@C 442d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 443d4bb536fSBarry Smith 444c7fcc2eaSBarry Smith Not Collective 445c7fcc2eaSBarry Smith 446d4bb536fSBarry Smith Input Parameters: 447c7fcc2eaSBarry Smith + mat - the shell matrix 448c7fcc2eaSBarry Smith - op - the name of the operation 449d4bb536fSBarry Smith 450d4bb536fSBarry Smith Output Parameter: 451d4bb536fSBarry Smith . f - the function that provides the operation. 452d4bb536fSBarry Smith 45315091d37SBarry Smith Level: advanced 45415091d37SBarry Smith 455d4bb536fSBarry Smith Notes: 456e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 457d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 458d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 459d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 460d4bb536fSBarry Smith 461d4bb536fSBarry Smith All user-provided functions have the same calling 462d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 463d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 464d4bb536fSBarry Smith routines, e.g., 465d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 466d4bb536fSBarry Smith 467d4bb536fSBarry Smith Within each user-defined routine, the user should call 468d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 469d4bb536fSBarry Smith set by MatCreateShell(). 470d4bb536fSBarry Smith 471d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 472d4bb536fSBarry Smith 473ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation(), MatShellSetContext() 474d4bb536fSBarry Smith @*/ 475dfbe8321SBarry Smith PetscErrorCode MatShellGetOperation(Mat mat,MatOperation op,void(**f)(void)) 476d4bb536fSBarry Smith { 477dfbe8321SBarry Smith PetscErrorCode ierr; 478273d9f13SBarry Smith PetscTruth flg; 479273d9f13SBarry Smith 4803a40ed3dSBarry Smith PetscFunctionBegin; 4814482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 482d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 483273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 484273d9f13SBarry Smith if (flg) { 485d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 486c134de8dSSatish Balay *f = (void(*)(void))shell->destroy; 487c7fcc2eaSBarry Smith } else { 488c134de8dSSatish Balay *f = (void(*)(void))mat->ops->destroy; 489d4bb536fSBarry Smith } 490c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 491c134de8dSSatish Balay *f = (void(*)(void))mat->ops->view; 492c7fcc2eaSBarry Smith } else { 493c134de8dSSatish Balay *f = (((void(**)(void))mat->ops)[op]); 494d4bb536fSBarry Smith } 495d4bb536fSBarry Smith 4963a40ed3dSBarry Smith PetscFunctionReturn(0); 497d4bb536fSBarry Smith } 498d4bb536fSBarry Smith 499