xref: /petsc/src/mat/impls/aij/seq/fdaij.c (revision e32f2f54e699d0aa6e733466c00da7e34666fe5e)
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;
1890d69ab7SBarry Smith   PetscTruth     done,flg = PETSC_FALSE;
193acb8795SBarry Smith   PetscTruth     flg1,flg2;
20639f9d9dSBarry Smith 
213a40ed3dSBarry Smith   PetscFunctionBegin;
22522c5e43SBarry Smith   if (!mat->assembled) {
23*e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();");
24522c5e43SBarry Smith   }
25522c5e43SBarry Smith 
26b9617806SBarry Smith   ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr);
273acb8795SBarry Smith   /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */
283acb8795SBarry Smith   ierr = PetscTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr);
293acb8795SBarry Smith   ierr = PetscTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr);
303acb8795SBarry Smith   if (flg1 || flg2) {
313acb8795SBarry Smith     ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr);
323acb8795SBarry Smith   }
333acb8795SBarry Smith 
343acb8795SBarry Smith   N          = mat->cmap->N/bs;
353acb8795SBarry Smith   c->M       = mat->rmap->N/bs;  /* set total rows, columns and local rows */
363acb8795SBarry Smith   c->N       = mat->cmap->N/bs;
373acb8795SBarry Smith   c->m       = mat->rmap->N/bs;
38005c665bSBarry Smith   c->rstart  = 0;
39005c665bSBarry Smith 
40639f9d9dSBarry Smith   c->ncolors = nis;
4138baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);CHKERRQ(ierr);
4238baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt*),&c->columns);CHKERRQ(ierr);
4338baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt),&c->nrows);CHKERRQ(ierr);
4438baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt*),&c->rows);CHKERRQ(ierr);
4538baddfdSBarry Smith   ierr       = PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);CHKERRQ(ierr);
4643a90d84SBarry Smith 
473acb8795SBarry Smith   ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
48*e32f2f54SBarry Smith   if (!done) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatGetColumnIJ() not supported for matrix type %s",((PetscObject)mat)->type_name);
4970c3da92SBarry Smith 
5070c3da92SBarry Smith   /*
51639f9d9dSBarry Smith      Temporary option to allow for debugging/testing
5270c3da92SBarry Smith   */
5390d69ab7SBarry Smith   ierr = PetscOptionsGetTruth(PETSC_NULL,"-matfdcoloring_slow",&flg,PETSC_NULL);CHKERRQ(ierr);
5470c3da92SBarry Smith 
5538baddfdSBarry Smith   ierr = PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);CHKERRQ(ierr);
5638baddfdSBarry Smith   ierr = PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);CHKERRQ(ierr);
5770c3da92SBarry Smith 
58639f9d9dSBarry Smith   for (i=0; i<nis; i++) {
59b9b97703SBarry Smith     ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr);
60639f9d9dSBarry Smith     ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr);
61639f9d9dSBarry Smith     c->ncolumns[i] = n;
62639f9d9dSBarry Smith     if (n) {
6338baddfdSBarry Smith       ierr = PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);CHKERRQ(ierr);
6438baddfdSBarry Smith       ierr = PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));CHKERRQ(ierr);
6570c3da92SBarry Smith     } else {
66639f9d9dSBarry Smith       c->columns[i]  = 0;
6770c3da92SBarry Smith     }
6870c3da92SBarry Smith 
693a7fca6bSBarry Smith     if (!flg) { /* ------------------------------------------------------------------------------*/
703a7fca6bSBarry Smith       /* fast, crude version requires O(N*N) work */
7138baddfdSBarry Smith       ierr = PetscMemzero(rowhit,N*sizeof(PetscInt));CHKERRQ(ierr);
72639f9d9dSBarry Smith       /* loop over columns*/
73639f9d9dSBarry Smith       for (j=0; j<n; j++) {
74639f9d9dSBarry Smith         col  = is[j];
75639f9d9dSBarry Smith         rows = cj + ci[col];
76639f9d9dSBarry Smith         m    = ci[col+1] - ci[col];
77639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
78639f9d9dSBarry Smith         for (k=0; k<m; k++) {
79639f9d9dSBarry Smith           rowhit[*rows++] = col + 1;
8070c3da92SBarry Smith         }
8170c3da92SBarry Smith       }
82639f9d9dSBarry Smith       /* count the number of hits */
83639f9d9dSBarry Smith       nrows = 0;
8470c3da92SBarry Smith       for (j=0; j<N; j++) {
85639f9d9dSBarry Smith         if (rowhit[j]) nrows++;
86639f9d9dSBarry Smith       }
87639f9d9dSBarry Smith       c->nrows[i] = nrows;
8838baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr);
8938baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr);
90639f9d9dSBarry Smith       nrows       = 0;
91639f9d9dSBarry Smith       for (j=0; j<N; j++) {
92639f9d9dSBarry Smith         if (rowhit[j]) {
93639f9d9dSBarry Smith           c->rows[i][nrows]          = j;
94639f9d9dSBarry Smith           c->columnsforrow[i][nrows] = rowhit[j] - 1;
95639f9d9dSBarry Smith           nrows++;
9670c3da92SBarry Smith         }
9770c3da92SBarry Smith       }
98639f9d9dSBarry Smith     } else {  /*-------------------------------------------------------------------------------*/
993a7fca6bSBarry Smith       /* slow version, using rowhit as a linked list */
10038baddfdSBarry Smith       PetscInt currentcol,fm,mfm;
101639f9d9dSBarry Smith       rowhit[N] = N;
102639f9d9dSBarry Smith       nrows     = 0;
103639f9d9dSBarry Smith       /* loop over columns */
104639f9d9dSBarry Smith       for (j=0; j<n; j++) {
105639f9d9dSBarry Smith         col   = is[j];
106639f9d9dSBarry Smith         rows  = cj + ci[col];
107639f9d9dSBarry Smith         m     = ci[col+1] - ci[col];
108639f9d9dSBarry Smith         /* loop over columns marking them in rowhit */
109639f9d9dSBarry Smith         fm    = N; /* fm points to first entry in linked list */
110639f9d9dSBarry Smith         for (k=0; k<m; k++) {
111639f9d9dSBarry Smith           currentcol = *rows++;
112639f9d9dSBarry Smith 	  /* is it already in the list? */
113639f9d9dSBarry Smith           do {
114639f9d9dSBarry Smith             mfm  = fm;
115639f9d9dSBarry Smith             fm   = rowhit[fm];
116639f9d9dSBarry Smith           } while (fm < currentcol);
117639f9d9dSBarry Smith           /* not in list so add it */
118639f9d9dSBarry Smith           if (fm != currentcol) {
119639f9d9dSBarry Smith             nrows++;
120639f9d9dSBarry Smith             columnsforrow[currentcol] = col;
121639f9d9dSBarry Smith             /* next three lines insert new entry into linked list */
122639f9d9dSBarry Smith             rowhit[mfm]               = currentcol;
123639f9d9dSBarry Smith             rowhit[currentcol]        = fm;
124639f9d9dSBarry Smith             fm                        = currentcol;
125639f9d9dSBarry Smith             /* fm points to present position in list since we know the columns are sorted */
12670c3da92SBarry Smith           } else {
127*e32f2f54SBarry Smith             SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Detected invalid coloring");
12870c3da92SBarry Smith           }
129639f9d9dSBarry Smith 
130639f9d9dSBarry Smith         }
131639f9d9dSBarry Smith       }
132639f9d9dSBarry Smith       c->nrows[i] = nrows;
13338baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr);
13438baddfdSBarry Smith       ierr        = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr);
135639f9d9dSBarry Smith       /* now store the linked list of rows into c->rows[i] */
136639f9d9dSBarry Smith       nrows       = 0;
137639f9d9dSBarry Smith       fm          = rowhit[N];
138639f9d9dSBarry Smith       do {
139639f9d9dSBarry Smith         c->rows[i][nrows]            = fm;
140639f9d9dSBarry Smith         c->columnsforrow[i][nrows++] = columnsforrow[fm];
141639f9d9dSBarry Smith         fm                           = rowhit[fm];
142639f9d9dSBarry Smith       } while (fm < N);
143639f9d9dSBarry Smith     } /* ---------------------------------------------------------------------------------------*/
144639f9d9dSBarry Smith     ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr);
145639f9d9dSBarry Smith   }
1463acb8795SBarry Smith   ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
147639f9d9dSBarry Smith 
148606d414cSSatish Balay   ierr = PetscFree(rowhit);CHKERRQ(ierr);
149606d414cSSatish Balay   ierr = PetscFree(columnsforrow);CHKERRQ(ierr);
150639f9d9dSBarry Smith 
15130b34957SBarry Smith   /* Optimize by adding the vscale, and scaleforrow[][] fields */
15230b34957SBarry Smith   /*
15330b34957SBarry Smith        see the version for MPIAIJ
15430b34957SBarry Smith   */
155d0f46423SBarry Smith   ierr = VecCreateGhost(((PetscObject)mat)->comm,mat->rmap->n,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr)
15638baddfdSBarry Smith   ierr = PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);CHKERRQ(ierr);
15730b34957SBarry Smith   for (k=0; k<c->ncolors; k++) {
15838baddfdSBarry Smith     ierr = PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);CHKERRQ(ierr);
15930b34957SBarry Smith     for (l=0; l<c->nrows[k]; l++) {
16030b34957SBarry Smith       col = c->columnsforrow[k][l];
16130b34957SBarry Smith       c->vscaleforrow[k][l] = col;
16230b34957SBarry Smith     }
16330b34957SBarry Smith   }
164b9617806SBarry Smith   ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr);
1653a40ed3dSBarry Smith   PetscFunctionReturn(0);
16670c3da92SBarry Smith }
167