Actual source code: fdaij.c

  1: #define PETSCMAT_DLL

 3:  #include ../src/mat/impls/aij/seq/aij.h

  7: /*
  8:     This routine is shared by AIJ and BAIJ matrices, since it operators only on the nonzero structure of the elements or blocks.
  9:     This is why it has the ugly code with the MatGetBlockSize()
 10: */
 11: PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
 12: {
 14:   PetscInt       i,n,nrows,N,j,k,m,*rows,*ci,*cj,ncols,col;
 15:   const PetscInt *is;
 16:   PetscInt       nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1;
 17:   IS             *isa;
 18:   PetscTruth     done,flg = PETSC_FALSE;
 19:   PetscTruth     flg1,flg2;

 22:   if (!mat->assembled) {
 23:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();");
 24:   }

 26:   ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);
 27:   /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */
 28:   PetscTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);
 29:   PetscTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);
 30:   if (flg1 || flg2) {
 31:     MatGetBlockSize(mat,&bs);
 32:   }

 34:   N          = mat->cmap->N/bs;
 35:   c->M       = mat->rmap->N/bs;  /* set total rows, columns and local rows */
 36:   c->N       = mat->cmap->N/bs;
 37:   c->m       = mat->rmap->N/bs;
 38:   c->rstart  = 0;

 40:   c->ncolors = nis;
 41:   PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);
 42:   PetscMalloc(nis*sizeof(PetscInt*),&c->columns);
 43:   PetscMalloc(nis*sizeof(PetscInt),&c->nrows);
 44:   PetscMalloc(nis*sizeof(PetscInt*),&c->rows);
 45:   PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);

 47:   MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);
 48:   if (!done) SETERRQ1(PETSC_ERR_SUP,"MatGetColumnIJ() not supported for matrix type %s",((PetscObject)mat)->type_name);

 50:   /*
 51:      Temporary option to allow for debugging/testing
 52:   */
 53:   PetscOptionsGetTruth(PETSC_NULL,"-matfdcoloring_slow",&flg,PETSC_NULL);

 55:   PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);
 56:   PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);

 58:   for (i=0; i<nis; i++) {
 59:     ISGetLocalSize(isa[i],&n);
 60:     ISGetIndices(isa[i],&is);
 61:     c->ncolumns[i] = n;
 62:     if (n) {
 63:       PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);
 64:       PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));
 65:     } else {
 66:       c->columns[i]  = 0;
 67:     }

 69:     if (!flg) { /* ------------------------------------------------------------------------------*/
 70:       /* fast, crude version requires O(N*N) work */
 71:       PetscMemzero(rowhit,N*sizeof(PetscInt));
 72:       /* loop over columns*/
 73:       for (j=0; j<n; j++) {
 74:         col  = is[j];
 75:         rows = cj + ci[col];
 76:         m    = ci[col+1] - ci[col];
 77:         /* loop over columns marking them in rowhit */
 78:         for (k=0; k<m; k++) {
 79:           rowhit[*rows++] = col + 1;
 80:         }
 81:       }
 82:       /* count the number of hits */
 83:       nrows = 0;
 84:       for (j=0; j<N; j++) {
 85:         if (rowhit[j]) nrows++;
 86:       }
 87:       c->nrows[i] = nrows;
 88:       PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);
 89:       PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);
 90:       nrows       = 0;
 91:       for (j=0; j<N; j++) {
 92:         if (rowhit[j]) {
 93:           c->rows[i][nrows]          = j;
 94:           c->columnsforrow[i][nrows] = rowhit[j] - 1;
 95:           nrows++;
 96:         }
 97:       }
 98:     } else {  /*-------------------------------------------------------------------------------*/
 99:       /* slow version, using rowhit as a linked list */
100:       PetscInt currentcol,fm,mfm;
101:       rowhit[N] = N;
102:       nrows     = 0;
103:       /* loop over columns */
104:       for (j=0; j<n; j++) {
105:         col   = is[j];
106:         rows  = cj + ci[col];
107:         m     = ci[col+1] - ci[col];
108:         /* loop over columns marking them in rowhit */
109:         fm    = N; /* fm points to first entry in linked list */
110:         for (k=0; k<m; k++) {
111:           currentcol = *rows++;
112:           /* is it already in the list? */
113:           do {
114:             mfm  = fm;
115:             fm   = rowhit[fm];
116:           } while (fm < currentcol);
117:           /* not in list so add it */
118:           if (fm != currentcol) {
119:             nrows++;
120:             columnsforrow[currentcol] = col;
121:             /* next three lines insert new entry into linked list */
122:             rowhit[mfm]               = currentcol;
123:             rowhit[currentcol]        = fm;
124:             fm                        = currentcol;
125:             /* fm points to present position in list since we know the columns are sorted */
126:           } else {
127:             SETERRQ(PETSC_ERR_PLIB,"Detected invalid coloring");
128:           }

130:         }
131:       }
132:       c->nrows[i] = nrows;
133:       PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);
134:       PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);
135:       /* now store the linked list of rows into c->rows[i] */
136:       nrows       = 0;
137:       fm          = rowhit[N];
138:       do {
139:         c->rows[i][nrows]            = fm;
140:         c->columnsforrow[i][nrows++] = columnsforrow[fm];
141:         fm                           = rowhit[fm];
142:       } while (fm < N);
143:     } /* ---------------------------------------------------------------------------------------*/
144:     ISRestoreIndices(isa[i],&is);
145:   }
146:   MatRestoreColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);

148:   PetscFree(rowhit);
149:   PetscFree(columnsforrow);

151:   /* Optimize by adding the vscale, and scaleforrow[][] fields */
152:   /*
153:        see the version for MPIAIJ
154:   */
155:   VecCreateGhost(((PetscObject)mat)->comm,mat->rmap->n,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr)
156:   PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);
157:   for (k=0; k<c->ncolors; k++) {
158:     PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);
159:     for (l=0; l<c->nrows[k]; l++) {
160:       col = c->columnsforrow[k][l];
161:       c->vscaleforrow[k][l] = col;
162:     }
163:   }
164:   ISColoringRestoreIS(iscoloring,&isa);
165:   return(0);
166: }