xref: /petsc/src/mat/impls/aij/seq/fdaij.c (revision 71cd77b2943dcd1bc5a309caa7d35086e59f45ae)
170c3da92SBarry Smith 
2c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>
3639f9d9dSBarry Smith 
44a2ae208SSatish Balay #undef __FUNCT__
54a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringCreate_SeqAIJ"
63acb8795SBarry Smith /*
73acb8795SBarry Smith     This routine is shared by AIJ and BAIJ matrices, since it operators only on the nonzero structure of the elements or blocks.
83acb8795SBarry Smith     This is why it has the ugly code with the MatGetBlockSize()
93acb8795SBarry Smith */
10dfbe8321SBarry Smith PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
11639f9d9dSBarry Smith {
126849ba73SBarry Smith   PetscErrorCode ierr;
133acb8795SBarry Smith   PetscInt       i,n,nrows,N,j,k,m,*rows,*ci,*cj,ncols,col;
145d0c19d7SBarry Smith   const PetscInt *is;
153acb8795SBarry Smith   PetscInt       nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1;
16b9617806SBarry Smith   IS             *isa;
17ace3abfcSBarry Smith   PetscBool      done,flg = PETSC_FALSE;
18ace3abfcSBarry Smith   PetscBool      flg1,flg2;
19639f9d9dSBarry Smith 
203a40ed3dSBarry Smith   PetscFunctionBegin;
21e7e72b3dSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();");
22522c5e43SBarry Smith 
23b9617806SBarry Smith   ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr);
243acb8795SBarry Smith   /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */
253acb8795SBarry Smith   ierr = PetscTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr);
263acb8795SBarry Smith   ierr = PetscTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr);
273acb8795SBarry Smith   if (flg1 || flg2) {
283acb8795SBarry Smith     ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr);
293acb8795SBarry Smith   }
303acb8795SBarry Smith 
313acb8795SBarry Smith   N          = mat->cmap->N/bs;
323acb8795SBarry Smith   c->M       = mat->rmap->N/bs;  /* set total rows, columns and local rows */
333acb8795SBarry Smith   c->N       = mat->cmap->N/bs;
343acb8795SBarry Smith   c->m       = mat->rmap->N/bs;
35005c665bSBarry Smith   c->rstart  = 0;
36005c665bSBarry Smith 
37639f9d9dSBarry Smith   c->ncolors = nis;
3838baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);CHKERRQ(ierr);
3938baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt*),&c->columns);CHKERRQ(ierr);
4038baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt),&c->nrows);CHKERRQ(ierr);
4138baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt*),&c->rows);CHKERRQ(ierr);
4238baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);CHKERRQ(ierr);
4343a90d84SBarry Smith 
443acb8795SBarry Smith   ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
4565e19b50SBarry Smith   if (!done) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MatGetColumnIJ() not supported for matrix type %s",((PetscObject)mat)->type_name);
4670c3da92SBarry Smith 
4770c3da92SBarry Smith   /*
48639f9d9dSBarry Smith      Temporary option to allow for debugging/testing
4970c3da92SBarry Smith   */
50acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(PETSC_NULL,"-matfdcoloring_slow",&flg,PETSC_NULL);CHKERRQ(ierr);
5170c3da92SBarry Smith 
5238baddfdSBarry Smith   ierr = PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);CHKERRQ(ierr);
5338baddfdSBarry Smith   ierr = PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);CHKERRQ(ierr);
5470c3da92SBarry Smith 
55639f9d9dSBarry Smith   for (i=0; i<nis; i++) {
56b9b97703SBarry Smith     ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr);
57639f9d9dSBarry Smith     ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr);
58639f9d9dSBarry Smith     c->ncolumns[i] = n;
59639f9d9dSBarry Smith     if (n) {
6038baddfdSBarry Smith       ierr = PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);CHKERRQ(ierr);
6138baddfdSBarry Smith       ierr = PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));CHKERRQ(ierr);
6270c3da92SBarry Smith     } else {
63639f9d9dSBarry Smith       c->columns[i]  = 0;
6470c3da92SBarry Smith     }
6570c3da92SBarry Smith 
663a7fca6bSBarry Smith     if (!flg) { /* ------------------------------------------------------------------------------*/
673a7fca6bSBarry Smith       /* fast, crude version requires O(N*N) work */
6838baddfdSBarry Smith       ierr = PetscMemzero(rowhit,N*sizeof(PetscInt));CHKERRQ(ierr);
69639f9d9dSBarry Smith       /* loop over columns*/
70639f9d9dSBarry Smith       for (j=0; j<n; j++) {
71639f9d9dSBarry Smith         col  = is[j];
72639f9d9dSBarry Smith         rows = cj + ci[col];
73639f9d9dSBarry Smith         m    = ci[col+1] - ci[col];
74639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
75639f9d9dSBarry Smith         for (k=0; k<m; k++) {
76639f9d9dSBarry Smith           rowhit[*rows++] = col + 1;
7770c3da92SBarry Smith         }
7870c3da92SBarry Smith       }
79639f9d9dSBarry Smith       /* count the number of hits */
80639f9d9dSBarry Smith       nrows = 0;
8170c3da92SBarry Smith       for (j=0; j<N; j++) {
82639f9d9dSBarry Smith         if (rowhit[j]) nrows++;
83639f9d9dSBarry Smith       }
84639f9d9dSBarry Smith       c->nrows[i] = nrows;
8538baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr);
8638baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr);
87639f9d9dSBarry Smith       nrows       = 0;
88639f9d9dSBarry Smith       for (j=0; j<N; j++) {
89639f9d9dSBarry Smith         if (rowhit[j]) {
90639f9d9dSBarry Smith           c->rows[i][nrows]          = j;
91639f9d9dSBarry Smith           c->columnsforrow[i][nrows] = rowhit[j] - 1;
92639f9d9dSBarry Smith           nrows++;
9370c3da92SBarry Smith         }
9470c3da92SBarry Smith       }
95639f9d9dSBarry Smith     } else {  /*-------------------------------------------------------------------------------*/
963a7fca6bSBarry Smith       /* slow version, using rowhit as a linked list */
9738baddfdSBarry Smith       PetscInt currentcol,fm,mfm;
98639f9d9dSBarry Smith       rowhit[N] = N;
99639f9d9dSBarry Smith       nrows     = 0;
100639f9d9dSBarry Smith       /* loop over columns */
101639f9d9dSBarry Smith       for (j=0; j<n; j++) {
102639f9d9dSBarry Smith         col   = is[j];
103639f9d9dSBarry Smith         rows  = cj + ci[col];
104639f9d9dSBarry Smith         m     = ci[col+1] - ci[col];
105639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
106639f9d9dSBarry Smith         fm    = N; /* fm points to first entry in linked list */
107639f9d9dSBarry Smith         for (k=0; k<m; k++) {
108639f9d9dSBarry Smith           currentcol = *rows++;
109639f9d9dSBarry Smith 	  /* is it already in the list? */
110639f9d9dSBarry Smith           do {
111639f9d9dSBarry Smith             mfm  = fm;
112639f9d9dSBarry Smith             fm   = rowhit[fm];
113639f9d9dSBarry Smith           } while (fm < currentcol);
114639f9d9dSBarry Smith           /* not in list so add it */
115639f9d9dSBarry Smith           if (fm != currentcol) {
116639f9d9dSBarry Smith             nrows++;
117639f9d9dSBarry Smith             columnsforrow[currentcol] = col;
118639f9d9dSBarry Smith             /* next three lines insert new entry into linked list */
119639f9d9dSBarry Smith             rowhit[mfm]               = currentcol;
120639f9d9dSBarry Smith             rowhit[currentcol]        = fm;
121639f9d9dSBarry Smith             fm                        = currentcol;
122639f9d9dSBarry Smith             /* fm points to present position in list since we know the columns are sorted */
123*71cd77b2SBarry Smith           } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Detected invalid coloring");
124639f9d9dSBarry Smith         }
125639f9d9dSBarry Smith       }
126639f9d9dSBarry Smith       c->nrows[i] = nrows;
12738baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr);
12838baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr);
129639f9d9dSBarry Smith       /* now store the linked list of rows into c->rows[i] */
130639f9d9dSBarry Smith       nrows       = 0;
131639f9d9dSBarry Smith       fm          = rowhit[N];
132639f9d9dSBarry Smith       do {
133639f9d9dSBarry Smith         c->rows[i][nrows]            = fm;
134639f9d9dSBarry Smith         c->columnsforrow[i][nrows++] = columnsforrow[fm];
135639f9d9dSBarry Smith         fm                           = rowhit[fm];
136639f9d9dSBarry Smith       } while (fm < N);
137639f9d9dSBarry Smith     } /* ---------------------------------------------------------------------------------------*/
138639f9d9dSBarry Smith     ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr);
139639f9d9dSBarry Smith   }
1403acb8795SBarry Smith   ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
141639f9d9dSBarry Smith 
142606d414cSSatish Balay   ierr = PetscFree(rowhit);CHKERRQ(ierr);
143606d414cSSatish Balay   ierr = PetscFree(columnsforrow);CHKERRQ(ierr);
144639f9d9dSBarry Smith 
14530b34957SBarry Smith   /* Optimize by adding the vscale, and scaleforrow[][] fields */
14630b34957SBarry Smith   /*
14730b34957SBarry Smith        see the version for MPIAIJ
14830b34957SBarry Smith   */
149cb9801acSJed Brown   ierr = VecCreateGhost(((PetscObject)mat)->comm,mat->rmap->n,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr);
15038baddfdSBarry Smith   ierr = PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);CHKERRQ(ierr);
15130b34957SBarry Smith   for (k=0; k<c->ncolors; k++) {
15238baddfdSBarry Smith     ierr = PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);CHKERRQ(ierr);
15330b34957SBarry Smith     for (l=0; l<c->nrows[k]; l++) {
15430b34957SBarry Smith       col = c->columnsforrow[k][l];
15530b34957SBarry Smith       c->vscaleforrow[k][l] = col;
15630b34957SBarry Smith     }
15730b34957SBarry Smith   }
158b9617806SBarry Smith   ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr);
1593a40ed3dSBarry Smith   PetscFunctionReturn(0);
16070c3da92SBarry Smith }
161