xref: /petsc/src/mat/impls/sbaij/seq/aijsbaij.c (revision 521d725246dfa58045cedb83828e8a3e8852731d)
159557b74SHong Zhang 
259557b74SHong Zhang #include "src/mat/impls/aij/seq/aij.h"
3595208bcSHong Zhang #include "src/mat/impls/baij/seq/baij.h"
4861ba921SHong Zhang #include "src/mat/impls/sbaij/seq/sbaij.h"
559557b74SHong Zhang 
659557b74SHong Zhang EXTERN_C_BEGIN
759557b74SHong Zhang #undef __FUNCT__
84e5e7fe4SHong Zhang #define __FUNCT__ "MatConvert_SeqSBAI_SeqAIJ"
9dfbe8321SBarry Smith PetscErrorCode MatConvert_SeqSBAIJ_SeqAIJ(Mat A,const MatType newtype,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;
15dfbe8321SBarry Smith   int *ai=a->i,*aj=a->j,m=A->m,n=A->n,i,j,k,*bi,*bj,
16a7a3a9ebSHong Zhang                *rowlengths,nz,*rowstart,itmp;
17*521d7252SBarry Smith   int          bs=A->bs,bs2=bs*bs,mbs=A->m/bs;
184e5e7fe4SHong Zhang   PetscScalar  *av,*bv;
194e5e7fe4SHong Zhang 
204e5e7fe4SHong Zhang   PetscFunctionBegin;
21a7a3a9ebSHong Zhang 
224e5e7fe4SHong Zhang   /* compute rowlengths of newmat */
23a7a3a9ebSHong Zhang   ierr = PetscMalloc((2*m+1)*sizeof(int),&rowlengths);CHKERRQ(ierr);
24a7a3a9ebSHong Zhang   rowstart = rowlengths + m;
25a7a3a9ebSHong Zhang 
26a7a3a9ebSHong Zhang   for (i=0; i<mbs; i++) rowlengths[i*bs] = 0;
274e5e7fe4SHong Zhang   aj = a->j;
28a7a3a9ebSHong Zhang   k = 0;
29a7a3a9ebSHong Zhang   for (i=0; i<mbs; i++) {
304e5e7fe4SHong Zhang     nz = ai[i+1] - ai[i];
31a7a3a9ebSHong Zhang     aj++; /* skip diagonal */
32a7a3a9ebSHong Zhang     for (j=1; j<nz; j++) { /* no. of lower triangular blocks */
33a7a3a9ebSHong Zhang       rowlengths[(*aj)*bs]++; aj++;
34a7a3a9ebSHong Zhang     }
35a7a3a9ebSHong Zhang     rowlengths[k] += nz;   /* no. of upper triangular blocks */
36a7a3a9ebSHong Zhang     rowlengths[k] *= bs;
37a7a3a9ebSHong Zhang     for (j=1; j<bs; j++) {
38a7a3a9ebSHong Zhang       rowlengths[k+j] = rowlengths[k];
39a7a3a9ebSHong Zhang     }
40a7a3a9ebSHong Zhang     k += bs;
41a7a3a9ebSHong Zhang     /* printf(" rowlengths[%d]: %d\n",i, rowlengths[i]); */
424e5e7fe4SHong Zhang   }
434e5e7fe4SHong Zhang 
44f204ca49SKris Buschelman   ierr = MatCreate(A->comm,m,n,m,n,&B);CHKERRQ(ierr);
45f204ca49SKris Buschelman   ierr = MatSetType(B,newtype);CHKERRQ(ierr);
46f204ca49SKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr);
47a7a3a9ebSHong Zhang   ierr = MatSetOption(B,MAT_COLUMN_ORIENTED);CHKERRQ(ierr);
484e5e7fe4SHong Zhang   ierr = MatSetOption(B,MAT_ROWS_SORTED);CHKERRQ(ierr);
494e5e7fe4SHong Zhang   ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr);
50*521d7252SBarry Smith   B->bs = A->bs;
514e5e7fe4SHong Zhang 
524e5e7fe4SHong Zhang   b  = (Mat_SeqAIJ*)(B->data);
534e5e7fe4SHong Zhang   bi = b->i;
544e5e7fe4SHong Zhang   bj = b->j;
554e5e7fe4SHong Zhang   bv = b->a;
564e5e7fe4SHong Zhang 
574e5e7fe4SHong Zhang   /* set b->i */
58a7a3a9ebSHong Zhang   bi[0] = 0; rowstart[0] = 0;
59a7a3a9ebSHong Zhang   for (i=0; i<mbs; i++){
60a7a3a9ebSHong Zhang     for (j=0; j<bs; j++){
61a7a3a9ebSHong Zhang       b->ilen[i*bs+j]  = rowlengths[i*bs];
62a7a3a9ebSHong Zhang       rowstart[i*bs+j+1] = rowstart[i*bs+j] + rowlengths[i*bs];
634e5e7fe4SHong Zhang     }
64a7a3a9ebSHong Zhang     bi[i+1]     = bi[i] + rowlengths[i*bs]/bs;
65a7a3a9ebSHong Zhang   }
6677431f27SBarry Smith   if (bi[mbs] != 2*a->nz - mbs) SETERRQ2(PETSC_ERR_PLIB,"bi[mbs]: %D != 2*a->nz-mbs: %D\n",bi[mbs],2*a->nz - mbs);
674e5e7fe4SHong Zhang 
684e5e7fe4SHong Zhang   /* set b->j and b->a */
694e5e7fe4SHong Zhang   aj = a->j; av = a->a;
70a7a3a9ebSHong Zhang   for (i=0; i<mbs; i++) {
71a7a3a9ebSHong Zhang     /* diagonal block */
72a7a3a9ebSHong Zhang     for (j=0; j<bs; j++){   /* row i*bs+j */
73a7a3a9ebSHong Zhang       itmp = i*bs+j;
74a7a3a9ebSHong Zhang       for (k=0; k<bs; k++){ /* col i*bs+k */
75a7a3a9ebSHong Zhang         *(bj + rowstart[itmp]) = (*aj)*bs+k;
76a7a3a9ebSHong Zhang         *(bv + rowstart[itmp]) = *(av+k*bs+j);
77a7a3a9ebSHong Zhang         rowstart[itmp]++;
78a7a3a9ebSHong Zhang       }
79a7a3a9ebSHong Zhang     }
80a7a3a9ebSHong Zhang     aj++; av += bs2;
81a7a3a9ebSHong Zhang 
824e5e7fe4SHong Zhang     nz = ai[i+1] - ai[i] -1;
834e5e7fe4SHong Zhang     while (nz--){
84a7a3a9ebSHong Zhang       /* lower triangular blocks */
85a7a3a9ebSHong Zhang       for (j=0; j<bs; j++){   /* row (*aj)*bs+j */
86a7a3a9ebSHong Zhang         itmp = (*aj)*bs+j;
87a7a3a9ebSHong Zhang         for (k=0; k<bs; k++){ /* col i*bs+k */
88a7a3a9ebSHong Zhang           *(bj + rowstart[itmp]) = i*bs+k;
89a7a3a9ebSHong Zhang           *(bv + rowstart[itmp]) = *(av+k*bs+j);
90a7a3a9ebSHong Zhang           rowstart[itmp]++;
91a7a3a9ebSHong Zhang         }
92a7a3a9ebSHong Zhang       }
93a7a3a9ebSHong Zhang       /* upper triangular blocks */
94a7a3a9ebSHong Zhang       for (j=0; j<bs; j++){   /* row i*bs+j */
95a7a3a9ebSHong Zhang         itmp = i*bs+j;
96a7a3a9ebSHong Zhang         for (k=0; k<bs; k++){ /* col (*aj)*bs+k */
97a7a3a9ebSHong Zhang           *(bj + rowstart[itmp]) = (*aj)*bs+k;
98a7a3a9ebSHong Zhang           *(bv + rowstart[itmp]) = *(av+k*bs+j);
99a7a3a9ebSHong Zhang           rowstart[itmp]++;
100a7a3a9ebSHong Zhang         }
101a7a3a9ebSHong Zhang       }
102a7a3a9ebSHong Zhang       aj++; av += bs2;
1034e5e7fe4SHong Zhang     }
1044e5e7fe4SHong Zhang   }
1054e5e7fe4SHong Zhang   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1064e5e7fe4SHong Zhang   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1074e5e7fe4SHong Zhang   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1084e5e7fe4SHong Zhang 
1094e5e7fe4SHong Zhang   /* Fake support for "inplace" convert. */
1104e5e7fe4SHong Zhang   if (*newmat == A) {
1114e5e7fe4SHong Zhang     ierr = MatDestroy(A);CHKERRQ(ierr);
1124e5e7fe4SHong Zhang   }
1134e5e7fe4SHong Zhang   *newmat = B;
1144e5e7fe4SHong Zhang   PetscFunctionReturn(0);
1154e5e7fe4SHong Zhang }
1164e5e7fe4SHong Zhang #undef __FUNCT__
11759557b74SHong Zhang #define __FUNCT__ "MatConvert_SeqAIJ_SeqSBAIJ"
118dfbe8321SBarry Smith PetscErrorCode MatConvert_SeqAIJ_SeqSBAIJ(Mat A,const MatType newtype,Mat *newmat) {
119676c34cdSKris Buschelman   Mat          B;
12059557b74SHong Zhang   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
121861ba921SHong Zhang   Mat_SeqSBAIJ *b;
122dfbe8321SBarry Smith   PetscErrorCode ierr;
123dfbe8321SBarry Smith   int *ai=a->i,*aj,m=A->M,n=A->N,i,j,
1242d9a3abdSHong Zhang                *bi,*bj,*rowlengths;
125861ba921SHong Zhang   PetscScalar  *av,*bv;
12659557b74SHong Zhang 
12759557b74SHong Zhang   PetscFunctionBegin;
1282d9a3abdSHong Zhang   if (n != m) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
129595208bcSHong Zhang   ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); /* check for missing diagonals, then mark diag */
13059557b74SHong Zhang 
13159557b74SHong Zhang   ierr = PetscMalloc(m*sizeof(int),&rowlengths);CHKERRQ(ierr);
13259557b74SHong Zhang   for (i=0; i<m; i++) {
13359557b74SHong Zhang     rowlengths[i] = ai[i+1] - a->diag[i];
13459557b74SHong Zhang   }
135f204ca49SKris Buschelman   ierr = MatCreate(A->comm,m,n,m,n,&B);CHKERRQ(ierr);
136f204ca49SKris Buschelman   ierr = MatSetType(B,newtype);CHKERRQ(ierr);
137f204ca49SKris Buschelman   ierr = MatSeqSBAIJSetPreallocation(B,1,0,rowlengths);CHKERRQ(ierr);
13859557b74SHong Zhang 
139676c34cdSKris Buschelman   ierr = MatSetOption(B,MAT_ROW_ORIENTED);CHKERRQ(ierr);
140676c34cdSKris Buschelman   ierr = MatSetOption(B,MAT_ROWS_SORTED);CHKERRQ(ierr);
141676c34cdSKris Buschelman   ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr);
14259557b74SHong Zhang 
143676c34cdSKris Buschelman   b  = (Mat_SeqSBAIJ*)(B->data);
144861ba921SHong Zhang   bi = b->i;
145861ba921SHong Zhang   bj = b->j;
146861ba921SHong Zhang   bv = b->a;
147861ba921SHong Zhang 
148861ba921SHong Zhang   bi[0] = 0;
14959557b74SHong Zhang   for (i=0; i<m; i++) {
15059557b74SHong Zhang     aj = a->j + a->diag[i];
15159557b74SHong Zhang     av = a->a + a->diag[i];
152861ba921SHong Zhang     for (j=0; j<rowlengths[i]; j++){
153861ba921SHong Zhang       *bj = *aj; bj++; aj++;
154861ba921SHong Zhang       *bv = *av; bv++; av++;
155861ba921SHong Zhang     }
156861ba921SHong Zhang     bi[i+1]    = bi[i] + rowlengths[i];
157861ba921SHong Zhang     b->ilen[i] = rowlengths[i];
15859557b74SHong Zhang   }
15959557b74SHong Zhang 
16059557b74SHong Zhang   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
161676c34cdSKris Buschelman   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
162676c34cdSKris Buschelman   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
163676c34cdSKris Buschelman 
164676c34cdSKris Buschelman   /* Fake support for "inplace" convert. */
165676c34cdSKris Buschelman   if (*newmat == A) {
166676c34cdSKris Buschelman     ierr = MatDestroy(A);CHKERRQ(ierr);
167676c34cdSKris Buschelman   }
168676c34cdSKris Buschelman   *newmat = B;
169676c34cdSKris Buschelman 
17059557b74SHong Zhang   PetscFunctionReturn(0);
17159557b74SHong Zhang }
17259557b74SHong Zhang EXTERN_C_END
17359557b74SHong Zhang 
174a0e1a404SHong Zhang EXTERN_C_BEGIN
175a0e1a404SHong Zhang #undef __FUNCT__
176a0e1a404SHong Zhang #define __FUNCT__ "MatConvert_SeqSBAI_SeqBAIJ"
177dfbe8321SBarry Smith PetscErrorCode MatConvert_SeqSBAIJ_SeqBAIJ(Mat A,const MatType newtype,Mat *newmat)
178a0e1a404SHong Zhang {
179a0e1a404SHong Zhang   Mat          B;
180a0e1a404SHong Zhang   Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data;
181a0e1a404SHong Zhang   Mat_SeqBAIJ  *b;
182dfbe8321SBarry Smith   PetscErrorCode ierr;
183dfbe8321SBarry Smith   int *ai=a->i,*aj=a->j,m=A->m,n=A->n,i,k,*bi,*bj,
184a0e1a404SHong Zhang                *browlengths,nz,*browstart,itmp;
185*521d7252SBarry Smith   int          bs=A->bs,bs2=bs*bs,mbs=m/bs;
186a0e1a404SHong Zhang   PetscScalar  *av,*bv;
187a0e1a404SHong Zhang 
188a0e1a404SHong Zhang   PetscFunctionBegin;
189a0e1a404SHong Zhang   /* compute browlengths of newmat */
190a0e1a404SHong Zhang   ierr = PetscMalloc(2*mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
191a0e1a404SHong Zhang   browstart = browlengths + mbs;
192a0e1a404SHong Zhang   for (i=0; i<mbs; i++) browlengths[i] = 0;
193a0e1a404SHong Zhang   aj = a->j;
194a0e1a404SHong Zhang   for (i=0; i<mbs; i++) {
195a0e1a404SHong Zhang     nz = ai[i+1] - ai[i];
196a0e1a404SHong Zhang     aj++; /* skip diagonal */
197a0e1a404SHong Zhang     for (k=1; k<nz; k++) { /* no. of lower triangular blocks */
198a0e1a404SHong Zhang       browlengths[*aj]++; aj++;
199a0e1a404SHong Zhang     }
200a0e1a404SHong Zhang     browlengths[i] += nz;   /* no. of upper triangular blocks */
201a0e1a404SHong Zhang   }
202a0e1a404SHong Zhang 
203f204ca49SKris Buschelman   ierr = MatCreate(A->comm,m,n,m,n,&B);CHKERRQ(ierr);
204f204ca49SKris Buschelman   ierr = MatSetType(B,newtype);CHKERRQ(ierr);
205f204ca49SKris Buschelman   ierr = MatSeqBAIJSetPreallocation(B,bs,0,browlengths);CHKERRQ(ierr);
206a0e1a404SHong Zhang   ierr = MatSetOption(B,MAT_ROW_ORIENTED);CHKERRQ(ierr);
207a0e1a404SHong Zhang   ierr = MatSetOption(B,MAT_ROWS_SORTED);CHKERRQ(ierr);
208a0e1a404SHong Zhang   ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr);
209a0e1a404SHong Zhang 
210a0e1a404SHong Zhang   b  = (Mat_SeqBAIJ*)(B->data);
211a0e1a404SHong Zhang   bi = b->i;
212a0e1a404SHong Zhang   bj = b->j;
213a0e1a404SHong Zhang   bv = b->a;
214a0e1a404SHong Zhang 
215a0e1a404SHong Zhang   /* set b->i */
216a0e1a404SHong Zhang   bi[0] = 0;
217a0e1a404SHong Zhang   for (i=0; i<mbs; i++){
218a0e1a404SHong Zhang     b->ilen[i]    = browlengths[i];
219a0e1a404SHong Zhang     bi[i+1]       = bi[i] + browlengths[i];
220a0e1a404SHong Zhang     browstart[i]  = bi[i];
221a0e1a404SHong Zhang   }
22277431f27SBarry Smith   if (bi[mbs] != 2*a->nz - mbs) SETERRQ2(PETSC_ERR_PLIB,"bi[mbs]: %D != 2*a->nz - mbs: %D\n",bi[mbs],2*a->nz - mbs);
223a0e1a404SHong Zhang 
224a0e1a404SHong Zhang   /* set b->j and b->a */
225a0e1a404SHong Zhang   aj = a->j; av = a->a;
226a0e1a404SHong Zhang   for (i=0; i<mbs; i++) {
227a0e1a404SHong Zhang     /* diagonal block */
228a0e1a404SHong Zhang     *(bj + browstart[i]) = *aj; aj++;
229a0e1a404SHong Zhang     itmp = bs2*browstart[i];
230a0e1a404SHong Zhang     for (k=0; k<bs2; k++){
231a0e1a404SHong Zhang       *(bv + itmp + k) = *av; av++;
232a0e1a404SHong Zhang     }
233a0e1a404SHong Zhang     browstart[i]++;
234a0e1a404SHong Zhang 
235a0e1a404SHong Zhang     nz = ai[i+1] - ai[i] -1;
236a0e1a404SHong Zhang     while (nz--){
237a0e1a404SHong Zhang       /* lower triangular blocks */
238a0e1a404SHong Zhang       *(bj + browstart[*aj]) = i;
239a0e1a404SHong Zhang       itmp = bs2*browstart[*aj];
240a0e1a404SHong Zhang       for (k=0; k<bs2; k++){
241a0e1a404SHong Zhang         *(bv + itmp + k) = *(av + k);
242a0e1a404SHong Zhang       }
243a0e1a404SHong Zhang       browstart[*aj]++;
244a0e1a404SHong Zhang 
245a0e1a404SHong Zhang       /* upper triangular blocks */
246a0e1a404SHong Zhang       *(bj + browstart[i]) = *aj; aj++;
247a0e1a404SHong Zhang       itmp = bs2*browstart[i];
248a0e1a404SHong Zhang       for (k=0; k<bs2; k++){
249a0e1a404SHong Zhang         *(bv + itmp + k) = *av; av++;
250a0e1a404SHong Zhang       }
251a0e1a404SHong Zhang       browstart[i]++;
252a0e1a404SHong Zhang     }
253a0e1a404SHong Zhang   }
254a0e1a404SHong Zhang   ierr = PetscFree(browlengths);CHKERRQ(ierr);
255a0e1a404SHong Zhang   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
256a0e1a404SHong Zhang   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
257a0e1a404SHong Zhang 
258a0e1a404SHong Zhang   /* Fake support for "inplace" convert. */
259a0e1a404SHong Zhang   if (*newmat == A) {
260a0e1a404SHong Zhang     ierr = MatDestroy(A);CHKERRQ(ierr);
261a0e1a404SHong Zhang   }
262a0e1a404SHong Zhang   *newmat = B;
263a0e1a404SHong Zhang   PetscFunctionReturn(0);
264a0e1a404SHong Zhang }
265a0e1a404SHong Zhang #undef __FUNCT__
266a0e1a404SHong Zhang #define __FUNCT__ "MatConvert_SeqBAIJ_SeqSBAIJ"
267dfbe8321SBarry Smith PetscErrorCode MatConvert_SeqBAIJ_SeqSBAIJ(Mat A,const MatType newtype,Mat *newmat)
268a0e1a404SHong Zhang {
269a0e1a404SHong Zhang   Mat          B;
270a0e1a404SHong Zhang   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
271a0e1a404SHong Zhang   Mat_SeqSBAIJ *b;
272dfbe8321SBarry Smith   PetscErrorCode ierr;
273dfbe8321SBarry Smith   int *ai=a->i,*aj,m=A->m,n=A->n,i,j,k,
274a0e1a404SHong Zhang                *bi,*bj,*browlengths;
275*521d7252SBarry Smith   int          bs=A->bs,bs2=bs*bs,mbs=m/bs;
276a0e1a404SHong Zhang   PetscScalar  *av,*bv;
277a0e1a404SHong Zhang 
278a0e1a404SHong Zhang   PetscFunctionBegin;
279a0e1a404SHong Zhang   if (n != m) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
280595208bcSHong Zhang   ierr = MatMissingDiagonal_SeqBAIJ(A);CHKERRQ(ierr); /* check for missing diagonals, then mark diag */
281a0e1a404SHong Zhang 
282a0e1a404SHong Zhang   ierr = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
283a0e1a404SHong Zhang   for (i=0; i<mbs; i++) {
284a0e1a404SHong Zhang     browlengths[i] = ai[i+1] - a->diag[i];
285a0e1a404SHong Zhang   }
286a0e1a404SHong Zhang 
287f204ca49SKris Buschelman   ierr = MatCreate(A->comm,m,n,m,n,&B);CHKERRQ(ierr);
288f204ca49SKris Buschelman   ierr = MatSetType(B,newtype);CHKERRQ(ierr);
289f204ca49SKris Buschelman   ierr = MatSeqSBAIJSetPreallocation(B,bs,0,browlengths);CHKERRQ(ierr);
290a0e1a404SHong Zhang   ierr = MatSetOption(B,MAT_ROW_ORIENTED);CHKERRQ(ierr);
291a0e1a404SHong Zhang   ierr = MatSetOption(B,MAT_ROWS_SORTED);CHKERRQ(ierr);
292a0e1a404SHong Zhang   ierr = MatSetOption(B,MAT_COLUMNS_SORTED);CHKERRQ(ierr);
293a0e1a404SHong Zhang 
294a0e1a404SHong Zhang   b  = (Mat_SeqSBAIJ*)(B->data);
295a0e1a404SHong Zhang   bi = b->i;
296a0e1a404SHong Zhang   bj = b->j;
297a0e1a404SHong Zhang   bv = b->a;
298a0e1a404SHong Zhang 
299a0e1a404SHong Zhang   bi[0] = 0;
300a0e1a404SHong Zhang   for (i=0; i<mbs; i++) {
301a0e1a404SHong Zhang     aj = a->j + a->diag[i];
302a0e1a404SHong Zhang     av = a->a + (a->diag[i])*bs2;
303a0e1a404SHong Zhang     for (j=0; j<browlengths[i]; j++){
304a0e1a404SHong Zhang       *bj = *aj; bj++; aj++;
305a0e1a404SHong Zhang       for (k=0; k<bs2; k++){
306a0e1a404SHong Zhang         *bv = *av; bv++; av++;
307a0e1a404SHong Zhang       }
308a0e1a404SHong Zhang     }
309a0e1a404SHong Zhang     bi[i+1]    = bi[i] + browlengths[i];
310a0e1a404SHong Zhang     b->ilen[i] = browlengths[i];
311a0e1a404SHong Zhang   }
312a0e1a404SHong Zhang   ierr = PetscFree(browlengths);CHKERRQ(ierr);
313a0e1a404SHong Zhang   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
314a0e1a404SHong Zhang   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
315a0e1a404SHong Zhang 
316a0e1a404SHong Zhang   /* Fake support for "inplace" convert. */
317a0e1a404SHong Zhang   if (*newmat == A) {
318a0e1a404SHong Zhang     ierr = MatDestroy(A);CHKERRQ(ierr);
319a0e1a404SHong Zhang   }
320a0e1a404SHong Zhang   *newmat = B;
321a0e1a404SHong Zhang 
322a0e1a404SHong Zhang   PetscFunctionReturn(0);
323a0e1a404SHong Zhang }
324a0e1a404SHong Zhang EXTERN_C_END
325