Actual source code: aijsbaij.c

petsc-3.10.5 2019-03-28
Report Typos and Errors

  2:  #include <../src/mat/impls/aij/seq/aij.h>
  3:  #include <../src/mat/impls/baij/seq/baij.h>
  4:  #include <../src/mat/impls/sbaij/seq/sbaij.h>

  6: PETSC_INTERN PetscErrorCode MatConvert_SeqSBAIJ_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
  7: {
  8:   Mat            B;
  9:   Mat_SeqSBAIJ   *a = (Mat_SeqSBAIJ*)A->data;
 10:   Mat_SeqAIJ     *b;
 12:   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->n,i,j,k,*bi,*bj,*rowlengths,nz,*rowstart,itmp;
 13:   PetscInt       bs =A->rmap->bs,bs2=bs*bs,mbs=A->rmap->N/bs,diagcnt=0;
 14:   MatScalar      *av,*bv;

 17:   /* compute rowlengths of newmat */
 18:   PetscMalloc2(m,&rowlengths,m+1,&rowstart);

 20:   for (i=0; i<mbs; i++) rowlengths[i*bs] = 0;
 21:   k  = 0;
 22:   for (i=0; i<mbs; i++) {
 23:     nz = ai[i+1] - ai[i];
 24:     if (nz) {
 25:       rowlengths[k] += nz;   /* no. of upper triangular blocks */
 26:       if (*aj == i) {aj++;diagcnt++;nz--;} /* skip diagonal */
 27:       for (j=0; j<nz; j++) { /* no. of lower triangular blocks */
 28:         rowlengths[(*aj)*bs]++; aj++;
 29:       }
 30:     }
 31:     rowlengths[k] *= bs;
 32:     for (j=1; j<bs; j++) {
 33:       rowlengths[k+j] = rowlengths[k];
 34:     }
 35:     k += bs;
 36:     /* printf(" rowlengths[%d]: %d\n",i, rowlengths[i]); */
 37:   }

 39:   MatCreate(PetscObjectComm((PetscObject)A),&B);
 40:   MatSetSizes(B,m,n,m,n);
 41:   MatSetType(B,MATSEQAIJ);
 42:   MatSeqAIJSetPreallocation(B,0,rowlengths);
 43:   MatSetOption(B,MAT_ROW_ORIENTED,PETSC_FALSE);

 45:   B->rmap->bs = A->rmap->bs;

 47:   b  = (Mat_SeqAIJ*)(B->data);
 48:   bi = b->i;
 49:   bj = b->j;
 50:   bv = b->a;

 52:   /* set b->i */
 53:   bi[0] = 0; rowstart[0] = 0;
 54:   for (i=0; i<mbs; i++) {
 55:     for (j=0; j<bs; j++) {
 56:       b->ilen[i*bs+j]    = rowlengths[i*bs];
 57:       rowstart[i*bs+j+1] = rowstart[i*bs+j] + rowlengths[i*bs];
 58:     }
 59:     bi[i+1] = bi[i] + rowlengths[i*bs]/bs;
 60:   }
 61:   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);

 63:   /* set b->j and b->a */
 64:   aj = a->j; av = a->a;
 65:   for (i=0; i<mbs; i++) {
 66:     nz = ai[i+1] - ai[i];
 67:     /* diagonal block */
 68:     if (nz && *aj == i) {
 69:       nz--;
 70:       for (j=0; j<bs; j++) {   /* row i*bs+j */
 71:         itmp = i*bs+j;
 72:         for (k=0; k<bs; k++) { /* col i*bs+k */
 73:           *(bj + rowstart[itmp]) = (*aj)*bs+k;
 74:           *(bv + rowstart[itmp]) = *(av+k*bs+j);
 75:           rowstart[itmp]++;
 76:         }
 77:       }
 78:       aj++; av += bs2;
 79:     }

 81:     while (nz--) {
 82:       /* lower triangular blocks */
 83:       for (j=0; j<bs; j++) {   /* row (*aj)*bs+j */
 84:         itmp = (*aj)*bs+j;
 85:         for (k=0; k<bs; k++) { /* col i*bs+k */
 86:           *(bj + rowstart[itmp]) = i*bs+k;
 87:           *(bv + rowstart[itmp]) = *(av+j*bs+k);
 88:           rowstart[itmp]++;
 89:         }
 90:       }
 91:       /* upper triangular blocks */
 92:       for (j=0; j<bs; j++) {   /* row i*bs+j */
 93:         itmp = i*bs+j;
 94:         for (k=0; k<bs; k++) { /* col (*aj)*bs+k */
 95:           *(bj + rowstart[itmp]) = (*aj)*bs+k;
 96:           *(bv + rowstart[itmp]) = *(av+k*bs+j);
 97:           rowstart[itmp]++;
 98:         }
 99:       }
100:       aj++; av += bs2;
101:     }
102:   }
103:   PetscFree2(rowlengths,rowstart);
104:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
105:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

