Actual source code: aijsbaij.c

  1: #define PETSCMAT_DLL

 3:  #include src/mat/impls/aij/seq/aij.h
 4:  #include src/mat/impls/baij/seq/baij.h
 5:  #include src/mat/impls/sbaij/seq/sbaij.h

 10: PetscErrorCode  MatConvert_SeqSBAIJ_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
 11: {
 12:   Mat            B;
 13:   Mat_SeqSBAIJ   *a = (Mat_SeqSBAIJ*)A->data;
 14:   Mat_SeqAIJ     *b;
 16:   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap.N,n=A->cmap.n,i,j,k,*bi,*bj,*rowlengths,nz,*rowstart,itmp;
 17:   PetscInt       bs=A->rmap.bs,bs2=bs*bs,mbs=A->rmap.N/bs;
 18:   PetscScalar    *av,*bv;

 21:   /* compute rowlengths of newmat */
 22:   PetscMalloc((2*m+1)*sizeof(PetscInt),&rowlengths);
 23:   rowstart = rowlengths + m;
 24: 
 25:   for (i=0; i<mbs; i++) rowlengths[i*bs] = 0;
 26:   aj = a->j;
 27:   k = 0;
 28:   for (i=0; i<mbs; i++) {
 29:     nz = ai[i+1] - ai[i];
 30:     aj++; /* skip diagonal */
 31:     for (j=1; j<nz; j++) { /* no. of lower triangular blocks */
 32:       rowlengths[(*aj)*bs]++; aj++;
 33:     }
 34:     rowlengths[k] += nz;   /* no. of upper triangular blocks */
 35:     rowlengths[k] *= bs;
 36:     for (j=1; j<bs; j++) {
 37:       rowlengths[k+j] = rowlengths[k];
 38:     }
 39:     k += bs;
 40:     /* printf(" rowlengths[%d]: %d\n",i, rowlengths[i]); */
 41:   }
 42: 
 43:   MatCreate(A->comm,&B);
 44:   MatSetSizes(B,m,n,m,n);
 45:   MatSetType(B,newtype);
 46:   MatSeqAIJSetPreallocation(B,0,rowlengths);
 47:   MatSetOption(B,MAT_COLUMN_ORIENTED);
 48:   MatSetOption(B,MAT_ROWS_SORTED);
 49:   MatSetOption(B,MAT_COLUMNS_SORTED);
 50:   B->rmap.bs = A->rmap.bs;

 52:   b  = (Mat_SeqAIJ*)(B->data);
 53:   bi = b->i;
 54:   bj = b->j;
 55:   bv = b->a;

 57:   /* set b->i */
 58:   bi[0] = 0; rowstart[0] = 0;
 59:   for (i=0; i<mbs; i++){
 60:     for (j=0; j<bs; j++){
 61:       b->ilen[i*bs+j]  = rowlengths[i*bs];
 62:       rowstart[i*bs+j+1] = rowstart[i*bs+j] + rowlengths[i*bs];
 63:     }
 64:     bi[i+1]     = bi[i] + rowlengths[i*bs]/bs;
 65:   }
 66:   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);

 68:   /* set b->j and b->a */
 69:   aj = a->j; av = a->a;
 70:   for (i=0; i<mbs; i++) {
 71:     /* diagonal block */
 72:     for (j=0; j<bs; j++){   /* row i*bs+j */
 73:       itmp = i*bs+j;
 74:       for (k=0; k<bs; k++){ /* col i*bs+k */
 75:         *(bj + rowstart[itmp]) = (*aj)*bs+k;
 76:         *(bv + rowstart[itmp]) = *(av+k*bs+j);
 77:         rowstart[itmp]++;
 78:       }
 79:     }
 80:     aj++; av += bs2;
 81: 
 82:     nz = ai[i+1] - ai[i] -1;
 83:     while (nz--){
 84:       /* lower triangular blocks */
 85:       for (j=0; j<bs; j++){   /* row (*aj)*bs+j */
 86:         itmp = (*aj)*bs+j;
 87:         for (k=0; k<bs; k++){ /* col i*bs+k */
 88:           *(bj + rowstart[itmp]) = i*bs+k;
 89:           *(bv + rowstart[itmp]) = *(av+k*bs+j);
 90:           rowstart[itmp]++;
 91:         }
 92:       }
 93:       /* upper triangular blocks */
 94:       for (j=0; j<bs; j++){   /* row i*bs+j */
 95:         itmp = i*bs+j;
 96:         for (k=0; k<bs; k++){ /* col (*aj)*bs+k */
 97:           *(bj + rowstart[itmp]) = (*aj)*bs+k;
 98:           *(bv + rowstart[itmp]) = *(av+k*bs+j);
 99:           rowstart[itmp]++;
100:         }
101:       }
102:       aj++; av += bs2;
103:     }
104:   }
105:   PetscFree(rowlengths);
106:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
107:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

