1ee1cef2cSJed Brown 2af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 3ee1cef2cSJed Brown 4ee1cef2cSJed Brown typedef struct { 5ee1cef2cSJed Brown IS isrow,iscol; /* rows and columns in submatrix, only used to check consistency */ 6ee1cef2cSJed Brown Vec lwork,rwork; /* work vectors inside the scatters */ 711c5f74dSStefano Zampini Vec lwork2,rwork2; /* work vectors inside the scatters */ 8ee1cef2cSJed Brown VecScatter lrestrict,rprolong; 9ee1cef2cSJed Brown Mat A; 1054e05e6cSHong Zhang } Mat_SubVirtual; 11ee1cef2cSJed Brown 12bddd1ffdSAlp Dener static PetscErrorCode MatScale_SubMatrix(Mat N,PetscScalar a) 13bddd1ffdSAlp Dener { 14bddd1ffdSAlp Dener Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data; 15bddd1ffdSAlp Dener PetscErrorCode ierr; 16bddd1ffdSAlp Dener 17bddd1ffdSAlp Dener PetscFunctionBegin; 1811c5f74dSStefano Zampini ierr = MatScale(Na->A,a);CHKERRQ(ierr); 19bddd1ffdSAlp Dener PetscFunctionReturn(0); 20bddd1ffdSAlp Dener } 21bddd1ffdSAlp Dener 22bddd1ffdSAlp Dener static PetscErrorCode MatShift_SubMatrix(Mat N,PetscScalar a) 23bddd1ffdSAlp Dener { 24bddd1ffdSAlp Dener Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data; 25bddd1ffdSAlp Dener PetscErrorCode ierr; 26bddd1ffdSAlp Dener 27bddd1ffdSAlp Dener PetscFunctionBegin; 2811c5f74dSStefano Zampini ierr = MatShift(Na->A,a);CHKERRQ(ierr); 29ee1cef2cSJed Brown PetscFunctionReturn(0); 30ee1cef2cSJed Brown } 31ee1cef2cSJed Brown 32ee1cef2cSJed Brown static PetscErrorCode MatDiagonalScale_SubMatrix(Mat N,Vec left,Vec right) 33ee1cef2cSJed Brown { 3454e05e6cSHong Zhang Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data; 35ee1cef2cSJed Brown PetscErrorCode ierr; 36ee1cef2cSJed Brown 37ee1cef2cSJed Brown PetscFunctionBegin; 38ee1cef2cSJed Brown if (right) { 3911c5f74dSStefano Zampini ierr = VecZeroEntries(Na->rwork);CHKERRQ(ierr); 4011c5f74dSStefano Zampini ierr = VecScatterBegin(Na->rprolong,right,Na->rwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4111c5f74dSStefano Zampini ierr = VecScatterEnd(Na->rprolong,right,Na->rwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 42ee1cef2cSJed Brown } 4311c5f74dSStefano Zampini if (left) { 4411c5f74dSStefano Zampini ierr = VecZeroEntries(Na->lwork);CHKERRQ(ierr); 4511c5f74dSStefano Zampini ierr = VecScatterBegin(Na->lrestrict,left,Na->lwork,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4611c5f74dSStefano Zampini ierr = VecScatterEnd(Na->lrestrict,left,Na->lwork,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 47ee1cef2cSJed Brown } 4811c5f74dSStefano Zampini ierr = MatDiagonalScale(Na->A,left ? Na->lwork : NULL,right ? Na->rwork : NULL);CHKERRQ(ierr); 4911c5f74dSStefano Zampini PetscFunctionReturn(0); 5011c5f74dSStefano Zampini } 5111c5f74dSStefano Zampini 5211c5f74dSStefano Zampini static PetscErrorCode MatGetDiagonal_SubMatrix(Mat N,Vec d) 5311c5f74dSStefano Zampini { 5411c5f74dSStefano Zampini Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data; 5511c5f74dSStefano Zampini PetscErrorCode ierr; 5611c5f74dSStefano Zampini 5711c5f74dSStefano Zampini PetscFunctionBegin; 5811c5f74dSStefano Zampini ierr = MatGetDiagonal(Na->A,Na->rwork);CHKERRQ(ierr); 5911c5f74dSStefano Zampini ierr = VecScatterBegin(Na->rprolong,Na->rwork,d,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6011c5f74dSStefano Zampini ierr = VecScatterEnd(Na->rprolong,Na->rwork,d,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 61ee1cef2cSJed Brown PetscFunctionReturn(0); 62ee1cef2cSJed Brown } 63ee1cef2cSJed Brown 64ee1cef2cSJed Brown static PetscErrorCode MatMult_SubMatrix(Mat N,Vec x,Vec y) 65ee1cef2cSJed Brown { 6654e05e6cSHong Zhang Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data; 67ee1cef2cSJed Brown PetscErrorCode ierr; 68ee1cef2cSJed Brown 69ee1cef2cSJed Brown PetscFunctionBegin; 70ee1cef2cSJed Brown ierr = VecZeroEntries(Na->rwork);CHKERRQ(ierr); 7111c5f74dSStefano Zampini ierr = VecScatterBegin(Na->rprolong,x,Na->rwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7211c5f74dSStefano Zampini ierr = VecScatterEnd(Na->rprolong,x,Na->rwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 73ee1cef2cSJed Brown ierr = MatMult(Na->A,Na->rwork,Na->lwork);CHKERRQ(ierr); 74ee1cef2cSJed Brown ierr = VecScatterBegin(Na->lrestrict,Na->lwork,y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 75ee1cef2cSJed Brown ierr = VecScatterEnd(Na->lrestrict,Na->lwork,y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 76ee1cef2cSJed Brown PetscFunctionReturn(0); 77ee1cef2cSJed Brown } 78ee1cef2cSJed Brown 79ee1cef2cSJed Brown static PetscErrorCode MatMultAdd_SubMatrix(Mat N,Vec v1,Vec v2,Vec v3) 80ee1cef2cSJed Brown { 8154e05e6cSHong Zhang Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data; 82ee1cef2cSJed Brown PetscErrorCode ierr; 83ee1cef2cSJed Brown 84ee1cef2cSJed Brown PetscFunctionBegin; 85ee1cef2cSJed Brown ierr = VecZeroEntries(Na->rwork);CHKERRQ(ierr); 8611c5f74dSStefano Zampini ierr = VecScatterBegin(Na->rprolong,v1,Na->rwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8711c5f74dSStefano Zampini ierr = VecScatterEnd(Na->rprolong,v1,Na->rwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8811c5f74dSStefano Zampini if (v1 == v2) { 8911c5f74dSStefano Zampini ierr = MatMultAdd(Na->A,Na->rwork,Na->rwork,Na->lwork);CHKERRQ(ierr); 9011c5f74dSStefano Zampini } else if (v2 == v3) { 9111c5f74dSStefano Zampini ierr = VecZeroEntries(Na->lwork);CHKERRQ(ierr); 9211c5f74dSStefano Zampini ierr = VecScatterBegin(Na->lrestrict,v2,Na->lwork,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9311c5f74dSStefano Zampini ierr = VecScatterEnd(Na->lrestrict,v2,Na->lwork,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9411c5f74dSStefano Zampini ierr = MatMultAdd(Na->A,Na->rwork,Na->lwork,Na->lwork);CHKERRQ(ierr); 951e7f0bbdSJed Brown } else { 9611c5f74dSStefano Zampini if (!Na->lwork2) { 9711c5f74dSStefano Zampini ierr = VecDuplicate(Na->lwork,&Na->lwork2);CHKERRQ(ierr); 9811c5f74dSStefano Zampini } else { 9911c5f74dSStefano Zampini ierr = VecZeroEntries(Na->lwork2);CHKERRQ(ierr); 10011c5f74dSStefano Zampini } 10111c5f74dSStefano Zampini ierr = VecScatterBegin(Na->lrestrict,v2,Na->lwork2,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10211c5f74dSStefano Zampini ierr = VecScatterEnd(Na->lrestrict,v2,Na->lwork2,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10311c5f74dSStefano Zampini ierr = MatMultAdd(Na->A,Na->rwork,Na->lwork2,Na->lwork);CHKERRQ(ierr); 10411c5f74dSStefano Zampini } 105ee1cef2cSJed Brown ierr = VecScatterBegin(Na->lrestrict,Na->lwork,v3,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 106ee1cef2cSJed Brown ierr = VecScatterEnd(Na->lrestrict,Na->lwork,v3,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 107ee1cef2cSJed Brown PetscFunctionReturn(0); 108ee1cef2cSJed Brown } 109ee1cef2cSJed Brown 110ee1cef2cSJed Brown static PetscErrorCode MatMultTranspose_SubMatrix(Mat N,Vec x,Vec y) 111ee1cef2cSJed Brown { 11254e05e6cSHong Zhang Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data; 113ee1cef2cSJed Brown PetscErrorCode ierr; 114ee1cef2cSJed Brown 115ee1cef2cSJed Brown PetscFunctionBegin; 116ee1cef2cSJed Brown ierr = VecZeroEntries(Na->lwork);CHKERRQ(ierr); 11711c5f74dSStefano Zampini ierr = VecScatterBegin(Na->lrestrict,x,Na->lwork,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11811c5f74dSStefano Zampini ierr = VecScatterEnd(Na->lrestrict,x,Na->lwork,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 119ee1cef2cSJed Brown ierr = MatMultTranspose(Na->A,Na->lwork,Na->rwork);CHKERRQ(ierr); 1201e7f0bbdSJed Brown ierr = VecScatterBegin(Na->rprolong,Na->rwork,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1211e7f0bbdSJed Brown ierr = VecScatterEnd(Na->rprolong,Na->rwork,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 122ee1cef2cSJed Brown PetscFunctionReturn(0); 123ee1cef2cSJed Brown } 124ee1cef2cSJed Brown 125ee1cef2cSJed Brown static PetscErrorCode MatMultTransposeAdd_SubMatrix(Mat N,Vec v1,Vec v2,Vec v3) 126ee1cef2cSJed Brown { 12754e05e6cSHong Zhang Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data; 128ee1cef2cSJed Brown PetscErrorCode ierr; 129ee1cef2cSJed Brown 130ee1cef2cSJed Brown PetscFunctionBegin; 131ee1cef2cSJed Brown ierr = VecZeroEntries(Na->lwork);CHKERRQ(ierr); 13211c5f74dSStefano Zampini ierr = VecScatterBegin(Na->lrestrict,v1,Na->lwork,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13311c5f74dSStefano Zampini ierr = VecScatterEnd(Na->lrestrict,v1,Na->lwork,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13411c5f74dSStefano Zampini if (v1 == v2) { 13511c5f74dSStefano Zampini ierr = MatMultTransposeAdd(Na->A,Na->lwork,Na->lwork,Na->rwork);CHKERRQ(ierr); 13611c5f74dSStefano Zampini } else if (v2 == v3) { 13711c5f74dSStefano Zampini ierr = VecZeroEntries(Na->rwork);CHKERRQ(ierr); 13811c5f74dSStefano Zampini ierr = VecScatterBegin(Na->rprolong,v2,Na->rwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13911c5f74dSStefano Zampini ierr = VecScatterEnd(Na->rprolong,v2,Na->rwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14011c5f74dSStefano Zampini ierr = MatMultTransposeAdd(Na->A,Na->lwork,Na->rwork,Na->rwork);CHKERRQ(ierr); 1411e7f0bbdSJed Brown } else { 14211c5f74dSStefano Zampini if (!Na->rwork2) { 14311c5f74dSStefano Zampini ierr = VecDuplicate(Na->rwork,&Na->rwork2);CHKERRQ(ierr); 14411c5f74dSStefano Zampini } else { 14511c5f74dSStefano Zampini ierr = VecZeroEntries(Na->rwork2);CHKERRQ(ierr); 14611c5f74dSStefano Zampini } 14711c5f74dSStefano Zampini ierr = VecScatterBegin(Na->rprolong,v2,Na->rwork2,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14811c5f74dSStefano Zampini ierr = VecScatterEnd(Na->rprolong,v2,Na->rwork2,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 14911c5f74dSStefano Zampini ierr = MatMultTransposeAdd(Na->A,Na->lwork,Na->rwork2,Na->rwork);CHKERRQ(ierr); 15011c5f74dSStefano Zampini } 1511e7f0bbdSJed Brown ierr = VecScatterBegin(Na->rprolong,Na->rwork,v3,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1521e7f0bbdSJed Brown ierr = VecScatterEnd(Na->rprolong,Na->rwork,v3,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 153ee1cef2cSJed Brown PetscFunctionReturn(0); 154ee1cef2cSJed Brown } 155ee1cef2cSJed Brown 156ee1cef2cSJed Brown static PetscErrorCode MatDestroy_SubMatrix(Mat N) 157ee1cef2cSJed Brown { 15854e05e6cSHong Zhang Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data; 159ee1cef2cSJed Brown PetscErrorCode ierr; 160ee1cef2cSJed Brown 161ee1cef2cSJed Brown PetscFunctionBegin; 1626bf464f9SBarry Smith ierr = ISDestroy(&Na->isrow);CHKERRQ(ierr); 1636bf464f9SBarry Smith ierr = ISDestroy(&Na->iscol);CHKERRQ(ierr); 1646bf464f9SBarry Smith ierr = VecDestroy(&Na->lwork);CHKERRQ(ierr); 1656bf464f9SBarry Smith ierr = VecDestroy(&Na->rwork);CHKERRQ(ierr); 16611c5f74dSStefano Zampini ierr = VecDestroy(&Na->lwork2);CHKERRQ(ierr); 16711c5f74dSStefano Zampini ierr = VecDestroy(&Na->rwork2);CHKERRQ(ierr); 1686bf464f9SBarry Smith ierr = VecScatterDestroy(&Na->lrestrict);CHKERRQ(ierr); 1696bf464f9SBarry Smith ierr = VecScatterDestroy(&Na->rprolong);CHKERRQ(ierr); 1706bf464f9SBarry Smith ierr = MatDestroy(&Na->A);CHKERRQ(ierr); 1716bf464f9SBarry Smith ierr = PetscFree(N->data);CHKERRQ(ierr); 172ee1cef2cSJed Brown PetscFunctionReturn(0); 173ee1cef2cSJed Brown } 174ee1cef2cSJed Brown 175ee1cef2cSJed Brown /*@ 17654e05e6cSHong Zhang MatCreateSubMatrixVirtual - Creates a virtual matrix that acts as a submatrix 177ee1cef2cSJed Brown 178ee1cef2cSJed Brown Collective on Mat 179ee1cef2cSJed Brown 180ee1cef2cSJed Brown Input Parameters: 181ee1cef2cSJed Brown + A - matrix that we will extract a submatrix of 182ee1cef2cSJed Brown . isrow - rows to be present in the submatrix 183ee1cef2cSJed Brown - iscol - columns to be present in the submatrix 184ee1cef2cSJed Brown 185ee1cef2cSJed Brown Output Parameters: 186ee1cef2cSJed Brown . newmat - new matrix 187ee1cef2cSJed Brown 188ee1cef2cSJed Brown Level: developer 189ee1cef2cSJed Brown 190ee1cef2cSJed Brown Notes: 1917dae84e0SHong Zhang Most will use MatCreateSubMatrix which provides a more efficient representation if it is available. 192ee1cef2cSJed Brown 19354e05e6cSHong Zhang .seealso: MatCreateSubMatrix(), MatSubMatrixVirtualUpdate() 194ee1cef2cSJed Brown @*/ 19554e05e6cSHong Zhang PetscErrorCode MatCreateSubMatrixVirtual(Mat A,IS isrow,IS iscol,Mat *newmat) 196ee1cef2cSJed Brown { 197ee1cef2cSJed Brown Vec left,right; 198ee1cef2cSJed Brown PetscInt m,n; 199ee1cef2cSJed Brown Mat N; 20054e05e6cSHong Zhang Mat_SubVirtual *Na; 201ee1cef2cSJed Brown PetscErrorCode ierr; 202ee1cef2cSJed Brown 203ee1cef2cSJed Brown PetscFunctionBegin; 2040700a824SBarry Smith PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2050700a824SBarry Smith PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 2060700a824SBarry Smith PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 207ee1cef2cSJed Brown PetscValidPointer(newmat,4); 208f4259b30SLisandro Dalcin *newmat = NULL; 209ee1cef2cSJed Brown 210ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&N);CHKERRQ(ierr); 211ee1cef2cSJed Brown ierr = ISGetLocalSize(isrow,&m);CHKERRQ(ierr); 212ee1cef2cSJed Brown ierr = ISGetLocalSize(iscol,&n);CHKERRQ(ierr); 213ee1cef2cSJed Brown ierr = MatSetSizes(N,m,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 214ee1cef2cSJed Brown ierr = PetscObjectChangeTypeName((PetscObject)N,MATSUBMATRIX);CHKERRQ(ierr); 215ee1cef2cSJed Brown 216b00a9115SJed Brown ierr = PetscNewLog(N,&Na);CHKERRQ(ierr); 217ee1cef2cSJed Brown N->data = (void*)Na; 21811c5f74dSStefano Zampini 219ee1cef2cSJed Brown ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 220ee1cef2cSJed Brown ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 221ee1cef2cSJed Brown Na->isrow = isrow; 222ee1cef2cSJed Brown Na->iscol = iscol; 22311c5f74dSStefano Zampini 22411c5f74dSStefano Zampini ierr = PetscFree(N->defaultvectype);CHKERRQ(ierr); 22511c5f74dSStefano Zampini ierr = PetscStrallocpy(A->defaultvectype,&N->defaultvectype);CHKERRQ(ierr); 22611c5f74dSStefano Zampini /* Do not use MatConvert directly since MatShell has a duplicate operation which does not increase 22711c5f74dSStefano Zampini the reference count of the context. This is a problem if A is already of type MATSHELL */ 22811c5f74dSStefano Zampini ierr = MatConvertFrom_Shell(A,MATSHELL,MAT_INITIAL_MATRIX,&Na->A);CHKERRQ(ierr); 229ee1cef2cSJed Brown 230ee1cef2cSJed Brown N->ops->destroy = MatDestroy_SubMatrix; 231ee1cef2cSJed Brown N->ops->mult = MatMult_SubMatrix; 232ee1cef2cSJed Brown N->ops->multadd = MatMultAdd_SubMatrix; 233ee1cef2cSJed Brown N->ops->multtranspose = MatMultTranspose_SubMatrix; 234ee1cef2cSJed Brown N->ops->multtransposeadd = MatMultTransposeAdd_SubMatrix; 235ee1cef2cSJed Brown N->ops->scale = MatScale_SubMatrix; 236ee1cef2cSJed Brown N->ops->diagonalscale = MatDiagonalScale_SubMatrix; 237bddd1ffdSAlp Dener N->ops->shift = MatShift_SubMatrix; 23811c5f74dSStefano Zampini N->ops->convert = MatConvert_Shell; 23911c5f74dSStefano Zampini N->ops->getdiagonal = MatGetDiagonal_SubMatrix; 240ee1cef2cSJed Brown 24133d57670SJed Brown ierr = MatSetBlockSizesFromMats(N,A,A);CHKERRQ(ierr); 24226283091SBarry Smith ierr = PetscLayoutSetUp(N->rmap);CHKERRQ(ierr); 24326283091SBarry Smith ierr = PetscLayoutSetUp(N->cmap);CHKERRQ(ierr); 244ee1cef2cSJed Brown 2452a7a6963SBarry Smith ierr = MatCreateVecs(A,&Na->rwork,&Na->lwork);CHKERRQ(ierr); 24611c5f74dSStefano Zampini ierr = MatCreateVecs(N,&right,&left);CHKERRQ(ierr); 2479448b7f1SJunchao Zhang ierr = VecScatterCreate(Na->lwork,isrow,left,NULL,&Na->lrestrict);CHKERRQ(ierr); 2489448b7f1SJunchao Zhang ierr = VecScatterCreate(right,NULL,Na->rwork,iscol,&Na->rprolong);CHKERRQ(ierr); 2496bf464f9SBarry Smith ierr = VecDestroy(&left);CHKERRQ(ierr); 2506bf464f9SBarry Smith ierr = VecDestroy(&right);CHKERRQ(ierr); 251be7c243fSJed Brown ierr = MatSetUp(N);CHKERRQ(ierr); 25226fbe8dcSKarl Rupp 25311c5f74dSStefano Zampini N->assembled = PETSC_TRUE; 254ee1cef2cSJed Brown *newmat = N; 255ee1cef2cSJed Brown PetscFunctionReturn(0); 256ee1cef2cSJed Brown } 257ee1cef2cSJed Brown 258ee1cef2cSJed Brown /*@ 25954e05e6cSHong Zhang MatSubMatrixVirtualUpdate - Updates a submatrix 260ee1cef2cSJed Brown 261ee1cef2cSJed Brown Collective on Mat 262ee1cef2cSJed Brown 263ee1cef2cSJed Brown Input Parameters: 264ee1cef2cSJed Brown + N - submatrix to update 265ee1cef2cSJed Brown . A - full matrix in the submatrix 266ee1cef2cSJed Brown . isrow - rows in the update (same as the first time the submatrix was created) 267ee1cef2cSJed Brown - iscol - columns in the update (same as the first time the submatrix was created) 268ee1cef2cSJed Brown 269ee1cef2cSJed Brown Level: developer 270ee1cef2cSJed Brown 271ee1cef2cSJed Brown Notes: 2727dae84e0SHong Zhang Most will use MatCreateSubMatrix which provides a more efficient representation if it is available. 273ee1cef2cSJed Brown 27454e05e6cSHong Zhang .seealso: MatCreateSubMatrixVirtual() 275ee1cef2cSJed Brown @*/ 27654e05e6cSHong Zhang PetscErrorCode MatSubMatrixVirtualUpdate(Mat N,Mat A,IS isrow,IS iscol) 277ee1cef2cSJed Brown { 278ee1cef2cSJed Brown PetscErrorCode ierr; 279ace3abfcSBarry Smith PetscBool flg; 28054e05e6cSHong Zhang Mat_SubVirtual *Na; 281ee1cef2cSJed Brown 282ee1cef2cSJed Brown PetscFunctionBegin; 2830700a824SBarry Smith PetscValidHeaderSpecific(N,MAT_CLASSID,1); 2840700a824SBarry Smith PetscValidHeaderSpecific(A,MAT_CLASSID,2); 2850700a824SBarry Smith PetscValidHeaderSpecific(isrow,IS_CLASSID,3); 2860700a824SBarry Smith PetscValidHeaderSpecific(iscol,IS_CLASSID,4); 287251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)N,MATSUBMATRIX,&flg);CHKERRQ(ierr); 288*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix has wrong type"); 289ee1cef2cSJed Brown 29054e05e6cSHong Zhang Na = (Mat_SubVirtual*)N->data; 291ee1cef2cSJed Brown ierr = ISEqual(isrow,Na->isrow,&flg);CHKERRQ(ierr); 292*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot update submatrix with different row indices"); 293ee1cef2cSJed Brown ierr = ISEqual(iscol,Na->iscol,&flg);CHKERRQ(ierr); 294*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot update submatrix with different column indices"); 295ee1cef2cSJed Brown 29611c5f74dSStefano Zampini ierr = PetscFree(N->defaultvectype);CHKERRQ(ierr); 29711c5f74dSStefano Zampini ierr = PetscStrallocpy(A->defaultvectype,&N->defaultvectype);CHKERRQ(ierr); 2986bf464f9SBarry Smith ierr = MatDestroy(&Na->A);CHKERRQ(ierr); 29911c5f74dSStefano Zampini /* Do not use MatConvert directly since MatShell has a duplicate operation which does not increase 30011c5f74dSStefano Zampini the reference count of the context. This is a problem if A is already of type MATSHELL */ 30111c5f74dSStefano Zampini ierr = MatConvertFrom_Shell(A,MATSHELL,MAT_INITIAL_MATRIX,&Na->A);CHKERRQ(ierr); 302ee1cef2cSJed Brown PetscFunctionReturn(0); 303ee1cef2cSJed Brown } 304