107:   if (reuse == MAT_INPLACE_MATRIX) {
108:     MatHeaderReplace(A,&B);
109:   } else {
110:     *newmat = B;
111:   }
112:   return(0);
113: }

115: PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqSBAIJ(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
116: {
117:   Mat            B;
118:   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
119:   Mat_SeqSBAIJ   *b;
121:   PetscInt       *ai=a->i,*aj,m=A->rmap->N,n=A->cmap->N,i,j,*bi,*bj,*rowlengths;
122:   MatScalar      *av,*bv;

125:   if (!A->symmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_USER,"Matrix must be symmetric. Call MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)");
126:   if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Matrix must be square");

128:   PetscMalloc1(m,&rowlengths);
129:   for (i=0; i<m; i++) {
130:     rowlengths[i] = ai[i+1] - a->diag[i];
131:   }
132:   MatCreate(PetscObjectComm((PetscObject)A),&B);
133:   MatSetSizes(B,m,n,m,n);
134:   MatSetType(B,MATSEQSBAIJ);
135:   MatSeqSBAIJSetPreallocation(B,1,0,rowlengths);

137:   MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE);

139:   b  = (Mat_SeqSBAIJ*)(B->data);
140:   bi = b->i;
141:   bj = b->j;
142:   bv = b->a;

144:   bi[0] = 0;
145:   for (i=0; i<m; i++) {
146:     aj = a->j + a->diag[i];
147:     av = a->a + a->diag[i];
148:     for (j=0; j<rowlengths[i]; j++) {
149:       *bj = *aj; bj++; aj++;
150:       *bv = *av; bv++; av++;
151:     }
152:     bi[i+1]    = bi[i] + rowlengths[i];
153:     b->ilen[i] = rowlengths[i];
154:   }

156:   PetscFree(rowlengths);
157:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
158:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

160:   if (reuse == MAT_INPLACE_MATRIX) {
161:     MatHeaderReplace(A,&B);
162:   } else {
163:     *newmat = B;
164:   }
165:   return(0);
166: }

168: PETSC_INTERN PetscErrorCode MatConvert_SeqSBAIJ_SeqBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
169: {
170:   Mat            B;
171:   Mat_SeqSBAIJ   *a = (Mat_SeqSBAIJ*)A->data;
172:   Mat_SeqBAIJ    *b;
174:   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->n,i,k,*bi,*bj,*browlengths,nz,*browstart,itmp;
175:   PetscInt       bs =A->rmap->bs,bs2=bs*bs,mbs=m/bs,col,row;
176:   MatScalar      *av,*bv;

179:   /* compute browlengths of newmat */
180:   PetscMalloc2(mbs,&browlengths,mbs,&browstart);
181:   for (i=0; i<mbs; i++) browlengths[i] = 0;
182:   for (i=0; i<mbs; i++) {
183:     nz = ai[i+1] - ai[i];
184:     aj++; /* skip diagonal */
185:     for (k=1; k<nz; k++) { /* no. of lower triangular blocks */
186:       browlengths[*aj]++; aj++;
187:     }
188:     browlengths[i] += nz;   /* no. of upper triangular blocks */
189:   }

191:   MatCreate(PetscObjectComm((PetscObject)A),&B);
192:   MatSetSizes(B,m,n,m,n);
193:   MatSetType(B,MATSEQBAIJ);
194:   MatSeqBAIJSetPreallocation(B,bs,0,browlengths);
195:   MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE);

197:   b  = (Mat_SeqBAIJ*)(B->data);
198:   bi = b->i;
199:   bj = b->j;
200:   bv = b->a;