109:   if (reuse == MAT_REUSE_MATRIX) {
110:     MatHeaderReplace(A,B);
111:   } else {
112:     *newmat = B;
113:   }
114:   return(0);
115: }

121: PetscErrorCode  MatConvert_SeqAIJ_SeqSBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) {
122:   Mat            B;
123:   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
124:   Mat_SeqSBAIJ   *b;
126:   PetscInt       *ai=a->i,*aj,m=A->rmap.N,n=A->cmap.N,i,j,*bi,*bj,*rowlengths;
127:   PetscScalar    *av,*bv;

130:   if (n != m) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");

132:   PetscMalloc(m*sizeof(PetscInt),&rowlengths);
133:   for (i=0; i<m; i++) {
134:     rowlengths[i] = ai[i+1] - a->diag[i];
135:   }
136:   MatCreate(A->comm,&B);
137:   MatSetSizes(B,m,n,m,n);
138:   MatSetType(B,newtype);
139:   MatSeqSBAIJSetPreallocation_SeqSBAIJ(B,1,0,rowlengths);

141:   MatSetOption(B,MAT_ROW_ORIENTED);
142:   MatSetOption(B,MAT_ROWS_SORTED);
143:   MatSetOption(B,MAT_COLUMNS_SORTED);
144: 
145:   b  = (Mat_SeqSBAIJ*)(B->data);
146:   bi = b->i;
147:   bj = b->j;
148:   bv = b->a;

150:   bi[0] = 0;
151:   for (i=0; i<m; i++) {
152:     aj = a->j + a->diag[i];
153:     av = a->a + a->diag[i];
154:     for (j=0; j<rowlengths[i]; j++){
155:       *bj = *aj; bj++; aj++;
156:       *bv = *av; bv++; av++;
157:     }
158:     bi[i+1]    = bi[i] + rowlengths[i];
159:     b->ilen[i] = rowlengths[i];
160:   }
161: 
162:   PetscFree(rowlengths);
163:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
164:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

166:   if (reuse == MAT_REUSE_MATRIX) {
167:     MatHeaderReplace(A,B);
168:   } else {
169:     *newmat = B;
170:   }
171:   return(0);
172: }

