xref: /petsc/src/mat/impls/sbaij/seq/aijsbaij.c (revision 701b2c3ffa9ad67f0aad350c7a294c28d93c2ea1)
159557b74SHong Zhang 
2c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>
3c6db04a5SJed Brown #include <../src/mat/impls/baij/seq/baij.h>
4c6db04a5SJed Brown #include <../src/mat/impls/sbaij/seq/sbaij.h>
559557b74SHong Zhang 
659557b74SHong Zhang EXTERN_C_BEGIN
759557b74SHong Zhang #undef __FUNCT__
84124e67cSShri Abhyankar #define __FUNCT__ "MatConvert_SeqSBAIJ_SeqAIJ"
97087cfbeSBarry Smith PetscErrorCode  MatConvert_SeqSBAIJ_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
104e5e7fe4SHong Zhang {
114e5e7fe4SHong Zhang   Mat            B;
124e5e7fe4SHong Zhang   Mat_SeqSBAIJ   *a = (Mat_SeqSBAIJ*)A->data;
134e5e7fe4SHong Zhang   Mat_SeqAIJ     *b;
14dfbe8321SBarry Smith   PetscErrorCode ierr;
15d0f46423SBarry Smith   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->n,i,j,k,*bi,*bj,*rowlengths,nz,*rowstart,itmp;
1601be0148SBarry Smith   PetscInt       bs=A->rmap->bs,bs2=bs*bs,mbs=A->rmap->N/bs,diagcnt=0;
17dd6ea824SBarry Smith   MatScalar      *av,*bv;
184e5e7fe4SHong Zhang 
194e5e7fe4SHong Zhang   PetscFunctionBegin;
204e5e7fe4SHong Zhang   /* compute rowlengths of newmat */
2174ed9c26SBarry Smith   ierr = PetscMalloc2(m,PetscInt,&rowlengths,m+1,PetscInt,&rowstart);CHKERRQ(ierr);
22a7a3a9ebSHong Zhang 
23a7a3a9ebSHong Zhang   for (i=0; i<mbs; i++) rowlengths[i*bs] = 0;
244e5e7fe4SHong Zhang   aj = a->j;
25a7a3a9ebSHong Zhang   k = 0;
26a7a3a9ebSHong Zhang   for (i=0; i<mbs; i++) {
274e5e7fe4SHong Zhang     nz = ai[i+1] - ai[i];
2801be0148SBarry Smith     if (nz) {
2901be0148SBarry Smith       rowlengths[k] += nz;   /* no. of upper triangular blocks */
3001be0148SBarry Smith       if (*aj == i) {aj++;diagcnt++;nz--;} /* skip diagonal */
3101be0148SBarry Smith       for (j=0; j<nz; j++) { /* no. of lower triangular blocks */
32a7a3a9ebSHong Zhang 	rowlengths[(*aj)*bs]++; aj++;
33a7a3a9ebSHong Zhang       }
3401be0148SBarry Smith     }
35a7a3a9ebSHong Zhang     rowlengths[k] *= bs;
36a7a3a9ebSHong Zhang     for (j=1; j<bs; j++) {
37a7a3a9ebSHong Zhang       rowlengths[k+j] = rowlengths[k];
38a7a3a9ebSHong Zhang     }
39a7a3a9ebSHong Zhang     k += bs;
40a7a3a9ebSHong Zhang     /* printf(" rowlengths[%d]: %d\n",i, rowlengths[i]); */
414e5e7fe4SHong Zhang   }
424e5e7fe4SHong Zhang 
437adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
44f69a0ea3SMatthew Knepley   ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
45f204ca49SKris Buschelman   ierr = MatSetType(B,newtype);CHKERRQ(ierr);
46f204ca49SKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr);
474e0d8c25SBarry Smith   ierr = MatSetOption(B,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
48d0f46423SBarry Smith   B->rmap->bs = A->rmap->bs;
494e5e7fe4SHong Zhang 
504e5e7fe4SHong Zhang   b  = (Mat_SeqAIJ*)(B->data);
514e5e7fe4SHong Zhang   bi = b->i;
524e5e7fe4SHong Zhang   bj = b->j;
534e5e7fe4SHong Zhang   bv = b->a;
544e5e7fe4SHong Zhang 
554e5e7fe4SHong Zhang   /* set b->i */
56a7a3a9ebSHong Zhang   bi[0] = 0; rowstart[0] = 0;
57a7a3a9ebSHong Zhang   for (i=0; i<mbs; i++){
58a7a3a9ebSHong Zhang     for (j=0; j<bs; j++){
59a7a3a9ebSHong Zhang       b->ilen[i*bs+j]    = rowlengths[i*bs];
60a7a3a9ebSHong Zhang       rowstart[i*bs+j+1] = rowstart[i*bs+j] + rowlengths[i*bs];
614e5e7fe4SHong Zhang     }
62a7a3a9ebSHong Zhang     bi[i+1]     = bi[i] + rowlengths[i*bs]/bs;
63a7a3a9ebSHong Zhang   }
6401be0148SBarry Smith   if (bi[mbs] != 2*a->nz - diagcnt) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"bi[mbs]: %D != 2*a->nz-diagcnt: %D\n",bi[mbs],2*a->nz - diagcnt);
654e5e7fe4SHong Zhang 
664e5e7fe4SHong Zhang   /* set b->j and b->a */
674e5e7fe4SHong Zhang   aj = a->j; av = a->a;
68a7a3a9ebSHong Zhang   for (i=0; i<mbs; i++) {
6901be0148SBarry Smith     nz = ai[i+1] - ai[i];
70a7a3a9ebSHong Zhang     /* diagonal block */
7101be0148SBarry Smith     if (nz && *aj == i) {
7201be0148SBarry Smith       nz--;
73a7a3a9ebSHong Zhang       for (j=0; j<bs; j++){   /* row i*bs+j */
74a7a3a9ebSHong Zhang 	itmp = i*bs+j;
75a7a3a9ebSHong Zhang 	for (k=0; k<bs; k++){ /* col i*bs+k */
76a7a3a9ebSHong Zhang 	  *(bj + rowstart[itmp]) = (*aj)*bs+k;
77a7a3a9ebSHong Zhang 	  *(bv + rowstart[itmp]) = *(av+k*bs+j);
78a7a3a9ebSHong Zhang 	  rowstart[itmp]++;
79a7a3a9ebSHong Zhang 	}
80a7a3a9ebSHong Zhang       }
81a7a3a9ebSHong Zhang       aj++; av += bs2;
8201be0148SBarry Smith     }
83a7a3a9ebSHong Zhang 
844e5e7fe4SHong Zhang     while (nz--){
85a7a3a9ebSHong Zhang       /* lower triangular blocks */
86a7a3a9ebSHong Zhang       for (j=0; j<bs; j++){   /* row (*aj)*bs+j */
87a7a3a9ebSHong Zhang         itmp = (*aj)*bs+j;
88a7a3a9ebSHong Zhang         for (k=0; k<bs; k++){ /* col i*bs+k */
89a7a3a9ebSHong Zhang           *(bj + rowstart[itmp]) = i*bs+k;
903bededecSBarry Smith           *(bv + rowstart[itmp]) = *(av+j*bs+k);
91a7a3a9ebSHong Zhang           rowstart[itmp]++;
92a7a3a9ebSHong Zhang         }
93a7a3a9ebSHong Zhang       }
94a7a3a9ebSHong Zhang       /* upper triangular blocks */
95a7a3a9ebSHong Zhang       for (j=0; j<bs; j++){   /* row i*bs+j */
96a7a3a9ebSHong Zhang         itmp = i*bs+j;
97a7a3a9ebSHong Zhang         for (k=0; k<bs; k++){ /* col (*aj)*bs+k */
98a7a3a9ebSHong Zhang           *(bj + rowstart[itmp]) = (*aj)*bs+k;
99a7a3a9ebSHong Zhang           *(bv + rowstart[itmp]) = *(av+k*bs+j);
100a7a3a9ebSHong Zhang           rowstart[itmp]++;
101a7a3a9ebSHong Zhang         }
102a7a3a9ebSHong Zhang       }
103a7a3a9ebSHong Zhang       aj++; av += bs2;
1044e5e7fe4SHong Zhang     }
1054e5e7fe4SHong Zhang   }
10674ed9c26SBarry Smith   ierr = PetscFree2(rowlengths,rowstart);CHKERRQ(ierr);
1074e5e7fe4SHong Zhang   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1084e5e7fe4SHong Zhang   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1094e5e7fe4SHong Zhang 
110ceb03754SKris Buschelman   if (reuse == MAT_REUSE_MATRIX) {
1118ab5b326SKris Buschelman     ierr = MatHeaderReplace(A,B);CHKERRQ(ierr);
112c3d102feSKris Buschelman   } else {
1134e5e7fe4SHong Zhang     *newmat = B;
114c3d102feSKris Buschelman   }
1154e5e7fe4SHong Zhang   PetscFunctionReturn(0);
1164e5e7fe4SHong Zhang }
117be1d678aSKris Buschelman EXTERN_C_END
118be1d678aSKris Buschelman 
119be1d678aSKris Buschelman EXTERN_C_BEGIN
1204e5e7fe4SHong Zhang #undef __FUNCT__
12159557b74SHong Zhang #define __FUNCT__ "MatConvert_SeqAIJ_SeqSBAIJ"
1227087cfbeSBarry Smith PetscErrorCode  MatConvert_SeqAIJ_SeqSBAIJ(Mat A,const MatType newtype,MatReuse reuse,Mat *newmat) {
123676c34cdSKris Buschelman   Mat            B;
12459557b74SHong Zhang   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
125861ba921SHong Zhang   Mat_SeqSBAIJ   *b;
126dfbe8321SBarry Smith   PetscErrorCode ierr;
127d0f46423SBarry Smith   PetscInt       *ai=a->i,*aj,m=A->rmap->N,n=A->cmap->N,i,j,*bi,*bj,*rowlengths;
128dd6ea824SBarry Smith   MatScalar      *av,*bv;
12959557b74SHong Zhang 
13059557b74SHong Zhang   PetscFunctionBegin;
131*701b2c3fSHong Zhang   if (!A->symmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_USER,"Matrix must be symmetric. Call MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)");
132e32f2f54SBarry Smith   if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Matrix must be square");
13359557b74SHong Zhang 
13413f74950SBarry Smith   ierr = PetscMalloc(m*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr);
13559557b74SHong Zhang   for (i=0; i<m; i++) {
13659557b74SHong Zhang     rowlengths[i] = ai[i+1] - a->diag[i];
13759557b74SHong Zhang   }
1387adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
139f69a0ea3SMatthew Knepley   ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
140f204ca49SKris Buschelman   ierr = MatSetType(B,newtype);CHKERRQ(ierr);
141ab93d7beSBarry Smith   ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(B,1,0,rowlengths);CHKERRQ(ierr);
14259557b74SHong Zhang 
1434e0d8c25SBarry Smith   ierr = MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
14459557b74SHong Zhang 
145676c34cdSKris Buschelman   b  = (Mat_SeqSBAIJ*)(B->data);
146861ba921SHong Zhang   bi = b->i;
147861ba921SHong Zhang   bj = b->j;
148861ba921SHong Zhang   bv = b->a;
149861ba921SHong Zhang 
150861ba921SHong Zhang   bi[0] = 0;
15159557b74SHong Zhang   for (i=0; i<m; i++) {
15259557b74SHong Zhang     aj = a->j + a->diag[i];
15359557b74SHong Zhang     av = a->a + a->diag[i];
154861ba921SHong Zhang     for (j=0; j<rowlengths[i]; j++){
155861ba921SHong Zhang       *bj = *aj; bj++; aj++;
156861ba921SHong Zhang       *bv = *av; bv++; av++;
157861ba921SHong Zhang     }
158861ba921SHong Zhang     bi[i+1]    = bi[i] + rowlengths[i];
159861ba921SHong Zhang     b->ilen[i] = rowlengths[i];
16059557b74SHong Zhang   }
16159557b74SHong Zhang 
16259557b74SHong Zhang   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
163676c34cdSKris Buschelman   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
164676c34cdSKris Buschelman   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
165eeffb40dSHong Zhang   if (A->hermitian){
166eeffb40dSHong Zhang     ierr = MatSetOption(B,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
167eeffb40dSHong Zhang   }
168676c34cdSKris Buschelman 
169ceb03754SKris Buschelman   if (reuse == MAT_REUSE_MATRIX) {
1708ab5b326SKris Buschelman     ierr = MatHeaderReplace(A,B);CHKERRQ(ierr);
171c3d102feSKris Buschelman   } else {
172676c34cdSKris Buschelman     *newmat = B;
173c3d102feSKris Buschelman   }
17459557b74SHong Zhang   PetscFunctionReturn(0);
17559557b74SHong Zhang }
17659557b74SHong Zhang EXTERN_C_END
17759557b74SHong Zhang 
178a0e1a404SHong Zhang EXTERN_C_BEGIN
179a0e1a404SHong Zhang #undef __FUNCT__
1807af9e4fdSHong Zhang #define __FUNCT__ "MatConvert_SeqSBAIJ_SeqBAIJ"
1817087cfbeSBarry Smith PetscErrorCode  MatConvert_SeqSBAIJ_SeqBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
182a0e1a404SHong Zhang {
183a0e1a404SHong Zhang   Mat            B;
184a0e1a404SHong Zhang   Mat_SeqSBAIJ   *a = (Mat_SeqSBAIJ*)A->data;
185a0e1a404SHong Zhang   Mat_SeqBAIJ    *b;
186dfbe8321SBarry Smith   PetscErrorCode ierr;
187d0f46423SBarry Smith   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->n,i,k,*bi,*bj,*browlengths,nz,*browstart,itmp;
18874ee4d9fSHong Zhang   PetscInt       bs=A->rmap->bs,bs2=bs*bs,mbs=m/bs,col,row;
189dd6ea824SBarry Smith   MatScalar      *av,*bv;
190a0e1a404SHong Zhang 
191a0e1a404SHong Zhang   PetscFunctionBegin;
192a0e1a404SHong Zhang   /* compute browlengths of newmat */
19374ed9c26SBarry Smith   ierr = PetscMalloc2(mbs,PetscInt,&browlengths,mbs,PetscInt,&browstart);CHKERRQ(ierr);
194a0e1a404SHong Zhang   for (i=0; i<mbs; i++) browlengths[i] = 0;
195a0e1a404SHong Zhang   aj = a->j;
196a0e1a404SHong Zhang   for (i=0; i<mbs; i++) {
197a0e1a404SHong Zhang     nz = ai[i+1] - ai[i];
198a0e1a404SHong Zhang     aj++; /* skip diagonal */
199a0e1a404SHong Zhang     for (k=1; k<nz; k++) { /* no. of lower triangular blocks */
200a0e1a404SHong Zhang       browlengths[*aj]++; aj++;
201a0e1a404SHong Zhang     }
202a0e1a404SHong Zhang     browlengths[i] += nz;   /* no. of upper triangular blocks */
203a0e1a404SHong Zhang   }
204a0e1a404SHong Zhang 
2057adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
206f69a0ea3SMatthew Knepley   ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
207f204ca49SKris Buschelman   ierr = MatSetType(B,newtype);CHKERRQ(ierr);
208f204ca49SKris Buschelman   ierr = MatSeqBAIJSetPreallocation(B,bs,0,browlengths);CHKERRQ(ierr);
2094e0d8c25SBarry Smith   ierr = MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
210a0e1a404SHong Zhang 
211a0e1a404SHong Zhang   b  = (Mat_SeqBAIJ*)(B->data);
212a0e1a404SHong Zhang   bi = b->i;
213a0e1a404SHong Zhang   bj = b->j;
214a0e1a404SHong Zhang   bv = b->a;
215a0e1a404SHong Zhang 
216a0e1a404SHong Zhang   /* set b->i */
217a0e1a404SHong Zhang   bi[0] = 0;
218a0e1a404SHong Zhang   for (i=0; i<mbs; i++){
219a0e1a404SHong Zhang     b->ilen[i]   = browlengths[i];
220a0e1a404SHong Zhang     bi[i+1]      = bi[i] + browlengths[i];
221a0e1a404SHong Zhang     browstart[i] = bi[i];
222a0e1a404SHong Zhang   }
223e32f2f54SBarry Smith   if (bi[mbs] != 2*a->nz - mbs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"bi[mbs]: %D != 2*a->nz - mbs: %D\n",bi[mbs],2*a->nz - mbs);
224a0e1a404SHong Zhang 
225a0e1a404SHong Zhang   /* set b->j and b->a */
226a0e1a404SHong Zhang   aj = a->j; av = a->a;
227a0e1a404SHong Zhang   for (i=0; i<mbs; i++) {
228a0e1a404SHong Zhang     /* diagonal block */
229a0e1a404SHong Zhang     *(bj + browstart[i]) = *aj; aj++;
230a0e1a404SHong Zhang     itmp = bs2*browstart[i];
231a0e1a404SHong Zhang     for (k=0; k<bs2; k++){
232a0e1a404SHong Zhang       *(bv + itmp + k) = *av; av++;
233a0e1a404SHong Zhang     }
234a0e1a404SHong Zhang     browstart[i]++;
235a0e1a404SHong Zhang 
236a0e1a404SHong Zhang     nz = ai[i+1] - ai[i] -1;
237a0e1a404SHong Zhang     while (nz--){
23874ee4d9fSHong Zhang       /* lower triangular blocks - transpose blocks of A */
23974ee4d9fSHong Zhang       *(bj + browstart[*aj]) = i; /* block col index */
24074ee4d9fSHong Zhang       itmp = bs2*browstart[*aj];  /* row index */
24174ee4d9fSHong Zhang       for (col=0; col<bs; col++){
24274ee4d9fSHong Zhang         k = col;
24374ee4d9fSHong Zhang         for (row=0; row<bs; row++){
24474ee4d9fSHong Zhang           bv[itmp + col*bs+row] = av[k]; k+=bs;
24574ee4d9fSHong Zhang         }
246a0e1a404SHong Zhang       }
247a0e1a404SHong Zhang       browstart[*aj]++;
248a0e1a404SHong Zhang 
249a0e1a404SHong Zhang       /* upper triangular blocks */
250a0e1a404SHong Zhang       *(bj + browstart[i]) = *aj; aj++;
251a0e1a404SHong Zhang       itmp = bs2*browstart[i];
252a0e1a404SHong Zhang       for (k=0; k<bs2; k++){
25374ee4d9fSHong Zhang         bv[itmp + k] = av[k];
254a0e1a404SHong Zhang       }
25574ee4d9fSHong Zhang       av += bs2;
256a0e1a404SHong Zhang       browstart[i]++;
257a0e1a404SHong Zhang     }
258a0e1a404SHong Zhang   }
25974ed9c26SBarry Smith   ierr = PetscFree2(browlengths,browstart);CHKERRQ(ierr);
260a0e1a404SHong Zhang   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
261a0e1a404SHong Zhang   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
262a0e1a404SHong Zhang 
263ceb03754SKris Buschelman   if (reuse == MAT_REUSE_MATRIX) {
2648ab5b326SKris Buschelman     ierr = MatHeaderReplace(A,B);CHKERRQ(ierr);
265c3d102feSKris Buschelman   } else {
266a0e1a404SHong Zhang     *newmat = B;
267c3d102feSKris Buschelman   }
268a0e1a404SHong Zhang   PetscFunctionReturn(0);
269a0e1a404SHong Zhang }
270be1d678aSKris Buschelman EXTERN_C_END
271be1d678aSKris Buschelman 
272be1d678aSKris Buschelman EXTERN_C_BEGIN
273a0e1a404SHong Zhang #undef __FUNCT__
274a0e1a404SHong Zhang #define __FUNCT__ "MatConvert_SeqBAIJ_SeqSBAIJ"
2757087cfbeSBarry Smith PetscErrorCode  MatConvert_SeqBAIJ_SeqSBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
276a0e1a404SHong Zhang {
277a0e1a404SHong Zhang   Mat            B;
278a0e1a404SHong Zhang   Mat_SeqBAIJ    *a = (Mat_SeqBAIJ*)A->data;
279a0e1a404SHong Zhang   Mat_SeqSBAIJ   *b;
280dfbe8321SBarry Smith   PetscErrorCode ierr;
281d0f46423SBarry Smith   PetscInt       *ai=a->i,*aj,m=A->rmap->N,n=A->cmap->n,i,j,k,*bi,*bj,*browlengths;
282d0f46423SBarry Smith   PetscInt       bs=A->rmap->bs,bs2=bs*bs,mbs=m/bs,dd;
283dd6ea824SBarry Smith   MatScalar      *av,*bv;
284ace3abfcSBarry Smith   PetscBool      flg;
285a0e1a404SHong Zhang 
286a0e1a404SHong Zhang   PetscFunctionBegin;
287*701b2c3fSHong Zhang   if (!A->symmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_USER,"Matrix must be symmetric. Call MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)");
288e32f2f54SBarry Smith   if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2892af78befSBarry Smith   ierr = MatMissingDiagonal_SeqBAIJ(A,&flg,&dd);CHKERRQ(ierr); /* check for missing diagonals, then mark diag */
290e32f2f54SBarry Smith   if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal %D",dd);
291a0e1a404SHong Zhang 
29213f74950SBarry Smith   ierr = PetscMalloc(mbs*sizeof(PetscInt),&browlengths);CHKERRQ(ierr);
293a0e1a404SHong Zhang   for (i=0; i<mbs; i++) {
294a0e1a404SHong Zhang     browlengths[i] = ai[i+1] - a->diag[i];
295a0e1a404SHong Zhang   }
296a0e1a404SHong Zhang 
2977adad957SLisandro Dalcin   ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr);
298f69a0ea3SMatthew Knepley   ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
299f204ca49SKris Buschelman   ierr = MatSetType(B,newtype);CHKERRQ(ierr);
300ab93d7beSBarry Smith   ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(B,bs,0,browlengths);CHKERRQ(ierr);
3014e0d8c25SBarry Smith   ierr = MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
302a0e1a404SHong Zhang 
303a0e1a404SHong Zhang   b  = (Mat_SeqSBAIJ*)(B->data);
304a0e1a404SHong Zhang   bi = b->i;
305a0e1a404SHong Zhang   bj = b->j;
306a0e1a404SHong Zhang   bv = b->a;
307a0e1a404SHong Zhang 
308a0e1a404SHong Zhang   bi[0] = 0;
309a0e1a404SHong Zhang   for (i=0; i<mbs; i++) {
310a0e1a404SHong Zhang     aj = a->j + a->diag[i];
311a0e1a404SHong Zhang     av = a->a + (a->diag[i])*bs2;
312a0e1a404SHong Zhang     for (j=0; j<browlengths[i]; j++){
313a0e1a404SHong Zhang       *bj = *aj; bj++; aj++;
314a0e1a404SHong Zhang       for (k=0; k<bs2; k++){
315a0e1a404SHong Zhang         *bv = *av; bv++; av++;
316a0e1a404SHong Zhang       }
317a0e1a404SHong Zhang     }
318a0e1a404SHong Zhang     bi[i+1]    = bi[i] + browlengths[i];
319a0e1a404SHong Zhang     b->ilen[i] = browlengths[i];
320a0e1a404SHong Zhang   }
321a0e1a404SHong Zhang   ierr = PetscFree(browlengths);CHKERRQ(ierr);
322a0e1a404SHong Zhang   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
323a0e1a404SHong Zhang   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
324a0e1a404SHong Zhang 
325ceb03754SKris Buschelman   if (reuse == MAT_REUSE_MATRIX) {
3268ab5b326SKris Buschelman     ierr = MatHeaderReplace(A,B);CHKERRQ(ierr);
327c3d102feSKris Buschelman   } else {
328a0e1a404SHong Zhang     *newmat = B;
329c3d102feSKris Buschelman   }
330a0e1a404SHong Zhang 
331a0e1a404SHong Zhang   PetscFunctionReturn(0);
332a0e1a404SHong Zhang }
333a0e1a404SHong Zhang EXTERN_C_END
334