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 97c4f633dSBarry Smith #include "private/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); 1518be62a5SSatish Balay PetscErrorCode (*multtranspose)(Mat,Vec,Vec); 1618be62a5SSatish Balay PetscErrorCode (*getdiagonal)(Mat,Vec); 17ef66eb69SBarry Smith PetscTruth scale,shift; 18ef66eb69SBarry Smith PetscScalar vscale,vshift; 1920563c6bSBarry Smith void *ctx; 2088cf3e7dSBarry Smith } Mat_Shell; 21e51e0e81SBarry Smith 22711e205bSSatish Balay #undef __FUNCT__ 23711e205bSSatish Balay #define __FUNCT__ "MatShellGetContext" 2435d520bfSBarry Smith /*@C 25a62d957aSLois Curfman McInnes MatShellGetContext - Returns the user-provided context associated with a shell matrix. 26b4fd4287SBarry Smith 27c7fcc2eaSBarry Smith Not Collective 28c7fcc2eaSBarry Smith 29b4fd4287SBarry Smith Input Parameter: 30b4fd4287SBarry Smith . mat - the matrix, should have been created with MatCreateShell() 31b4fd4287SBarry Smith 32b4fd4287SBarry Smith Output Parameter: 33b4fd4287SBarry Smith . ctx - the user provided context 34b4fd4287SBarry Smith 3515091d37SBarry Smith Level: advanced 3615091d37SBarry Smith 37a62d957aSLois Curfman McInnes Notes: 38a62d957aSLois Curfman McInnes This routine is intended for use within various shell matrix routines, 39a62d957aSLois Curfman McInnes as set with MatShellSetOperation(). 40a62d957aSLois Curfman McInnes 41a62d957aSLois Curfman McInnes .keywords: matrix, shell, get, context 42a62d957aSLois Curfman McInnes 43ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellSetOperation(), MatShellSetContext() 440bc0a719SBarry Smith @*/ 45be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellGetContext(Mat mat,void **ctx) 46b4fd4287SBarry Smith { 47dfbe8321SBarry Smith PetscErrorCode ierr; 48273d9f13SBarry Smith PetscTruth flg; 49273d9f13SBarry Smith 503a40ed3dSBarry Smith PetscFunctionBegin; 51*0700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 524482741eSBarry Smith PetscValidPointer(ctx,2); 53273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 54273d9f13SBarry Smith if (!flg) *ctx = 0; 55b4fd4287SBarry Smith else *ctx = ((Mat_Shell*)(mat->data))->ctx; 563a40ed3dSBarry Smith PetscFunctionReturn(0); 57b4fd4287SBarry Smith } 58b4fd4287SBarry Smith 59711e205bSSatish Balay #undef __FUNCT__ 60711e205bSSatish Balay #define __FUNCT__ "MatDestroy_Shell" 61dfbe8321SBarry Smith PetscErrorCode MatDestroy_Shell(Mat mat) 62e51e0e81SBarry Smith { 63dfbe8321SBarry Smith PetscErrorCode ierr; 6488cf3e7dSBarry Smith Mat_Shell *shell; 65ed3cc1f0SBarry Smith 663a40ed3dSBarry Smith PetscFunctionBegin; 6788cf3e7dSBarry Smith shell = (Mat_Shell*)mat->data; 683a3eedf2SBarry Smith if (shell->destroy) {ierr = (*shell->destroy)(mat);CHKERRQ(ierr);} 69606d414cSSatish Balay ierr = PetscFree(shell);CHKERRQ(ierr); 703a40ed3dSBarry Smith PetscFunctionReturn(0); 71e51e0e81SBarry Smith } 72e51e0e81SBarry Smith 73711e205bSSatish Balay #undef __FUNCT__ 74ef66eb69SBarry Smith #define __FUNCT__ "MatMult_Shell" 75dfbe8321SBarry Smith PetscErrorCode MatMult_Shell(Mat A,Vec x,Vec y) 76ef66eb69SBarry Smith { 77ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)A->data; 78dfbe8321SBarry Smith PetscErrorCode ierr; 79ef66eb69SBarry Smith 80ef66eb69SBarry Smith PetscFunctionBegin; 81ef66eb69SBarry Smith ierr = (*shell->mult)(A,x,y);CHKERRQ(ierr); 82ef66eb69SBarry Smith if (shell->shift && shell->scale) { 832dcb1b2aSMatthew Knepley ierr = VecAXPBY(y,shell->vshift,shell->vscale,x);CHKERRQ(ierr); 84ef66eb69SBarry Smith } else if (shell->scale) { 852dcb1b2aSMatthew Knepley ierr = VecScale(y,shell->vscale);CHKERRQ(ierr); 86ef66eb69SBarry Smith } else { 872dcb1b2aSMatthew Knepley ierr = VecAXPY(y,shell->vshift,x);CHKERRQ(ierr); 88ef66eb69SBarry Smith } 89ef66eb69SBarry Smith PetscFunctionReturn(0); 90ef66eb69SBarry Smith } 91ef66eb69SBarry Smith 92ef66eb69SBarry Smith #undef __FUNCT__ 9318be62a5SSatish Balay #define __FUNCT__ "MatMultTranspose_Shell" 9418be62a5SSatish Balay PetscErrorCode MatMultTranspose_Shell(Mat A,Vec x,Vec y) 9518be62a5SSatish Balay { 9618be62a5SSatish Balay Mat_Shell *shell = (Mat_Shell*)A->data; 9718be62a5SSatish Balay PetscErrorCode ierr; 9818be62a5SSatish Balay 9918be62a5SSatish Balay PetscFunctionBegin; 10018be62a5SSatish Balay ierr = (*shell->multtranspose)(A,x,y);CHKERRQ(ierr); 10118be62a5SSatish Balay if (shell->shift && shell->scale) { 10218be62a5SSatish Balay ierr = VecAXPBY(y,shell->vshift,shell->vscale,x);CHKERRQ(ierr); 10318be62a5SSatish Balay } else if (shell->scale) { 10418be62a5SSatish Balay ierr = VecScale(y,shell->vscale);CHKERRQ(ierr); 10518be62a5SSatish Balay } else { 10618be62a5SSatish Balay ierr = VecAXPY(y,shell->vshift,x);CHKERRQ(ierr); 10718be62a5SSatish Balay } 10818be62a5SSatish Balay PetscFunctionReturn(0); 10918be62a5SSatish Balay } 11018be62a5SSatish Balay 11118be62a5SSatish Balay #undef __FUNCT__ 11218be62a5SSatish Balay #define __FUNCT__ "MatGetDiagonal_Shell" 11318be62a5SSatish Balay PetscErrorCode MatGetDiagonal_Shell(Mat A,Vec v) 11418be62a5SSatish Balay { 11518be62a5SSatish Balay Mat_Shell *shell = (Mat_Shell*)A->data; 11618be62a5SSatish Balay PetscErrorCode ierr; 11718be62a5SSatish Balay 11818be62a5SSatish Balay PetscFunctionBegin; 11918be62a5SSatish Balay ierr = (*shell->getdiagonal)(A,v);CHKERRQ(ierr); 12018be62a5SSatish Balay if (shell->scale) { 12118be62a5SSatish Balay ierr = VecScale(v,shell->vscale);CHKERRQ(ierr); 12218be62a5SSatish Balay } 12318be62a5SSatish Balay if (shell->shift) { 12418be62a5SSatish Balay ierr = VecShift(v,shell->vshift);CHKERRQ(ierr); 12518be62a5SSatish Balay } 12618be62a5SSatish Balay PetscFunctionReturn(0); 12718be62a5SSatish Balay } 12818be62a5SSatish Balay 12918be62a5SSatish Balay #undef __FUNCT__ 130ef66eb69SBarry Smith #define __FUNCT__ "MatShift_Shell" 131f4df32b1SMatthew Knepley PetscErrorCode MatShift_Shell(Mat Y,PetscScalar a) 132ef66eb69SBarry Smith { 133ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 134b24ad042SBarry Smith 135ef66eb69SBarry Smith PetscFunctionBegin; 136ef66eb69SBarry Smith if (shell->scale || shell->shift) { 137f4df32b1SMatthew Knepley shell->vshift += a; 138ef66eb69SBarry Smith } else { 139ef66eb69SBarry Smith shell->mult = Y->ops->mult; 140ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 14118be62a5SSatish Balay if (Y->ops->multtranspose) { 14218be62a5SSatish Balay shell->multtranspose = Y->ops->multtranspose; 14318be62a5SSatish Balay Y->ops->multtranspose = MatMultTranspose_Shell; 14418be62a5SSatish Balay } 14518be62a5SSatish Balay if (Y->ops->getdiagonal) { 14618be62a5SSatish Balay shell->getdiagonal = Y->ops->getdiagonal; 14718be62a5SSatish Balay Y->ops->getdiagonal = MatGetDiagonal_Shell; 14818be62a5SSatish Balay } 149f4df32b1SMatthew Knepley shell->vshift = a; 150ef66eb69SBarry Smith } 151ef66eb69SBarry Smith shell->shift = PETSC_TRUE; 152ef66eb69SBarry Smith PetscFunctionReturn(0); 153ef66eb69SBarry Smith } 154ef66eb69SBarry Smith 155ef66eb69SBarry Smith #undef __FUNCT__ 156ef66eb69SBarry Smith #define __FUNCT__ "MatScale_Shell" 157f4df32b1SMatthew Knepley PetscErrorCode MatScale_Shell(Mat Y,PetscScalar a) 158ef66eb69SBarry Smith { 159ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 160b24ad042SBarry Smith 161ef66eb69SBarry Smith PetscFunctionBegin; 162ef66eb69SBarry Smith if (shell->scale || shell->shift) { 163f4df32b1SMatthew Knepley shell->vscale *= a; 164ef66eb69SBarry Smith } else { 165ef66eb69SBarry Smith shell->mult = Y->ops->mult; 166ef66eb69SBarry Smith Y->ops->mult = MatMult_Shell; 16718be62a5SSatish Balay if (Y->ops->multtranspose) { 16818be62a5SSatish Balay shell->multtranspose = Y->ops->multtranspose; 16918be62a5SSatish Balay Y->ops->multtranspose = MatMultTranspose_Shell; 17018be62a5SSatish Balay } 17118be62a5SSatish Balay if (Y->ops->getdiagonal) { 17218be62a5SSatish Balay shell->getdiagonal = Y->ops->getdiagonal; 17318be62a5SSatish Balay Y->ops->getdiagonal = MatGetDiagonal_Shell; 17418be62a5SSatish Balay } 175f4df32b1SMatthew Knepley shell->vscale = a; 176ef66eb69SBarry Smith } 177ef66eb69SBarry Smith shell->scale = PETSC_TRUE; 178ef66eb69SBarry Smith PetscFunctionReturn(0); 179ef66eb69SBarry Smith } 180ef66eb69SBarry Smith 181ef66eb69SBarry Smith #undef __FUNCT__ 182ef66eb69SBarry Smith #define __FUNCT__ "MatAssemblyEnd_Shell" 183dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Shell(Mat Y,MatAssemblyType t) 184ef66eb69SBarry Smith { 185ef66eb69SBarry Smith Mat_Shell *shell = (Mat_Shell*)Y->data; 186ef66eb69SBarry Smith 187ef66eb69SBarry Smith PetscFunctionBegin; 188ef66eb69SBarry Smith if ((shell->shift || shell->scale) && t == MAT_FINAL_ASSEMBLY) { 189ef66eb69SBarry Smith shell->scale = PETSC_FALSE; 190ef66eb69SBarry Smith shell->shift = PETSC_FALSE; 191ef66eb69SBarry Smith shell->vshift = 0.0; 192ef66eb69SBarry Smith shell->vscale = 1.0; 193ef66eb69SBarry Smith Y->ops->mult = shell->mult; 19418be62a5SSatish Balay Y->ops->multtranspose = shell->multtranspose; 19518be62a5SSatish Balay Y->ops->getdiagonal = shell->getdiagonal; 196ef66eb69SBarry Smith } 197ef66eb69SBarry Smith PetscFunctionReturn(0); 198ef66eb69SBarry Smith } 199ef66eb69SBarry Smith 200a313700dSBarry Smith EXTERN PetscErrorCode MatConvert_Shell(Mat, const MatType,MatReuse,Mat*); 201b951964fSBarry Smith 202521d7252SBarry Smith #undef __FUNCT__ 203521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_Shell" 204521d7252SBarry Smith PetscErrorCode MatSetBlockSize_Shell(Mat A,PetscInt bs) 205521d7252SBarry Smith { 20641c166b1SJed Brown PetscErrorCode ierr; 20741c166b1SJed Brown 208521d7252SBarry Smith PetscFunctionBegin; 20941c166b1SJed Brown ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr); 21041c166b1SJed Brown ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr); 211521d7252SBarry Smith PetscFunctionReturn(0); 212521d7252SBarry Smith } 213521d7252SBarry Smith 21409dc0095SBarry Smith static struct _MatOps MatOps_Values = {0, 21520563c6bSBarry Smith 0, 21620563c6bSBarry Smith 0, 21720563c6bSBarry Smith 0, 21897304618SKris Buschelman /* 4*/ 0, 21920563c6bSBarry Smith 0, 220b951964fSBarry Smith 0, 221b951964fSBarry Smith 0, 222b951964fSBarry Smith 0, 223b951964fSBarry Smith 0, 22497304618SKris Buschelman /*10*/ 0, 225b951964fSBarry Smith 0, 226b951964fSBarry Smith 0, 227b951964fSBarry Smith 0, 228b951964fSBarry Smith 0, 22997304618SKris Buschelman /*15*/ 0, 230b951964fSBarry Smith 0, 231b951964fSBarry Smith 0, 232b951964fSBarry Smith 0, 233b951964fSBarry Smith 0, 23497304618SKris Buschelman /*20*/ 0, 235ef66eb69SBarry Smith MatAssemblyEnd_Shell, 236b951964fSBarry Smith 0, 237b951964fSBarry Smith 0, 238d519adbfSMatthew Knepley /*24*/ 0, 239b951964fSBarry Smith 0, 240b951964fSBarry Smith 0, 241b951964fSBarry Smith 0, 242b951964fSBarry Smith 0, 243d519adbfSMatthew Knepley /*29*/ 0, 244b951964fSBarry Smith 0, 245273d9f13SBarry Smith 0, 246b951964fSBarry Smith 0, 247b951964fSBarry Smith 0, 248d519adbfSMatthew Knepley /*34*/ 0, 249b951964fSBarry Smith 0, 250b951964fSBarry Smith 0, 25109dc0095SBarry Smith 0, 25209dc0095SBarry Smith 0, 253d519adbfSMatthew Knepley /*39*/ 0, 25409dc0095SBarry Smith 0, 25509dc0095SBarry Smith 0, 25609dc0095SBarry Smith 0, 25709dc0095SBarry Smith 0, 258d519adbfSMatthew Knepley /*44*/ 0, 259ef66eb69SBarry Smith MatScale_Shell, 260ef66eb69SBarry Smith MatShift_Shell, 26109dc0095SBarry Smith 0, 26209dc0095SBarry Smith 0, 263d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_Shell, 26409dc0095SBarry Smith 0, 26509dc0095SBarry Smith 0, 26609dc0095SBarry Smith 0, 26709dc0095SBarry Smith 0, 268d519adbfSMatthew Knepley /*54*/ 0, 26909dc0095SBarry Smith 0, 27009dc0095SBarry Smith 0, 27109dc0095SBarry Smith 0, 27209dc0095SBarry Smith 0, 273d519adbfSMatthew Knepley /*59*/ 0, 274b9b97703SBarry Smith MatDestroy_Shell, 27509dc0095SBarry Smith 0, 276357abbc8SBarry Smith 0, 277273d9f13SBarry Smith 0, 278d519adbfSMatthew Knepley /*64*/ 0, 279273d9f13SBarry Smith 0, 280273d9f13SBarry Smith 0, 281273d9f13SBarry Smith 0, 282273d9f13SBarry Smith 0, 283d519adbfSMatthew Knepley /*69*/ 0, 284273d9f13SBarry Smith 0, 285c87e5d42SMatthew Knepley MatConvert_Shell, 286273d9f13SBarry Smith 0, 28797304618SKris Buschelman 0, 288d519adbfSMatthew Knepley /*74*/ 0, 28997304618SKris Buschelman 0, 29097304618SKris Buschelman 0, 29197304618SKris Buschelman 0, 29297304618SKris Buschelman 0, 293d519adbfSMatthew Knepley /*79*/ 0, 29497304618SKris Buschelman 0, 29597304618SKris Buschelman 0, 29697304618SKris Buschelman 0, 297865e5f61SKris Buschelman 0, 298d519adbfSMatthew Knepley /*84*/ 0, 299865e5f61SKris Buschelman 0, 300865e5f61SKris Buschelman 0, 301865e5f61SKris Buschelman 0, 302865e5f61SKris Buschelman 0, 303d519adbfSMatthew Knepley /*89*/ 0, 304865e5f61SKris Buschelman 0, 305865e5f61SKris Buschelman 0, 306865e5f61SKris Buschelman 0, 307865e5f61SKris Buschelman 0, 308d519adbfSMatthew Knepley /*94*/ 0, 309865e5f61SKris Buschelman 0, 310865e5f61SKris Buschelman 0, 311865e5f61SKris Buschelman 0}; 312273d9f13SBarry Smith 3130bad9183SKris Buschelman /*MC 314fafad747SKris Buschelman MATSHELL - MATSHELL = "shell" - A matrix type to be used to define your own matrix type -- perhaps matrix free. 3150bad9183SKris Buschelman 3160bad9183SKris Buschelman Level: advanced 3170bad9183SKris Buschelman 3180bad9183SKris Buschelman .seealso: MatCreateShell 3190bad9183SKris Buschelman M*/ 3200bad9183SKris Buschelman 321273d9f13SBarry Smith EXTERN_C_BEGIN 322711e205bSSatish Balay #undef __FUNCT__ 323711e205bSSatish Balay #define __FUNCT__ "MatCreate_Shell" 324be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Shell(Mat A) 325273d9f13SBarry Smith { 326273d9f13SBarry Smith Mat_Shell *b; 327dfbe8321SBarry Smith PetscErrorCode ierr; 328273d9f13SBarry Smith 329273d9f13SBarry Smith PetscFunctionBegin; 330273d9f13SBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 331273d9f13SBarry Smith 33238f2d2fdSLisandro Dalcin ierr = PetscNewLog(A,Mat_Shell,&b);CHKERRQ(ierr); 333273d9f13SBarry Smith A->data = (void*)b; 334273d9f13SBarry Smith 335d0f46423SBarry Smith if (A->rmap->n == PETSC_DECIDE || A->cmap->n == PETSC_DECIDE) { 336e005ede5SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Must give local row and column count for matrix"); 337273d9f13SBarry Smith } 338273d9f13SBarry Smith 33926283091SBarry Smith ierr = PetscLayoutSetBlockSize(A->rmap,1);CHKERRQ(ierr); 34026283091SBarry Smith ierr = PetscLayoutSetBlockSize(A->cmap,1);CHKERRQ(ierr); 34126283091SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 34226283091SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 343273d9f13SBarry Smith 344273d9f13SBarry Smith b->ctx = 0; 345ef66eb69SBarry Smith b->scale = PETSC_FALSE; 346ef66eb69SBarry Smith b->shift = PETSC_FALSE; 347ef66eb69SBarry Smith b->vshift = 0.0; 348ef66eb69SBarry Smith b->vscale = 1.0; 349ef66eb69SBarry Smith b->mult = 0; 35018be62a5SSatish Balay b->multtranspose = 0; 35118be62a5SSatish Balay b->getdiagonal = 0; 352273d9f13SBarry Smith A->assembled = PETSC_TRUE; 353210f0121SBarry Smith A->preallocated = PETSC_FALSE; 35417667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATSHELL);CHKERRQ(ierr); 355273d9f13SBarry Smith PetscFunctionReturn(0); 356273d9f13SBarry Smith } 357273d9f13SBarry Smith EXTERN_C_END 358e51e0e81SBarry Smith 359711e205bSSatish Balay #undef __FUNCT__ 360711e205bSSatish Balay #define __FUNCT__ "MatCreateShell" 3614b828684SBarry Smith /*@C 362052efed2SBarry Smith MatCreateShell - Creates a new matrix class for use with a user-defined 363ff756334SLois Curfman McInnes private data storage format. 364e51e0e81SBarry Smith 365c7fcc2eaSBarry Smith Collective on MPI_Comm 366c7fcc2eaSBarry Smith 367e51e0e81SBarry Smith Input Parameters: 368c7fcc2eaSBarry Smith + comm - MPI communicator 369c7fcc2eaSBarry Smith . m - number of local rows (must be given) 370c7fcc2eaSBarry Smith . n - number of local columns (must be given) 371c7fcc2eaSBarry Smith . M - number of global rows (may be PETSC_DETERMINE) 372c7fcc2eaSBarry Smith . N - number of global columns (may be PETSC_DETERMINE) 373c7fcc2eaSBarry Smith - ctx - pointer to data needed by the shell matrix routines 374e51e0e81SBarry Smith 375ff756334SLois Curfman McInnes Output Parameter: 37644cd7ae7SLois Curfman McInnes . A - the matrix 377e51e0e81SBarry Smith 378ff2fd236SBarry Smith Level: advanced 379ff2fd236SBarry Smith 380f39d1f56SLois Curfman McInnes Usage: 3817b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 382f39d1f56SLois Curfman McInnes $ MatCreateShell(comm,m,n,M,N,ctx,&mat); 383c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 384f39d1f56SLois Curfman McInnes $ [ Use matrix for operations that have been set ] 385f39d1f56SLois Curfman McInnes $ MatDestroy(mat); 386f39d1f56SLois Curfman McInnes 387ff756334SLois Curfman McInnes Notes: 388ff756334SLois Curfman McInnes The shell matrix type is intended to provide a simple class to use 389ff756334SLois Curfman McInnes with KSP (such as, for use with matrix-free methods). You should not 390ff756334SLois Curfman McInnes use the shell type if you plan to define a complete matrix class. 391e51e0e81SBarry Smith 392f38a8d56SBarry Smith Fortran Notes: The context can only be an integer or a PetscObject 393f38a8d56SBarry Smith unfortunately it cannot be a Fortran array or derived type. 394f38a8d56SBarry Smith 395f39d1f56SLois Curfman McInnes PETSc requires that matrices and vectors being used for certain 396f39d1f56SLois Curfman McInnes operations are partitioned accordingly. For example, when 397645985a0SLois Curfman McInnes creating a shell matrix, A, that supports parallel matrix-vector 398645985a0SLois Curfman McInnes products using MatMult(A,x,y) the user should set the number 399645985a0SLois Curfman McInnes of local matrix rows to be the number of local elements of the 400645985a0SLois Curfman McInnes corresponding result vector, y. Note that this is information is 401645985a0SLois Curfman McInnes required for use of the matrix interface routines, even though 402645985a0SLois Curfman McInnes the shell matrix may not actually be physically partitioned. 403645985a0SLois Curfman McInnes For example, 404f39d1f56SLois Curfman McInnes 405f39d1f56SLois Curfman McInnes $ 406f39d1f56SLois Curfman McInnes $ Vec x, y 4077b2a1423SBarry Smith $ extern int mult(Mat,Vec,Vec); 408645985a0SLois Curfman McInnes $ Mat A 409f39d1f56SLois Curfman McInnes $ 410c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,M,&y); 411c94f878dSBarry Smith $ VecCreateMPI(comm,PETSC_DECIDE,N,&x); 412f39d1f56SLois Curfman McInnes $ VecGetLocalSize(y,&m); 413c7fcc2eaSBarry Smith $ VecGetLocalSize(x,&n); 414c7fcc2eaSBarry Smith $ MatCreateShell(comm,m,n,M,N,ctx,&A); 415c134de8dSSatish Balay $ MatShellSetOperation(mat,MATOP_MULT,(void(*)(void))mult); 416645985a0SLois Curfman McInnes $ MatMult(A,x,y); 417645985a0SLois Curfman McInnes $ MatDestroy(A); 418f39d1f56SLois Curfman McInnes $ VecDestroy(y); VecDestroy(x); 419645985a0SLois Curfman McInnes $ 420e51e0e81SBarry Smith 4210b627109SLois Curfman McInnes .keywords: matrix, shell, create 4220b627109SLois Curfman McInnes 423ab50ec6bSBarry Smith .seealso: MatShellSetOperation(), MatHasOperation(), MatShellGetContext(), MatShellSetContext() 424e51e0e81SBarry Smith @*/ 425be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateShell(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,void *ctx,Mat *A) 426e51e0e81SBarry Smith { 427dfbe8321SBarry Smith PetscErrorCode ierr; 428ed3cc1f0SBarry Smith 4293a40ed3dSBarry Smith PetscFunctionBegin; 430f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 431f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,M,N);CHKERRQ(ierr); 432899cda47SBarry Smith 433273d9f13SBarry Smith ierr = MatSetType(*A,MATSHELL);CHKERRQ(ierr); 434273d9f13SBarry Smith ierr = MatShellSetContext(*A,ctx);CHKERRQ(ierr); 435273d9f13SBarry Smith PetscFunctionReturn(0); 436c7fcc2eaSBarry Smith } 437c7fcc2eaSBarry Smith 438711e205bSSatish Balay #undef __FUNCT__ 439711e205bSSatish Balay #define __FUNCT__ "MatShellSetContext" 440c6866cfdSSatish Balay /*@ 441273d9f13SBarry Smith MatShellSetContext - sets the context for a shell matrix 442c7fcc2eaSBarry Smith 443273d9f13SBarry Smith Collective on Mat 444c7fcc2eaSBarry Smith 445273d9f13SBarry Smith Input Parameters: 446273d9f13SBarry Smith + mat - the shell matrix 447273d9f13SBarry Smith - ctx - the context 448273d9f13SBarry Smith 449273d9f13SBarry Smith Level: advanced 450273d9f13SBarry Smith 451f38a8d56SBarry Smith Fortran Notes: The context can only be an integer or a PetscObject 452f38a8d56SBarry Smith unfortunately it cannot be a Fortran array or derived type. 453273d9f13SBarry Smith 454273d9f13SBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 4550bc0a719SBarry Smith @*/ 456be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellSetContext(Mat mat,void *ctx) 457273d9f13SBarry Smith { 458273d9f13SBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 459dfbe8321SBarry Smith PetscErrorCode ierr; 460273d9f13SBarry Smith PetscTruth flg; 461273d9f13SBarry Smith 462273d9f13SBarry Smith PetscFunctionBegin; 463*0700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 464273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 465273d9f13SBarry Smith if (flg) { 466273d9f13SBarry Smith shell->ctx = ctx; 467273d9f13SBarry Smith } 4683a40ed3dSBarry Smith PetscFunctionReturn(0); 469e51e0e81SBarry Smith } 470e51e0e81SBarry Smith 471711e205bSSatish Balay #undef __FUNCT__ 472711e205bSSatish Balay #define __FUNCT__ "MatShellSetOperation" 473c16cb8f2SBarry Smith /*@C 4743a3eedf2SBarry Smith MatShellSetOperation - Allows user to set a matrix operation for 4753a3eedf2SBarry Smith a shell matrix. 476e51e0e81SBarry Smith 477fee21e36SBarry Smith Collective on Mat 478fee21e36SBarry Smith 479c7fcc2eaSBarry Smith Input Parameters: 480c7fcc2eaSBarry Smith + mat - the shell matrix 481c7fcc2eaSBarry Smith . op - the name of the operation 482c7fcc2eaSBarry Smith - f - the function that provides the operation. 483c7fcc2eaSBarry Smith 48415091d37SBarry Smith Level: advanced 48515091d37SBarry Smith 486fae171e0SBarry Smith Usage: 487e93bc3c1Svictor $ extern PetscErrorCode usermult(Mat,Vec,Vec); 488f39d1f56SLois Curfman McInnes $ ierr = MatCreateShell(comm,m,n,M,N,ctx,&A); 489c134de8dSSatish Balay $ ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 4900b627109SLois Curfman McInnes 491a62d957aSLois Curfman McInnes Notes: 492e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 4931c1c02c0SLois Curfman McInnes operations, which all have the form MATOP_<OPERATION>, where 494a62d957aSLois Curfman McInnes <OPERATION> is the name (in all capital letters) of the 4951c1c02c0SLois Curfman McInnes user interface routine (e.g., MatMult() -> MATOP_MULT). 496a62d957aSLois Curfman McInnes 497a62d957aSLois Curfman McInnes All user-provided functions should have the same calling 498deebb3c3SLois Curfman McInnes sequence as the usual matrix interface routines, since they 499deebb3c3SLois Curfman McInnes are intended to be accessed via the usual matrix interface 500deebb3c3SLois Curfman McInnes routines, e.g., 501a62d957aSLois Curfman McInnes $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 502a62d957aSLois Curfman McInnes 5034aa34b0aSBarry Smith In particular each function MUST return an error code of 0 on success and 5044aa34b0aSBarry Smith nonzero on failure. 5054aa34b0aSBarry Smith 506a62d957aSLois Curfman McInnes Within each user-defined routine, the user should call 507a62d957aSLois Curfman McInnes MatShellGetContext() to obtain the user-defined context that was 508a62d957aSLois Curfman McInnes set by MatCreateShell(). 509a62d957aSLois Curfman McInnes 510a62d957aSLois Curfman McInnes .keywords: matrix, shell, set, operation 511a62d957aSLois Curfman McInnes 512ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellSetContext() 513e51e0e81SBarry Smith @*/ 514be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellSetOperation(Mat mat,MatOperation op,void (*f)(void)) 515e51e0e81SBarry Smith { 516dfbe8321SBarry Smith PetscErrorCode ierr; 517273d9f13SBarry Smith PetscTruth flg; 518273d9f13SBarry Smith 5193a40ed3dSBarry Smith PetscFunctionBegin; 520*0700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5211c1c02c0SLois Curfman McInnes if (op == MATOP_DESTROY) { 522273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 523273d9f13SBarry Smith if (flg) { 524a62d957aSLois Curfman McInnes Mat_Shell *shell = (Mat_Shell*)mat->data; 5256849ba73SBarry Smith shell->destroy = (PetscErrorCode (*)(Mat)) f; 5266849ba73SBarry Smith } else mat->ops->destroy = (PetscErrorCode (*)(Mat)) f; 527a62d957aSLois Curfman McInnes } 5286849ba73SBarry Smith else if (op == MATOP_VIEW) mat->ops->view = (PetscErrorCode (*)(Mat,PetscViewer)) f; 529c134de8dSSatish Balay else (((void(**)(void))mat->ops)[op]) = f; 530a62d957aSLois Curfman McInnes 5313a40ed3dSBarry Smith PetscFunctionReturn(0); 532e51e0e81SBarry Smith } 533f0479e8cSBarry Smith 534711e205bSSatish Balay #undef __FUNCT__ 535711e205bSSatish Balay #define __FUNCT__ "MatShellGetOperation" 536d4bb536fSBarry Smith /*@C 537d4bb536fSBarry Smith MatShellGetOperation - Gets a matrix function for a shell matrix. 538d4bb536fSBarry Smith 539c7fcc2eaSBarry Smith Not Collective 540c7fcc2eaSBarry Smith 541d4bb536fSBarry Smith Input Parameters: 542c7fcc2eaSBarry Smith + mat - the shell matrix 543c7fcc2eaSBarry Smith - op - the name of the operation 544d4bb536fSBarry Smith 545d4bb536fSBarry Smith Output Parameter: 546d4bb536fSBarry Smith . f - the function that provides the operation. 547d4bb536fSBarry Smith 54815091d37SBarry Smith Level: advanced 54915091d37SBarry Smith 550d4bb536fSBarry Smith Notes: 551e090d566SSatish Balay See the file include/petscmat.h for a complete list of matrix 552d4bb536fSBarry Smith operations, which all have the form MATOP_<OPERATION>, where 553d4bb536fSBarry Smith <OPERATION> is the name (in all capital letters) of the 554d4bb536fSBarry Smith user interface routine (e.g., MatMult() -> MATOP_MULT). 555d4bb536fSBarry Smith 556d4bb536fSBarry Smith All user-provided functions have the same calling 557d4bb536fSBarry Smith sequence as the usual matrix interface routines, since they 558d4bb536fSBarry Smith are intended to be accessed via the usual matrix interface 559d4bb536fSBarry Smith routines, e.g., 560d4bb536fSBarry Smith $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 561d4bb536fSBarry Smith 562d4bb536fSBarry Smith Within each user-defined routine, the user should call 563d4bb536fSBarry Smith MatShellGetContext() to obtain the user-defined context that was 564d4bb536fSBarry Smith set by MatCreateShell(). 565d4bb536fSBarry Smith 566d4bb536fSBarry Smith .keywords: matrix, shell, set, operation 567d4bb536fSBarry Smith 568ab50ec6bSBarry Smith .seealso: MatCreateShell(), MatShellGetContext(), MatShellSetOperation(), MatShellSetContext() 569d4bb536fSBarry Smith @*/ 570be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatShellGetOperation(Mat mat,MatOperation op,void(**f)(void)) 571d4bb536fSBarry Smith { 572dfbe8321SBarry Smith PetscErrorCode ierr; 573273d9f13SBarry Smith PetscTruth flg; 574273d9f13SBarry Smith 5753a40ed3dSBarry Smith PetscFunctionBegin; 576*0700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 577d4bb536fSBarry Smith if (op == MATOP_DESTROY) { 578273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSHELL,&flg);CHKERRQ(ierr); 579273d9f13SBarry Smith if (flg) { 580d4bb536fSBarry Smith Mat_Shell *shell = (Mat_Shell*)mat->data; 581c134de8dSSatish Balay *f = (void(*)(void))shell->destroy; 582c7fcc2eaSBarry Smith } else { 583c134de8dSSatish Balay *f = (void(*)(void))mat->ops->destroy; 584d4bb536fSBarry Smith } 585c7fcc2eaSBarry Smith } else if (op == MATOP_VIEW) { 586c134de8dSSatish Balay *f = (void(*)(void))mat->ops->view; 587c7fcc2eaSBarry Smith } else { 588c134de8dSSatish Balay *f = (((void(**)(void))mat->ops)[op]); 589d4bb536fSBarry Smith } 590d4bb536fSBarry Smith 5913a40ed3dSBarry Smith PetscFunctionReturn(0); 592d4bb536fSBarry Smith } 593d4bb536fSBarry Smith 594