xref: /petsc/src/mat/impls/submat/submat.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
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 
16bddd1ffdSAlp Dener   PetscFunctionBegin;
17*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatScale(Na->A,a));
18bddd1ffdSAlp Dener   PetscFunctionReturn(0);
19bddd1ffdSAlp Dener }
20bddd1ffdSAlp Dener 
21bddd1ffdSAlp Dener static PetscErrorCode MatShift_SubMatrix(Mat N,PetscScalar a)
22bddd1ffdSAlp Dener {
23bddd1ffdSAlp Dener   Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data;
24bddd1ffdSAlp Dener 
25bddd1ffdSAlp Dener   PetscFunctionBegin;
26*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatShift(Na->A,a));
27ee1cef2cSJed Brown   PetscFunctionReturn(0);
28ee1cef2cSJed Brown }
29ee1cef2cSJed Brown 
30ee1cef2cSJed Brown static PetscErrorCode MatDiagonalScale_SubMatrix(Mat N,Vec left,Vec right)
31ee1cef2cSJed Brown {
3254e05e6cSHong Zhang   Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data;
33ee1cef2cSJed Brown 
34ee1cef2cSJed Brown   PetscFunctionBegin;
35ee1cef2cSJed Brown   if (right) {
36*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecZeroEntries(Na->rwork));
37*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(Na->rprolong,right,Na->rwork,INSERT_VALUES,SCATTER_FORWARD));
38*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(Na->rprolong,right,Na->rwork,INSERT_VALUES,SCATTER_FORWARD));
39ee1cef2cSJed Brown   }
4011c5f74dSStefano Zampini   if (left) {
41*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecZeroEntries(Na->lwork));
42*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(Na->lrestrict,left,Na->lwork,INSERT_VALUES,SCATTER_REVERSE));
43*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(Na->lrestrict,left,Na->lwork,INSERT_VALUES,SCATTER_REVERSE));
44ee1cef2cSJed Brown   }
45*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDiagonalScale(Na->A,left ? Na->lwork : NULL,right ? Na->rwork : NULL));
4611c5f74dSStefano Zampini   PetscFunctionReturn(0);
4711c5f74dSStefano Zampini }
4811c5f74dSStefano Zampini 
4911c5f74dSStefano Zampini static PetscErrorCode MatGetDiagonal_SubMatrix(Mat N,Vec d)
5011c5f74dSStefano Zampini {
5111c5f74dSStefano Zampini   Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data;
5211c5f74dSStefano Zampini 
5311c5f74dSStefano Zampini   PetscFunctionBegin;
54*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetDiagonal(Na->A,Na->rwork));
55*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(Na->rprolong,Na->rwork,d,INSERT_VALUES,SCATTER_REVERSE));
56*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(Na->rprolong,Na->rwork,d,INSERT_VALUES,SCATTER_REVERSE));
57ee1cef2cSJed Brown   PetscFunctionReturn(0);
58ee1cef2cSJed Brown }
59ee1cef2cSJed Brown 
60ee1cef2cSJed Brown static PetscErrorCode MatMult_SubMatrix(Mat N,Vec x,Vec y)
61ee1cef2cSJed Brown {
6254e05e6cSHong Zhang   Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data;
63ee1cef2cSJed Brown 
64ee1cef2cSJed Brown   PetscFunctionBegin;
65*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecZeroEntries(Na->rwork));
66*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(Na->rprolong,x,Na->rwork,INSERT_VALUES,SCATTER_FORWARD));
67*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(Na->rprolong,x,Na->rwork,INSERT_VALUES,SCATTER_FORWARD));
68*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMult(Na->A,Na->rwork,Na->lwork));
69*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(Na->lrestrict,Na->lwork,y,INSERT_VALUES,SCATTER_FORWARD));
70*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(Na->lrestrict,Na->lwork,y,INSERT_VALUES,SCATTER_FORWARD));
71ee1cef2cSJed Brown   PetscFunctionReturn(0);
72ee1cef2cSJed Brown }
73ee1cef2cSJed Brown 
74ee1cef2cSJed Brown static PetscErrorCode MatMultAdd_SubMatrix(Mat N,Vec v1,Vec v2,Vec v3)
75ee1cef2cSJed Brown {
7654e05e6cSHong Zhang   Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data;
77ee1cef2cSJed Brown 
78ee1cef2cSJed Brown   PetscFunctionBegin;
79*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecZeroEntries(Na->rwork));
80*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(Na->rprolong,v1,Na->rwork,INSERT_VALUES,SCATTER_FORWARD));
81*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(Na->rprolong,v1,Na->rwork,INSERT_VALUES,SCATTER_FORWARD));
8211c5f74dSStefano Zampini   if (v1 == v2) {
83*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultAdd(Na->A,Na->rwork,Na->rwork,Na->lwork));
8411c5f74dSStefano Zampini   } else if (v2 == v3) {
85*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecZeroEntries(Na->lwork));
86*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(Na->lrestrict,v2,Na->lwork,INSERT_VALUES,SCATTER_REVERSE));
87*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(Na->lrestrict,v2,Na->lwork,INSERT_VALUES,SCATTER_REVERSE));
88*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultAdd(Na->A,Na->rwork,Na->lwork,Na->lwork));
891e7f0bbdSJed Brown   } else {
9011c5f74dSStefano Zampini     if (!Na->lwork2) {
91*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDuplicate(Na->lwork,&Na->lwork2));
9211c5f74dSStefano Zampini     } else {
93*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecZeroEntries(Na->lwork2));
9411c5f74dSStefano Zampini     }
95*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(Na->lrestrict,v2,Na->lwork2,INSERT_VALUES,SCATTER_REVERSE));
96*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(Na->lrestrict,v2,Na->lwork2,INSERT_VALUES,SCATTER_REVERSE));
97*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultAdd(Na->A,Na->rwork,Na->lwork2,Na->lwork));
9811c5f74dSStefano Zampini   }
99*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(Na->lrestrict,Na->lwork,v3,INSERT_VALUES,SCATTER_FORWARD));
100*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(Na->lrestrict,Na->lwork,v3,INSERT_VALUES,SCATTER_FORWARD));
101ee1cef2cSJed Brown   PetscFunctionReturn(0);
102ee1cef2cSJed Brown }
103ee1cef2cSJed Brown 
104ee1cef2cSJed Brown static PetscErrorCode MatMultTranspose_SubMatrix(Mat N,Vec x,Vec y)
105ee1cef2cSJed Brown {
10654e05e6cSHong Zhang   Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data;
107ee1cef2cSJed Brown 
108ee1cef2cSJed Brown   PetscFunctionBegin;
109*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecZeroEntries(Na->lwork));
110*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(Na->lrestrict,x,Na->lwork,INSERT_VALUES,SCATTER_REVERSE));
111*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(Na->lrestrict,x,Na->lwork,INSERT_VALUES,SCATTER_REVERSE));
112*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultTranspose(Na->A,Na->lwork,Na->rwork));
113*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(Na->rprolong,Na->rwork,y,INSERT_VALUES,SCATTER_REVERSE));
114*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(Na->rprolong,Na->rwork,y,INSERT_VALUES,SCATTER_REVERSE));
115ee1cef2cSJed Brown   PetscFunctionReturn(0);
116ee1cef2cSJed Brown }
117ee1cef2cSJed Brown 
118ee1cef2cSJed Brown static PetscErrorCode MatMultTransposeAdd_SubMatrix(Mat N,Vec v1,Vec v2,Vec v3)
119ee1cef2cSJed Brown {
12054e05e6cSHong Zhang   Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data;
121ee1cef2cSJed Brown 
122ee1cef2cSJed Brown   PetscFunctionBegin;
123*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecZeroEntries(Na->lwork));
124*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(Na->lrestrict,v1,Na->lwork,INSERT_VALUES,SCATTER_REVERSE));
125*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(Na->lrestrict,v1,Na->lwork,INSERT_VALUES,SCATTER_REVERSE));
12611c5f74dSStefano Zampini   if (v1 == v2) {
127*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultTransposeAdd(Na->A,Na->lwork,Na->lwork,Na->rwork));
12811c5f74dSStefano Zampini   } else if (v2 == v3) {
129*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecZeroEntries(Na->rwork));
130*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(Na->rprolong,v2,Na->rwork,INSERT_VALUES,SCATTER_FORWARD));
131*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(Na->rprolong,v2,Na->rwork,INSERT_VALUES,SCATTER_FORWARD));
132*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultTransposeAdd(Na->A,Na->lwork,Na->rwork,Na->rwork));
1331e7f0bbdSJed Brown   } else {
13411c5f74dSStefano Zampini     if (!Na->rwork2) {
135*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDuplicate(Na->rwork,&Na->rwork2));
13611c5f74dSStefano Zampini     } else {
137*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecZeroEntries(Na->rwork2));
13811c5f74dSStefano Zampini     }
139*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterBegin(Na->rprolong,v2,Na->rwork2,INSERT_VALUES,SCATTER_FORWARD));
140*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScatterEnd(Na->rprolong,v2,Na->rwork2,INSERT_VALUES,SCATTER_FORWARD));
141*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultTransposeAdd(Na->A,Na->lwork,Na->rwork2,Na->rwork));
14211c5f74dSStefano Zampini   }
143*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterBegin(Na->rprolong,Na->rwork,v3,INSERT_VALUES,SCATTER_REVERSE));
144*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterEnd(Na->rprolong,Na->rwork,v3,INSERT_VALUES,SCATTER_REVERSE));
145ee1cef2cSJed Brown   PetscFunctionReturn(0);
146ee1cef2cSJed Brown }
147ee1cef2cSJed Brown 
148ee1cef2cSJed Brown static PetscErrorCode MatDestroy_SubMatrix(Mat N)
149ee1cef2cSJed Brown {
15054e05e6cSHong Zhang   Mat_SubVirtual *Na = (Mat_SubVirtual*)N->data;
151ee1cef2cSJed Brown 
152ee1cef2cSJed Brown   PetscFunctionBegin;
153*5f80ce2aSJacob Faibussowitsch   CHKERRQ(ISDestroy(&Na->isrow));
154*5f80ce2aSJacob Faibussowitsch   CHKERRQ(ISDestroy(&Na->iscol));
155*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&Na->lwork));
156*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&Na->rwork));
157*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&Na->lwork2));
158*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&Na->rwork2));
159*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterDestroy(&Na->lrestrict));
160*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterDestroy(&Na->rprolong));
161*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&Na->A));
162*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(N->data));
163ee1cef2cSJed Brown   PetscFunctionReturn(0);
164ee1cef2cSJed Brown }
165ee1cef2cSJed Brown 
166ee1cef2cSJed Brown /*@
16754e05e6cSHong Zhang    MatCreateSubMatrixVirtual - Creates a virtual matrix that acts as a submatrix
168ee1cef2cSJed Brown 
169ee1cef2cSJed Brown    Collective on Mat
170ee1cef2cSJed Brown 
171ee1cef2cSJed Brown    Input Parameters:
172ee1cef2cSJed Brown +  A - matrix that we will extract a submatrix of
173ee1cef2cSJed Brown .  isrow - rows to be present in the submatrix
174ee1cef2cSJed Brown -  iscol - columns to be present in the submatrix
175ee1cef2cSJed Brown 
176ee1cef2cSJed Brown    Output Parameters:
177ee1cef2cSJed Brown .  newmat - new matrix
178ee1cef2cSJed Brown 
179ee1cef2cSJed Brown    Level: developer
180ee1cef2cSJed Brown 
181ee1cef2cSJed Brown    Notes:
1827dae84e0SHong Zhang    Most will use MatCreateSubMatrix which provides a more efficient representation if it is available.
183ee1cef2cSJed Brown 
18454e05e6cSHong Zhang .seealso: MatCreateSubMatrix(), MatSubMatrixVirtualUpdate()
185ee1cef2cSJed Brown @*/
18654e05e6cSHong Zhang PetscErrorCode MatCreateSubMatrixVirtual(Mat A,IS isrow,IS iscol,Mat *newmat)
187ee1cef2cSJed Brown {
188ee1cef2cSJed Brown   Vec            left,right;
189ee1cef2cSJed Brown   PetscInt       m,n;
190ee1cef2cSJed Brown   Mat            N;
19154e05e6cSHong Zhang   Mat_SubVirtual *Na;
192ee1cef2cSJed Brown 
193ee1cef2cSJed Brown   PetscFunctionBegin;
1940700a824SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1950700a824SBarry Smith   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
1960700a824SBarry Smith   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
197ee1cef2cSJed Brown   PetscValidPointer(newmat,4);
198f4259b30SLisandro Dalcin   *newmat = NULL;
199ee1cef2cSJed Brown 
200*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreate(PetscObjectComm((PetscObject)A),&N));
201*5f80ce2aSJacob Faibussowitsch   CHKERRQ(ISGetLocalSize(isrow,&m));
202*5f80ce2aSJacob Faibussowitsch   CHKERRQ(ISGetLocalSize(iscol,&n));
203*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetSizes(N,m,n,PETSC_DETERMINE,PETSC_DETERMINE));
204*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectChangeTypeName((PetscObject)N,MATSUBMATRIX));
205ee1cef2cSJed Brown 
206*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNewLog(N,&Na));
207ee1cef2cSJed Brown   N->data   = (void*)Na;
20811c5f74dSStefano Zampini 
209*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectReference((PetscObject)isrow));
210*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectReference((PetscObject)iscol));
211ee1cef2cSJed Brown   Na->isrow = isrow;
212ee1cef2cSJed Brown   Na->iscol = iscol;
21311c5f74dSStefano Zampini 
214*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(N->defaultvectype));
215*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrallocpy(A->defaultvectype,&N->defaultvectype));
21611c5f74dSStefano Zampini   /* Do not use MatConvert directly since MatShell has a duplicate operation which does not increase
21711c5f74dSStefano Zampini      the reference count of the context. This is a problem if A is already of type MATSHELL */
218*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvertFrom_Shell(A,MATSHELL,MAT_INITIAL_MATRIX,&Na->A));
219ee1cef2cSJed Brown 
220ee1cef2cSJed Brown   N->ops->destroy          = MatDestroy_SubMatrix;
221ee1cef2cSJed Brown   N->ops->mult             = MatMult_SubMatrix;
222ee1cef2cSJed Brown   N->ops->multadd          = MatMultAdd_SubMatrix;
223ee1cef2cSJed Brown   N->ops->multtranspose    = MatMultTranspose_SubMatrix;
224ee1cef2cSJed Brown   N->ops->multtransposeadd = MatMultTransposeAdd_SubMatrix;
225ee1cef2cSJed Brown   N->ops->scale            = MatScale_SubMatrix;
226ee1cef2cSJed Brown   N->ops->diagonalscale    = MatDiagonalScale_SubMatrix;
227bddd1ffdSAlp Dener   N->ops->shift            = MatShift_SubMatrix;
22811c5f74dSStefano Zampini   N->ops->convert          = MatConvert_Shell;
22911c5f74dSStefano Zampini   N->ops->getdiagonal      = MatGetDiagonal_SubMatrix;
230ee1cef2cSJed Brown 
231*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetBlockSizesFromMats(N,A,A));
232*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscLayoutSetUp(N->rmap));
233*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscLayoutSetUp(N->cmap));
234ee1cef2cSJed Brown 
235*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateVecs(A,&Na->rwork,&Na->lwork));
236*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateVecs(N,&right,&left));
237*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterCreate(Na->lwork,isrow,left,NULL,&Na->lrestrict));
238*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScatterCreate(right,NULL,Na->rwork,iscol,&Na->rprolong));
239*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&left));
240*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&right));
241*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetUp(N));
24226fbe8dcSKarl Rupp 
24311c5f74dSStefano Zampini   N->assembled = PETSC_TRUE;
244ee1cef2cSJed Brown   *newmat      = N;
245ee1cef2cSJed Brown   PetscFunctionReturn(0);
246ee1cef2cSJed Brown }
247ee1cef2cSJed Brown 
248ee1cef2cSJed Brown /*@
24954e05e6cSHong Zhang    MatSubMatrixVirtualUpdate - Updates a submatrix
250ee1cef2cSJed Brown 
251ee1cef2cSJed Brown    Collective on Mat
252ee1cef2cSJed Brown 
253ee1cef2cSJed Brown    Input Parameters:
254ee1cef2cSJed Brown +  N - submatrix to update
255ee1cef2cSJed Brown .  A - full matrix in the submatrix
256ee1cef2cSJed Brown .  isrow - rows in the update (same as the first time the submatrix was created)
257ee1cef2cSJed Brown -  iscol - columns in the update (same as the first time the submatrix was created)
258ee1cef2cSJed Brown 
259ee1cef2cSJed Brown    Level: developer
260ee1cef2cSJed Brown 
261ee1cef2cSJed Brown    Notes:
2627dae84e0SHong Zhang    Most will use MatCreateSubMatrix which provides a more efficient representation if it is available.
263ee1cef2cSJed Brown 
26454e05e6cSHong Zhang .seealso: MatCreateSubMatrixVirtual()
265ee1cef2cSJed Brown @*/
26654e05e6cSHong Zhang PetscErrorCode  MatSubMatrixVirtualUpdate(Mat N,Mat A,IS isrow,IS iscol)
267ee1cef2cSJed Brown {
268ace3abfcSBarry Smith   PetscBool      flg;
26954e05e6cSHong Zhang   Mat_SubVirtual *Na;
270ee1cef2cSJed Brown 
271ee1cef2cSJed Brown   PetscFunctionBegin;
2720700a824SBarry Smith   PetscValidHeaderSpecific(N,MAT_CLASSID,1);
2730700a824SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,2);
2740700a824SBarry Smith   PetscValidHeaderSpecific(isrow,IS_CLASSID,3);
2750700a824SBarry Smith   PetscValidHeaderSpecific(iscol,IS_CLASSID,4);
276*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)N,MATSUBMATRIX,&flg));
2772c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix has wrong type");
278ee1cef2cSJed Brown 
27954e05e6cSHong Zhang   Na   = (Mat_SubVirtual*)N->data;
280*5f80ce2aSJacob Faibussowitsch   CHKERRQ(ISEqual(isrow,Na->isrow,&flg));
2812c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot update submatrix with different row indices");
282*5f80ce2aSJacob Faibussowitsch   CHKERRQ(ISEqual(iscol,Na->iscol,&flg));
2832c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot update submatrix with different column indices");
284ee1cef2cSJed Brown 
285*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(N->defaultvectype));
286*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrallocpy(A->defaultvectype,&N->defaultvectype));
287*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&Na->A));
28811c5f74dSStefano Zampini   /* Do not use MatConvert directly since MatShell has a duplicate operation which does not increase
28911c5f74dSStefano Zampini      the reference count of the context. This is a problem if A is already of type MATSHELL */
290*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatConvertFrom_Shell(A,MATSHELL,MAT_INITIAL_MATRIX,&Na->A));
291ee1cef2cSJed Brown   PetscFunctionReturn(0);
292ee1cef2cSJed Brown }
293