/*$Id: fdaij.c,v 1.35 2000/10/24 20:25:32 bsmith Exp bsmith $*/ #include "src/mat/impls/aij/seq/aij.h" #include "src/vec/vecimpl.h" EXTERN int MatGetColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*); EXTERN int MatRestoreColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*); #undef __FUNC__ #define __FUNC__ "MatFDColoringCreate_SeqAIJ" int MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) { int i,*is,n,nrows,N = mat->N,j,k,m,*rows,ierr,*ci,*cj,ncols,col; int nis = iscoloring->n,*rowhit,*columnsforrow,l; IS *isa = iscoloring->is; PetscTruth done,flg; PetscFunctionBegin; if (!mat->assembled) { SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); } c->M = mat->M; /* set total rows, columns and local rows */ c->N = mat->N; c->m = mat->M; c->rstart = 0; c->ncolors = nis; ierr = PetscMalloc(nis*sizeof(int),&c->ncolumns);CHKERRQ(ierr); ierr = PetscMalloc(nis*sizeof(int*),&c->columns);CHKERRQ(ierr); ierr = PetscMalloc(nis*sizeof(int),&c->nrows);CHKERRQ(ierr); ierr = PetscMalloc(nis*sizeof(int*),&c->rows);CHKERRQ(ierr); ierr = PetscMalloc(nis*sizeof(int*),&c->columnsforrow);CHKERRQ(ierr); /* Calls the _SeqAIJ() version of these routines to make sure it does not get the reduced (by inodes) version of I and J */ ierr = MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); /* Temporary option to allow for debugging/testing */ ierr = PetscOptionsHasName(PETSC_NULL,"-matfdcoloring_slow",&flg);CHKERRQ(ierr); ierr = PetscMalloc((N+1)*sizeof(int),&rowhit);CHKERRQ(ierr); ierr = PetscMalloc((N+1)*sizeof(int),&columnsforrow);CHKERRQ(ierr); for (i=0; incolumns[i] = n; if (n) { ierr = PetscMalloc(n*sizeof(int),&c->columns[i]);CHKERRQ(ierr); ierr = PetscMemcpy(c->columns[i],is,n*sizeof(int));CHKERRQ(ierr); } else { c->columns[i] = 0; } if (flg) { /* ------------------------------------------------------------------------------*/ /* crude version requires O(N*N) work */ ierr = PetscMemzero(rowhit,N*sizeof(int));CHKERRQ(ierr); /* loop over columns*/ for (j=0; jnrows[i] = nrows; ierr = PetscMalloc(nrows*sizeof(int),&c->rows[i]);CHKERRQ(ierr); ierr = PetscMalloc(nrows*sizeof(int),&c->columnsforrow[i]);CHKERRQ(ierr); nrows = 0; for (j=0; jrows[i][nrows] = j; c->columnsforrow[i][nrows] = rowhit[j] - 1; nrows++; } } } else { /*-------------------------------------------------------------------------------*/ /* efficient version, using rowhit as a linked list */ int currentcol,fm,mfm; rowhit[N] = N; nrows = 0; /* loop over columns */ for (j=0; jnrows[i] = nrows; ierr = PetscMalloc((nrows+1)*sizeof(int),&c->rows[i]);CHKERRQ(ierr); ierr = PetscMalloc((nrows+1)*sizeof(int),&c->columnsforrow[i]);CHKERRQ(ierr); /* now store the linked list of rows into c->rows[i] */ nrows = 0; fm = rowhit[N]; do { c->rows[i][nrows] = fm; c->columnsforrow[i][nrows++] = columnsforrow[fm]; fm = rowhit[fm]; } while (fm < N); } /* ---------------------------------------------------------------------------------------*/ ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr); } ierr = MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); ierr = PetscFree(rowhit);CHKERRQ(ierr); ierr = PetscFree(columnsforrow);CHKERRQ(ierr); /* Optimize by adding the vscale, and scaleforrow[][] fields */ /* see the version for MPIAIJ */ ierr = VecCreateGhost(mat->comm,mat->m,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr) ierr = PetscMalloc(c->ncolors*sizeof(int*),&c->vscaleforrow);CHKERRQ(ierr); for (k=0; kncolors; k++) { ierr = PetscMalloc((c->nrows[k]+1)*sizeof(int),&c->vscaleforrow[k]);CHKERRQ(ierr); for (l=0; lnrows[k]; l++) { col = c->columnsforrow[k][l]; c->vscaleforrow[k][l] = col; } } PetscFunctionReturn(0); } #undef __FUNC__ #define __FUNC__ "MatColoringPatch_SeqAIJ" int MatColoringPatch_SeqAIJ(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) { int n = mat->n,*sizes,i,**ii,ierr,tag; IS *is; PetscFunctionBegin; /* construct the index sets from the coloring array */ ierr = PetscMalloc(ncolors*sizeof(int),&sizes);CHKERRQ(ierr); ierr = PetscMemzero(sizes,ncolors*sizeof(int));CHKERRQ(ierr); for (i=0; in = ncolors; (*iscoloring)->is = is; ierr = PetscCommDuplicate_Private(mat->comm,&(*iscoloring)->comm,&tag);CHKERRQ(ierr); ierr = PetscFree(sizes);CHKERRQ(ierr); ierr = PetscFree(ii[0]);CHKERRQ(ierr); ierr = PetscFree(ii);CHKERRQ(ierr); PetscFunctionReturn(0); } /* Makes a longer coloring[] array and calls the usual code with that */ #undef __FUNC__ #define __FUNC__ "MatColoringPatch_SeqAIJ_Inode" int MatColoringPatch_SeqAIJ_Inode(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) { Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; int n = mat->n,ierr,m = a->inode.node_count,j,*ns = a->inode.size,row; int *colorused,i,*newcolor; PetscFunctionBegin; ierr = PetscMalloc((n+1)*sizeof(int),&newcolor);CHKERRQ(ierr); /* loop over inodes, marking a color for each column*/ row = 0; for (i=0; i