202:   /* set b->i */
203:   bi[0] = 0;
204:   for (i=0; i<mbs; i++) {
205:     b->ilen[i]   = browlengths[i];
206:     bi[i+1]      = bi[i] + browlengths[i];
207:     browstart[i] = bi[i];
208:   }
209:   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);

211:   /* set b->j and b->a */
212:   aj = a->j; av = a->a;
213:   for (i=0; i<mbs; i++) {
214:     /* diagonal block */
215:     *(bj + browstart[i]) = *aj; aj++;

217:     itmp = bs2*browstart[i];
218:     for (k=0; k<bs2; k++) {
219:       *(bv + itmp + k) = *av; av++;
220:     }
221:     browstart[i]++;

223:     nz = ai[i+1] - ai[i] -1;
224:     while (nz--) {
225:       /* lower triangular blocks - transpose blocks of A */
226:       *(bj + browstart[*aj]) = i; /* block col index */

228:       itmp = bs2*browstart[*aj];  /* row index */
229:       for (col=0; col<bs; col++) {
230:         k = col;
231:         for (row=0; row<bs; row++) {
232:           bv[itmp + col*bs+row] = av[k]; k+=bs;
233:         }
234:       }
235:       browstart[*aj]++;

237:       /* upper triangular blocks */
238:       *(bj + browstart[i]) = *aj; aj++;

240:       itmp = bs2*browstart[i];
241:       for (k=0; k<bs2; k++) {
242:         bv[itmp + k] = av[k];
243:       }
244:       av += bs2;
245:       browstart[i]++;
246:     }
247:   }
248:   PetscFree2(browlengths,browstart);
249:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
250:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

252:   if (reuse == MAT_INPLACE_MATRIX) {
253:     MatHeaderReplace(A,&B);
254:   } else {
255:     *newmat = B;
256:   }
257:   return(0);
258: }

260: PETSC_INTERN PetscErrorCode MatConvert_SeqBAIJ_SeqSBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
261: {
262:   Mat            B;
263:   Mat_SeqBAIJ    *a = (Mat_SeqBAIJ*)A->data;
264:   Mat_SeqSBAIJ   *b;
266:   PetscInt       *ai=a->i,*aj,m=A->rmap->N,n=A->cmap->n,i,j,k,*bi,*bj,*browlengths;
267:   PetscInt       bs =A->rmap->bs,bs2=bs*bs,mbs=m/bs,dd;
268:   MatScalar      *av,*bv;
269:   PetscBool      flg;

272:   if (!A->symmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_USER,"Matrix must be symmetric. Call MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)");
273:   if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Matrix must be square");
274:   MatMissingDiagonal_SeqBAIJ(A,&flg,&dd); /* check for missing diagonals, then mark diag */
275:   if (flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal %D",dd);

277:   PetscMalloc1(mbs,&browlengths);
278:   for (i=0; i<mbs; i++) {
279:     browlengths[i] = ai[i+1] - a->diag[i];
280:   }

282:   MatCreate(PetscObjectComm((PetscObject)A),&B);
283:   MatSetSizes(B,m,n,m,n);
284:   MatSetType(B,MATSEQSBAIJ);
285:   MatSeqSBAIJSetPreallocation(B,bs,0,browlengths);
286:   MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE);

288:   b  = (Mat_SeqSBAIJ*)(B->data);
289:   bi = b->i;
290:   bj = b->j;
291:   bv = b->a;

293:   bi[0] = 0;
294:   for (i=0; i<mbs; i++) {
295:     aj = a->j + a->diag[i];
296:     av = a->a + (a->diag[i])*bs2;
297:     for (j=0; j<browlengths[i]; j++) {
298:       *bj = *aj; bj++; aj++;
299:       for (k=0; k<bs2; k++) {
300:         *bv = *av; bv++; av++;
301:       }
302:     }
303:     bi[i+1]    = bi[i] + browlengths[i];
304:     b->ilen[i] = browlengths[i];
305:   }
306:   PetscFree(browlengths);
307:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
308:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

310:   if (reuse == MAT_INPLACE_MATRIX) {
311:     MatHeaderReplace(A,&B);
312:   } else {
313:     *newmat = B;
314:   }
315:   return(0);
316: }