178: PetscErrorCode  MatConvert_SeqSBAIJ_SeqBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
179: {
180:   Mat            B;
181:   Mat_SeqSBAIJ   *a = (Mat_SeqSBAIJ*)A->data;
182:   Mat_SeqBAIJ    *b;
184:   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap.N,n=A->cmap.n,i,k,*bi,*bj,*browlengths,nz,*browstart,itmp;
185:   PetscInt       bs=A->rmap.bs,bs2=bs*bs,mbs=m/bs;
186:   PetscScalar    *av,*bv;

189:   /* compute browlengths of newmat */
190:   PetscMalloc(2*mbs*sizeof(PetscInt),&browlengths);
191:   browstart = browlengths + mbs;
192:   for (i=0; i<mbs; i++) browlengths[i] = 0;
193:   aj = a->j;
194:   for (i=0; i<mbs; i++) {
195:     nz = ai[i+1] - ai[i];
196:     aj++; /* skip diagonal */
197:     for (k=1; k<nz; k++) { /* no. of lower triangular blocks */
198:       browlengths[*aj]++; aj++;
199:     }
200:     browlengths[i] += nz;   /* no. of upper triangular blocks */
201:   }
202: 
203:   MatCreate(A->comm,&B);
204:   MatSetSizes(B,m,n,m,n);
205:   MatSetType(B,newtype);
206:   MatSeqBAIJSetPreallocation(B,bs,0,browlengths);
207:   MatSetOption(B,MAT_ROW_ORIENTED);
208:   MatSetOption(B,MAT_ROWS_SORTED);
209:   MatSetOption(B,MAT_COLUMNS_SORTED);
210: 
211:   b  = (Mat_SeqBAIJ*)(B->data);
212:   bi = b->i;
213:   bj = b->j;
214:   bv = b->a;

216:   /* set b->i */
217:   bi[0] = 0;
218:   for (i=0; i<mbs; i++){
219:     b->ilen[i]    = browlengths[i];
220:     bi[i+1]       = bi[i] + browlengths[i];
221:     browstart[i]  = bi[i];
222:   }
223:   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);
224: 
225:   /* set b->j and b->a */
226:   aj = a->j; av = a->a;
227:   for (i=0; i<mbs; i++) {
228:     /* diagonal block */
229:     *(bj + browstart[i]) = *aj; aj++;
230:     itmp = bs2*browstart[i];
231:     for (k=0; k<bs2; k++){
232:       *(bv + itmp + k) = *av; av++;
233:     }
234:     browstart[i]++;
235: 
236:     nz = ai[i+1] - ai[i] -1;
237:     while (nz--){
238:       /* lower triangular blocks */
239:       *(bj + browstart[*aj]) = i;
240:       itmp = bs2*browstart[*aj];
241:       for (k=0; k<bs2; k++){
242:         *(bv + itmp + k) = *(av + k);
243:       }
244:       browstart[*aj]++;

246:       /* upper triangular blocks */
247:       *(bj + browstart[i]) = *aj; aj++;
248:       itmp = bs2*browstart[i];
249:       for (k=0; k<bs2; k++){
250:         *(bv + itmp + k) = *av; av++;
251:       }
252:       browstart[i]++;
253:     }
254:   }
255:   PetscFree(browlengths);
256:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
257:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

259:   if (reuse == MAT_REUSE_MATRIX) {
260:     MatHeaderReplace(A,B);
261:   } else {
262:     *newmat = B;
263:   }
264:   return(0);
265: }

271: PetscErrorCode  MatConvert_SeqBAIJ_SeqSBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
272: {
273:   Mat            B;
274:   Mat_SeqBAIJ    *a = (Mat_SeqBAIJ*)A->data;
275:   Mat_SeqSBAIJ   *b;
277:   PetscInt       *ai=a->i,*aj,m=A->rmap.N,n=A->cmap.n,i,j,k,*bi,*bj,*browlengths;
278:   PetscInt       bs=A->rmap.bs,bs2=bs*bs,mbs=m/bs;
279:   PetscScalar    *av,*bv;

282:   if (n != m) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
283:   MatMissingDiagonal_SeqBAIJ(A); /* check for missing diagonals, then mark diag */
284: 
285:   PetscMalloc(mbs*sizeof(PetscInt),&browlengths);
286:   for (i=0; i<mbs; i++) {
287:     browlengths[i] = ai[i+1] - a->diag[i];
288:   }

290:   MatCreate(A->comm,&B);
291:   MatSetSizes(B,m,n,m,n);
292:   MatSetType(B,newtype);
293:   MatSeqSBAIJSetPreallocation_SeqSBAIJ(B,bs,0,browlengths);
294:   MatSetOption(B,MAT_ROW_ORIENTED);
295:   MatSetOption(B,MAT_ROWS_SORTED);
296:   MatSetOption(B,MAT_COLUMNS_SORTED);
297: 
298:   b  = (Mat_SeqSBAIJ*)(B->data);
299:   bi = b->i;
300:   bj = b->j;
301:   bv = b->a;

303:   bi[0] = 0;
304:   for (i=0; i<mbs; i++) {
305:     aj = a->j + a->diag[i];
306:     av = a->a + (a->diag[i])*bs2;
307:     for (j=0; j<browlengths[i]; j++){
308:       *bj = *aj; bj++; aj++;
309:       for (k=0; k<bs2; k++){
310:         *bv = *av; bv++; av++;
311:       }
312:     }
313:     bi[i+1]    = bi[i] + browlengths[i];
314:     b->ilen[i] = browlengths[i];
315:   }
316:   PetscFree(browlengths);
317:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
318:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

320:   if (reuse == MAT_REUSE_MATRIX) {
321:     MatHeaderReplace(A,B);
322:   } else {
323:     *newmat = B;
324:   }

326:   return(0);
327: }