Actual source code: fdaij.c
1: #define PETSCMAT_DLL
3: #include src/mat/impls/aij/seq/aij.h
7: PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
8: {
10: PetscInt i,*is,n,nrows,N = mat->cmap.N,j,k,m,*rows,*ci,*cj,ncols,col;
11: PetscInt nis = iscoloring->n,*rowhit,*columnsforrow,l;
12: IS *isa;
13: PetscTruth done,flg;
16: if (!mat->assembled) {
17: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();");
18: }
20: ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);
21: c->M = mat->rmap.N; /* set total rows, columns and local rows */
22: c->N = mat->cmap.N;
23: c->m = mat->rmap.N;
24: c->rstart = 0;
26: c->ncolors = nis;
27: PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);
28: PetscMalloc(nis*sizeof(PetscInt*),&c->columns);
29: PetscMalloc(nis*sizeof(PetscInt),&c->nrows);
30: PetscMalloc(nis*sizeof(PetscInt*),&c->rows);
31: PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);
33: /*
34: Calls the _SeqAIJ() version of these routines to make sure it does not
35: get the reduced (by inodes) version of I and J
36: */
37: MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);
39: /*
40: Temporary option to allow for debugging/testing
41: */
42: PetscOptionsHasName(PETSC_NULL,"-matfdcoloring_slow",&flg);
44: PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);
45: PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);
47: for (i=0; i<nis; i++) {
48: ISGetLocalSize(isa[i],&n);
49: ISGetIndices(isa[i],&is);
50: c->ncolumns[i] = n;
51: if (n) {
52: PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);
53: PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));
54: } else {
55: c->columns[i] = 0;
56: }
58: if (!flg) { /* ------------------------------------------------------------------------------*/
59: /* fast, crude version requires O(N*N) work */
60: PetscMemzero(rowhit,N*sizeof(PetscInt));
61: /* loop over columns*/
62: for (j=0; j<n; j++) {
63: col = is[j];
64: rows = cj + ci[col];
65: m = ci[col+1] - ci[col];
66: /* loop over columns marking them in rowhit */
67: for (k=0; k<m; k++) {
68: rowhit[*rows++] = col + 1;
69: }
70: }
71: /* count the number of hits */
72: nrows = 0;
73: for (j=0; j<N; j++) {
74: if (rowhit[j]) nrows++;
75: }
76: c->nrows[i] = nrows;
77: PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);
78: PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);
79: nrows = 0;
80: for (j=0; j<N; j++) {
81: if (rowhit[j]) {
82: c->rows[i][nrows] = j;
83: c->columnsforrow[i][nrows] = rowhit[j] - 1;
84: nrows++;
85: }
86: }
87: } else { /*-------------------------------------------------------------------------------*/
88: /* slow version, using rowhit as a linked list */
89: PetscInt currentcol,fm,mfm;
90: rowhit[N] = N;
91: nrows = 0;
92: /* loop over columns */
93: for (j=0; j<n; j++) {
94: col = is[j];
95: rows = cj + ci[col];
96: m = ci[col+1] - ci[col];
97: /* loop over columns marking them in rowhit */
98: fm = N; /* fm points to first entry in linked list */
99: for (k=0; k<m; k++) {
100: currentcol = *rows++;
101: /* is it already in the list? */
102: do {
103: mfm = fm;
104: fm = rowhit[fm];
105: } while (fm < currentcol);
106: /* not in list so add it */
107: if (fm != currentcol) {
108: nrows++;
109: columnsforrow[currentcol] = col;
110: /* next three lines insert new entry into linked list */
111: rowhit[mfm] = currentcol;
112: rowhit[currentcol] = fm;
113: fm = currentcol;
114: /* fm points to present position in list since we know the columns are sorted */
115: } else {
116: SETERRQ(PETSC_ERR_PLIB,"Detected invalid coloring");
117: }
119: }
120: }
121: c->nrows[i] = nrows;
122: PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);
123: PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);
124: /* now store the linked list of rows into c->rows[i] */
125: nrows = 0;
126: fm = rowhit[N];
127: do {
128: c->rows[i][nrows] = fm;
129: c->columnsforrow[i][nrows++] = columnsforrow[fm];
130: fm = rowhit[fm];
131: } while (fm < N);
132: } /* ---------------------------------------------------------------------------------------*/
133: ISRestoreIndices(isa[i],&is);
134: }
135: MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);
137: PetscFree(rowhit);
138: PetscFree(columnsforrow);
140: /* Optimize by adding the vscale, and scaleforrow[][] fields */
141: /*
142: see the version for MPIAIJ
143: */
144: VecCreateGhost(mat->comm,mat->rmap.n,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr)
145: PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);
146: for (k=0; k<c->ncolors; k++) {
147: PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);
148: for (l=0; l<c->nrows[k]; l++) {
149: col = c->columnsforrow[k][l];
150: c->vscaleforrow[k][l] = col;
151: }
152: }
153: ISColoringRestoreIS(iscoloring,&isa);
154: return(0);
155: }