xref: /petsc/src/mat/impls/aij/seq/fdaij.c (revision 3acb87959449f26430bfb44c593b059e1dfb39fd)
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"
7*3acb8795SBarry Smith /*
8*3acb8795SBarry Smith     This routine is shared by AIJ and BAIJ matrices, since it operators only on the nonzero structure of the elements or blocks.
9*3acb8795SBarry Smith     This is why it has the ugly code with the MatGetBlockSize()
10*3acb8795SBarry Smith */
11dfbe8321SBarry Smith PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
12639f9d9dSBarry Smith {
136849ba73SBarry Smith   PetscErrorCode ierr;
14*3acb8795SBarry Smith   PetscInt       i,n,nrows,N,j,k,m,*rows,*ci,*cj,ncols,col;
155d0c19d7SBarry Smith   const PetscInt *is;
16*3acb8795SBarry Smith   PetscInt       nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1;
17b9617806SBarry Smith   IS             *isa;
1890d69ab7SBarry Smith   PetscTruth     done,flg = PETSC_FALSE;
19*3acb8795SBarry Smith   PetscTruth     flg1,flg2;
20639f9d9dSBarry Smith 
213a40ed3dSBarry Smith   PetscFunctionBegin;
22522c5e43SBarry Smith   if (!mat->assembled) {
2329bbc08cSBarry Smith     SETERRQ(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);
27*3acb8795SBarry Smith   /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */
28*3acb8795SBarry Smith   ierr = PetscTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr);
29*3acb8795SBarry Smith   ierr = PetscTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr);
30*3acb8795SBarry Smith   if (flg1 || flg2) {
31*3acb8795SBarry Smith     ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr);
32*3acb8795SBarry Smith   }
33*3acb8795SBarry Smith 
34*3acb8795SBarry Smith   N          = mat->cmap->N/bs;
35*3acb8795SBarry Smith   c->M       = mat->rmap->N/bs;  /* set total rows, columns and local rows */
36*3acb8795SBarry Smith   c->N       = mat->cmap->N/bs;
37*3acb8795SBarry 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 
47*3acb8795SBarry Smith   ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr);
48*3acb8795SBarry Smith   if (!done) SETERRQ1(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 {
12729bbc08cSBarry Smith             SETERRQ(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   }
146*3acb8795SBarry 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