xref: /petsc/src/mat/impls/aij/seq/fdaij.c (revision acfcf0e5ba359b58e6a8a7af3f239cd7334278e8)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
270c3da92SBarry Smith 
37c4f633dSBarry Smith #include "../src/mat/impls/aij/seq/aij.h"
4639f9d9dSBarry Smith 
54a2ae208SSatish Balay #undef __FUNCT__
64a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringCreate_SeqAIJ"
73acb8795SBarry Smith /*
83acb8795SBarry Smith     This routine is shared by AIJ and BAIJ matrices, since it operators only on the nonzero structure of the elements or blocks.
93acb8795SBarry Smith     This is why it has the ugly code with the MatGetBlockSize()
103acb8795SBarry Smith */
11dfbe8321SBarry Smith PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
12639f9d9dSBarry Smith {
136849ba73SBarry Smith   PetscErrorCode ierr;
143acb8795SBarry Smith   PetscInt       i,n,nrows,N,j,k,m,*rows,*ci,*cj,ncols,col;
155d0c19d7SBarry Smith   const PetscInt *is;
163acb8795SBarry Smith   PetscInt       nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1;
17b9617806SBarry Smith   IS             *isa;
18ace3abfcSBarry Smith   PetscBool      done,flg = PETSC_FALSE;
19ace3abfcSBarry Smith   PetscBool      flg1,flg2;
20639f9d9dSBarry Smith 
213a40ed3dSBarry Smith   PetscFunctionBegin;
22e7e72b3dSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();");
23522c5e43SBarry Smith 
24b9617806SBarry Smith   ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr);
253acb8795SBarry Smith   /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */
263acb8795SBarry Smith   ierr = PetscTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr);
273acb8795SBarry Smith   ierr = PetscTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr);
283acb8795SBarry Smith   if (flg1 || flg2) {
293acb8795SBarry Smith     ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr);
303acb8795SBarry Smith   }
313acb8795SBarry Smith 
323acb8795SBarry Smith   N          = mat->cmap->N/bs;
333acb8795SBarry Smith   c->M       = mat->rmap->N/bs;  /* set total rows, columns and local rows */
343acb8795SBarry Smith   c->N       = mat->cmap->N/bs;
353acb8795SBarry Smith   c->m       = mat->rmap->N/bs;
36005c665bSBarry Smith   c->rstart  = 0;
37005c665bSBarry Smith 
38639f9d9dSBarry Smith   c->ncolors = nis;
3938baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);CHKERRQ(ierr);
4038baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt*),&c->columns);CHKERRQ(ierr);
4138baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt),&c->nrows);CHKERRQ(ierr);
4238baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt*),&c->rows);CHKERRQ(ierr);
4338baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);CHKERRQ(ierr);
4443a90d84SBarry Smith 
453acb8795SBarry Smith   ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
4665e19b50SBarry Smith   if (!done) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MatGetColumnIJ() not supported for matrix type %s",((PetscObject)mat)->type_name);
4770c3da92SBarry Smith 
4870c3da92SBarry Smith   /*
49639f9d9dSBarry Smith      Temporary option to allow for debugging/testing
5070c3da92SBarry Smith   */
51*acfcf0e5SJed Brown   ierr = PetscOptionsGetBool(PETSC_NULL,"-matfdcoloring_slow",&flg,PETSC_NULL);CHKERRQ(ierr);
5270c3da92SBarry Smith 
5338baddfdSBarry Smith   ierr = PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);CHKERRQ(ierr);
5438baddfdSBarry Smith   ierr = PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);CHKERRQ(ierr);
5570c3da92SBarry Smith 
56639f9d9dSBarry Smith   for (i=0; i<nis; i++) {
57b9b97703SBarry Smith     ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr);
58639f9d9dSBarry Smith     ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr);
59639f9d9dSBarry Smith     c->ncolumns[i] = n;
60639f9d9dSBarry Smith     if (n) {
6138baddfdSBarry Smith       ierr = PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);CHKERRQ(ierr);
6238baddfdSBarry Smith       ierr = PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));CHKERRQ(ierr);
6370c3da92SBarry Smith     } else {
64639f9d9dSBarry Smith       c->columns[i]  = 0;
6570c3da92SBarry Smith     }
6670c3da92SBarry Smith 
673a7fca6bSBarry Smith     if (!flg) { /* ------------------------------------------------------------------------------*/
683a7fca6bSBarry Smith       /* fast, crude version requires O(N*N) work */
6938baddfdSBarry Smith       ierr = PetscMemzero(rowhit,N*sizeof(PetscInt));CHKERRQ(ierr);
70639f9d9dSBarry Smith       /* loop over columns*/
71639f9d9dSBarry Smith       for (j=0; j<n; j++) {
72639f9d9dSBarry Smith         col  = is[j];
73639f9d9dSBarry Smith         rows = cj + ci[col];
74639f9d9dSBarry Smith         m    = ci[col+1] - ci[col];
75639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
76639f9d9dSBarry Smith         for (k=0; k<m; k++) {
77639f9d9dSBarry Smith           rowhit[*rows++] = col + 1;
7870c3da92SBarry Smith         }
7970c3da92SBarry Smith       }
80639f9d9dSBarry Smith       /* count the number of hits */
81639f9d9dSBarry Smith       nrows = 0;
8270c3da92SBarry Smith       for (j=0; j<N; j++) {
83639f9d9dSBarry Smith         if (rowhit[j]) nrows++;
84639f9d9dSBarry Smith       }
85639f9d9dSBarry Smith       c->nrows[i] = nrows;
8638baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr);
8738baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr);
88639f9d9dSBarry Smith       nrows       = 0;
89639f9d9dSBarry Smith       for (j=0; j<N; j++) {
90639f9d9dSBarry Smith         if (rowhit[j]) {
91639f9d9dSBarry Smith           c->rows[i][nrows]          = j;
92639f9d9dSBarry Smith           c->columnsforrow[i][nrows] = rowhit[j] - 1;
93639f9d9dSBarry Smith           nrows++;
9470c3da92SBarry Smith         }
9570c3da92SBarry Smith       }
96639f9d9dSBarry Smith     } else {  /*-------------------------------------------------------------------------------*/
973a7fca6bSBarry Smith       /* slow version, using rowhit as a linked list */
9838baddfdSBarry Smith       PetscInt currentcol,fm,mfm;
99639f9d9dSBarry Smith       rowhit[N] = N;
100639f9d9dSBarry Smith       nrows     = 0;
101639f9d9dSBarry Smith       /* loop over columns */
102639f9d9dSBarry Smith       for (j=0; j<n; j++) {
103639f9d9dSBarry Smith         col   = is[j];
104639f9d9dSBarry Smith         rows  = cj + ci[col];
105639f9d9dSBarry Smith         m     = ci[col+1] - ci[col];
106639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
107639f9d9dSBarry Smith         fm    = N; /* fm points to first entry in linked list */
108639f9d9dSBarry Smith         for (k=0; k<m; k++) {
109639f9d9dSBarry Smith           currentcol = *rows++;
110639f9d9dSBarry Smith 	  /* is it already in the list? */
111639f9d9dSBarry Smith           do {
112639f9d9dSBarry Smith             mfm  = fm;
113639f9d9dSBarry Smith             fm   = rowhit[fm];
114639f9d9dSBarry Smith           } while (fm < currentcol);
115639f9d9dSBarry Smith           /* not in list so add it */
116639f9d9dSBarry Smith           if (fm != currentcol) {
117639f9d9dSBarry Smith             nrows++;
118639f9d9dSBarry Smith             columnsforrow[currentcol] = col;
119639f9d9dSBarry Smith             /* next three lines insert new entry into linked list */
120639f9d9dSBarry Smith             rowhit[mfm]               = currentcol;
121639f9d9dSBarry Smith             rowhit[currentcol]        = fm;
122639f9d9dSBarry Smith             fm                        = currentcol;
123639f9d9dSBarry Smith             /* fm points to present position in list since we know the columns are sorted */
12470c3da92SBarry Smith           } else {
125e32f2f54SBarry Smith             SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Detected invalid coloring");
12670c3da92SBarry Smith           }
127639f9d9dSBarry Smith 
128639f9d9dSBarry Smith         }
129639f9d9dSBarry Smith       }
130639f9d9dSBarry Smith       c->nrows[i] = nrows;
13138baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr);
13238baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr);
133639f9d9dSBarry Smith       /* now store the linked list of rows into c->rows[i] */
134639f9d9dSBarry Smith       nrows       = 0;
135639f9d9dSBarry Smith       fm          = rowhit[N];
136639f9d9dSBarry Smith       do {
137639f9d9dSBarry Smith         c->rows[i][nrows]            = fm;
138639f9d9dSBarry Smith         c->columnsforrow[i][nrows++] = columnsforrow[fm];
139639f9d9dSBarry Smith         fm                           = rowhit[fm];
140639f9d9dSBarry Smith       } while (fm < N);
141639f9d9dSBarry Smith     } /* ---------------------------------------------------------------------------------------*/
142639f9d9dSBarry Smith     ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr);
143639f9d9dSBarry Smith   }
1443acb8795SBarry Smith   ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
145639f9d9dSBarry Smith 
146606d414cSSatish Balay   ierr = PetscFree(rowhit);CHKERRQ(ierr);
147606d414cSSatish Balay   ierr = PetscFree(columnsforrow);CHKERRQ(ierr);
148639f9d9dSBarry Smith 
14930b34957SBarry Smith   /* Optimize by adding the vscale, and scaleforrow[][] fields */
15030b34957SBarry Smith   /*
15130b34957SBarry Smith        see the version for MPIAIJ
15230b34957SBarry Smith   */
153cb9801acSJed Brown   ierr = VecCreateGhost(((PetscObject)mat)->comm,mat->rmap->n,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr);
15438baddfdSBarry Smith   ierr = PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);CHKERRQ(ierr);
15530b34957SBarry Smith   for (k=0; k<c->ncolors; k++) {
15638baddfdSBarry Smith     ierr = PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);CHKERRQ(ierr);
15730b34957SBarry Smith     for (l=0; l<c->nrows[k]; l++) {
15830b34957SBarry Smith       col = c->columnsforrow[k][l];
15930b34957SBarry Smith       c->vscaleforrow[k][l] = col;
16030b34957SBarry Smith     }
16130b34957SBarry Smith   }
162b9617806SBarry Smith   ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr);
1633a40ed3dSBarry Smith   PetscFunctionReturn(0);
16470c3da92SBarry Smith }
165