1*b97cf49bSBarry Smith #ifdef PETSC_RCS_HEADER 2*b97cf49bSBarry Smith static char vcid[] = "$Id: adj.c,v 1.5 1997/08/22 15:14:50 bsmith Exp $"; 3*b97cf49bSBarry Smith #endif 4*b97cf49bSBarry Smith 5*b97cf49bSBarry Smith /* 6*b97cf49bSBarry Smith Defines the basic matrix operations for the ADJ adjacency list matrix data-structure. 7*b97cf49bSBarry Smith */ 8*b97cf49bSBarry Smith 9*b97cf49bSBarry Smith #include "pinclude/pviewer.h" 10*b97cf49bSBarry Smith #include "sys.h" 11*b97cf49bSBarry Smith #include "src/mat/impls/adj/seq/adj.h" 12*b97cf49bSBarry Smith #include "src/inline/bitarray.h" 13*b97cf49bSBarry Smith 14*b97cf49bSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 15*b97cf49bSBarry Smith 16*b97cf49bSBarry Smith #undef __FUNC__ 17*b97cf49bSBarry Smith #define __FUNC__ "MatGetRowIJ_SeqAdj" 18*b97cf49bSBarry Smith int MatGetRowIJ_SeqAdj(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja, 19*b97cf49bSBarry Smith PetscTruth *done) 20*b97cf49bSBarry Smith { 21*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 22*b97cf49bSBarry Smith int ierr,i; 23*b97cf49bSBarry Smith 24*b97cf49bSBarry Smith *m = A->m; 25*b97cf49bSBarry Smith if (!ia) return 0; 26*b97cf49bSBarry Smith if (symmetric && !a->symmetric) { 27*b97cf49bSBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,0,oshift,ia,ja); CHKERRQ(ierr); 28*b97cf49bSBarry Smith } else if (oshift == 1) { 29*b97cf49bSBarry Smith int nz = a->i[a->m] + 1; 30*b97cf49bSBarry Smith /* malloc space and add 1 to i and j indices */ 31*b97cf49bSBarry Smith *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) ); CHKPTRQ(*ia); 32*b97cf49bSBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja); 33*b97cf49bSBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] + 1; 34*b97cf49bSBarry Smith for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] + 1; 35*b97cf49bSBarry Smith } else { 36*b97cf49bSBarry Smith *ia = a->i; *ja = a->j; 37*b97cf49bSBarry Smith } 38*b97cf49bSBarry Smith 39*b97cf49bSBarry Smith return 0; 40*b97cf49bSBarry Smith } 41*b97cf49bSBarry Smith 42*b97cf49bSBarry Smith #undef __FUNC__ 43*b97cf49bSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqAdj" 44*b97cf49bSBarry Smith int MatRestoreRowIJ_SeqAdj(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja, 45*b97cf49bSBarry Smith PetscTruth *done) 46*b97cf49bSBarry Smith { 47*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 48*b97cf49bSBarry Smith 49*b97cf49bSBarry Smith if (!ia) return 0; 50*b97cf49bSBarry Smith if ((symmetric && !a->symmetric) || oshift == 1) { 51*b97cf49bSBarry Smith PetscFree(*ia); 52*b97cf49bSBarry Smith PetscFree(*ja); 53*b97cf49bSBarry Smith } 54*b97cf49bSBarry Smith return 0; 55*b97cf49bSBarry Smith } 56*b97cf49bSBarry Smith 57*b97cf49bSBarry Smith #undef __FUNC__ 58*b97cf49bSBarry Smith #define __FUNC__ "MatView_SeqAdj_Binary" 59*b97cf49bSBarry Smith extern int MatView_SeqAdj_Binary(Mat A,Viewer viewer) 60*b97cf49bSBarry Smith { 61*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 62*b97cf49bSBarry Smith int i, fd, *col_lens, ierr; 63*b97cf49bSBarry Smith Scalar *values; 64*b97cf49bSBarry Smith 65*b97cf49bSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 66*b97cf49bSBarry Smith col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) ); CHKPTRQ(col_lens); 67*b97cf49bSBarry Smith col_lens[0] = MAT_COOKIE; 68*b97cf49bSBarry Smith col_lens[1] = a->m; 69*b97cf49bSBarry Smith col_lens[2] = a->n; 70*b97cf49bSBarry Smith col_lens[3] = a->nz; 71*b97cf49bSBarry Smith 72*b97cf49bSBarry Smith /* store lengths of each row and write (including header) to file */ 73*b97cf49bSBarry Smith for ( i=0; i<a->m; i++ ) { 74*b97cf49bSBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 75*b97cf49bSBarry Smith } 76*b97cf49bSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,BINARY_INT,1); CHKERRQ(ierr); 77*b97cf49bSBarry Smith PetscFree(col_lens); 78*b97cf49bSBarry Smith 79*b97cf49bSBarry Smith /* store column indices (zero start index) */ 80*b97cf49bSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,BINARY_INT,0); CHKERRQ(ierr); 81*b97cf49bSBarry Smith 82*b97cf49bSBarry Smith /* store nonzero values */ 83*b97cf49bSBarry Smith values = (Scalar *) PetscMalloc( a->nz*sizeof(Scalar) );CHKPTRQ(values); 84*b97cf49bSBarry Smith PetscMemzero(values,a->nz*sizeof(Scalar) ); 85*b97cf49bSBarry Smith ierr = PetscBinaryWrite(fd,values,a->nz,BINARY_SCALAR,0); CHKERRQ(ierr); 86*b97cf49bSBarry Smith PetscFree(values); 87*b97cf49bSBarry Smith return 0; 88*b97cf49bSBarry Smith } 89*b97cf49bSBarry Smith 90*b97cf49bSBarry Smith #undef __FUNC__ 91*b97cf49bSBarry Smith #define __FUNC__ "MatView_SeqAdj_ASCII" 92*b97cf49bSBarry Smith extern int MatView_SeqAdj_ASCII(Mat A,Viewer viewer) 93*b97cf49bSBarry Smith { 94*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 95*b97cf49bSBarry Smith int ierr, i,j, m = a->m, format; 96*b97cf49bSBarry Smith FILE *fd; 97*b97cf49bSBarry Smith char *outputname; 98*b97cf49bSBarry Smith 99*b97cf49bSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 100*b97cf49bSBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname); CHKERRQ(ierr); 101*b97cf49bSBarry Smith ierr = ViewerGetFormat(viewer,&format); 102*b97cf49bSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO) { 103*b97cf49bSBarry Smith return 0; 104*b97cf49bSBarry Smith } 105*b97cf49bSBarry Smith else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 106*b97cf49bSBarry Smith fprintf(fd,"%% Size = %d %d \n",m,a->n); 107*b97cf49bSBarry Smith fprintf(fd,"%% Nonzeros = %d \n",a->nz); 108*b97cf49bSBarry Smith fprintf(fd,"zzz = zeros(%d,3);\n",a->nz); 109*b97cf49bSBarry Smith fprintf(fd,"zzz = [\n"); 110*b97cf49bSBarry Smith 111*b97cf49bSBarry Smith for (i=0; i<m; i++) { 112*b97cf49bSBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 113*b97cf49bSBarry Smith #if defined(PETSC_COMPLEX) 114*b97cf49bSBarry Smith fprintf(fd,"%d %d %18.16e + %18.16e i \n",i+1,a->j[j],0.0,0.0); 115*b97cf49bSBarry Smith #else 116*b97cf49bSBarry Smith fprintf(fd,"%d %d %18.16e\n", i+1, a->j[j], 0.0); 117*b97cf49bSBarry Smith #endif 118*b97cf49bSBarry Smith } 119*b97cf49bSBarry Smith } 120*b97cf49bSBarry Smith fprintf(fd,"];\n %s = spconvert(zzz);\n",outputname); 121*b97cf49bSBarry Smith } 122*b97cf49bSBarry Smith else if (format == VIEWER_FORMAT_ASCII_COMMON) { 123*b97cf49bSBarry Smith for ( i=0; i<m; i++ ) { 124*b97cf49bSBarry Smith fprintf(fd,"row %d:",i); 125*b97cf49bSBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 126*b97cf49bSBarry Smith #if defined(PETSC_COMPLEX) 127*b97cf49bSBarry Smith fprintf(fd," %d %g + %g i",a->j[j],0.0,0.0); 128*b97cf49bSBarry Smith #else 129*b97cf49bSBarry Smith fprintf(fd," %d %g ",a->j[j],0.0); 130*b97cf49bSBarry Smith #endif 131*b97cf49bSBarry Smith } 132*b97cf49bSBarry Smith fprintf(fd,"\n"); 133*b97cf49bSBarry Smith } 134*b97cf49bSBarry Smith } 135*b97cf49bSBarry Smith else { 136*b97cf49bSBarry Smith for ( i=0; i<m; i++ ) { 137*b97cf49bSBarry Smith fprintf(fd,"row %d:",i); 138*b97cf49bSBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 139*b97cf49bSBarry Smith #if defined(PETSC_COMPLEX) 140*b97cf49bSBarry Smith fprintf(fd," %d %g + %g i",a->j[j],0.0,0.0); 141*b97cf49bSBarry Smith #else 142*b97cf49bSBarry Smith fprintf(fd," %d %g ",a->j[j],0.0); 143*b97cf49bSBarry Smith #endif 144*b97cf49bSBarry Smith } 145*b97cf49bSBarry Smith fprintf(fd,"\n"); 146*b97cf49bSBarry Smith } 147*b97cf49bSBarry Smith } 148*b97cf49bSBarry Smith fflush(fd); 149*b97cf49bSBarry Smith return 0; 150*b97cf49bSBarry Smith } 151*b97cf49bSBarry Smith 152*b97cf49bSBarry Smith #undef __FUNC__ 153*b97cf49bSBarry Smith #define __FUNC__ "MatView_SeqAdj_Draw" 154*b97cf49bSBarry Smith extern int MatView_SeqAdj_Draw(Mat A,Viewer viewer) 155*b97cf49bSBarry Smith { 156*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 157*b97cf49bSBarry Smith int ierr, i,j, m = a->m,color; 158*b97cf49bSBarry Smith int format; 159*b97cf49bSBarry Smith double xl,yl,xr,yr,w,h,x_l,x_r,y_l,y_r; 160*b97cf49bSBarry Smith Draw draw; 161*b97cf49bSBarry Smith PetscTruth isnull; 162*b97cf49bSBarry Smith 163*b97cf49bSBarry Smith ierr = ViewerDrawGetDraw(viewer,&draw); CHKERRQ(ierr); 164*b97cf49bSBarry Smith ierr = DrawCheckResizedWindow(draw); CHKERRQ(ierr); 165*b97cf49bSBarry Smith ierr = DrawClear(draw); CHKERRQ(ierr); 166*b97cf49bSBarry Smith ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr); 167*b97cf49bSBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) return 0; 168*b97cf49bSBarry Smith 169*b97cf49bSBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 170*b97cf49bSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 171*b97cf49bSBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 172*b97cf49bSBarry Smith /* loop over matrix elements drawing boxes */ 173*b97cf49bSBarry Smith 174*b97cf49bSBarry Smith if (format != VIEWER_FORMAT_DRAW_CONTOUR) { 175*b97cf49bSBarry Smith color = DRAW_BLUE; 176*b97cf49bSBarry Smith for ( i=0; i<m; i++ ) { 177*b97cf49bSBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 178*b97cf49bSBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 179*b97cf49bSBarry Smith x_l = a->j[j]; x_r = x_l + 1.0; 180*b97cf49bSBarry Smith DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color); 181*b97cf49bSBarry Smith } 182*b97cf49bSBarry Smith } 183*b97cf49bSBarry Smith } 184*b97cf49bSBarry Smith ierr = DrawPause(draw); CHKERRQ(ierr); 185*b97cf49bSBarry Smith return 0; 186*b97cf49bSBarry Smith } 187*b97cf49bSBarry Smith 188*b97cf49bSBarry Smith #undef __FUNC__ 189*b97cf49bSBarry Smith #define __FUNC__ "MatView_SeqAdj" 190*b97cf49bSBarry Smith int MatView_SeqAdj(PetscObject obj,Viewer viewer) 191*b97cf49bSBarry Smith { 192*b97cf49bSBarry Smith Mat A = (Mat) obj; 193*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj*) A->data; 194*b97cf49bSBarry Smith ViewerType vtype; 195*b97cf49bSBarry Smith int ierr; 196*b97cf49bSBarry Smith 197*b97cf49bSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 198*b97cf49bSBarry Smith if (vtype == MATLAB_VIEWER) { 199*b97cf49bSBarry Smith Scalar *values; 200*b97cf49bSBarry Smith values = (Scalar *) PetscMalloc(a->nz*sizeof(Scalar));CHKPTRQ(values); 201*b97cf49bSBarry Smith PetscMemzero(values,a->nz*sizeof(Scalar)); 202*b97cf49bSBarry Smith ierr = ViewerMatlabPutSparse_Private(viewer,a->m,a->n,a->nz,values,a->i,a->j);CHKERRQ(ierr); 203*b97cf49bSBarry Smith PetscFree(values); 204*b97cf49bSBarry Smith } 205*b97cf49bSBarry Smith else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){ 206*b97cf49bSBarry Smith return MatView_SeqAdj_ASCII(A,viewer); 207*b97cf49bSBarry Smith } 208*b97cf49bSBarry Smith else if (vtype == BINARY_FILE_VIEWER) { 209*b97cf49bSBarry Smith return MatView_SeqAdj_Binary(A,viewer); 210*b97cf49bSBarry Smith } 211*b97cf49bSBarry Smith else if (vtype == DRAW_VIEWER) { 212*b97cf49bSBarry Smith return MatView_SeqAdj_Draw(A,viewer); 213*b97cf49bSBarry Smith } 214*b97cf49bSBarry Smith return 0; 215*b97cf49bSBarry Smith } 216*b97cf49bSBarry Smith 217*b97cf49bSBarry Smith 218*b97cf49bSBarry Smith #undef __FUNC__ 219*b97cf49bSBarry Smith #define __FUNC__ "MatDestroy_SeqAdj" 220*b97cf49bSBarry Smith int MatDestroy_SeqAdj(PetscObject obj) 221*b97cf49bSBarry Smith { 222*b97cf49bSBarry Smith Mat A = (Mat) obj; 223*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 224*b97cf49bSBarry Smith 225*b97cf49bSBarry Smith #if defined(PETSC_LOG) 226*b97cf49bSBarry Smith PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 227*b97cf49bSBarry Smith #endif 228*b97cf49bSBarry Smith if (a->diag) PetscFree(a->diag); 229*b97cf49bSBarry Smith PetscFree(a->i); 230*b97cf49bSBarry Smith PetscFree(a->j); 231*b97cf49bSBarry Smith PetscFree(a); 232*b97cf49bSBarry Smith 233*b97cf49bSBarry Smith PLogObjectDestroy(A); 234*b97cf49bSBarry Smith PetscHeaderDestroy(A); 235*b97cf49bSBarry Smith return 0; 236*b97cf49bSBarry Smith } 237*b97cf49bSBarry Smith 238*b97cf49bSBarry Smith 239*b97cf49bSBarry Smith #undef __FUNC__ 240*b97cf49bSBarry Smith #define __FUNC__ "MatSetOption_SeqAdj" 241*b97cf49bSBarry Smith int MatSetOption_SeqAdj(Mat A,MatOption op) 242*b97cf49bSBarry Smith { 243*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 244*b97cf49bSBarry Smith 245*b97cf49bSBarry Smith if (op == MAT_STRUCTURALLY_SYMMETRIC) { 246*b97cf49bSBarry Smith a->symmetric = PETSC_TRUE; 247*b97cf49bSBarry Smith } else { 248*b97cf49bSBarry Smith PLogInfo(A,"Info:MatSetOption_SeqAdj:Option ignored\n"); 249*b97cf49bSBarry Smith } 250*b97cf49bSBarry Smith return 0; 251*b97cf49bSBarry Smith } 252*b97cf49bSBarry Smith 253*b97cf49bSBarry Smith 254*b97cf49bSBarry Smith /* 255*b97cf49bSBarry Smith Adds diagonal pointers to sparse matrix structure. 256*b97cf49bSBarry Smith */ 257*b97cf49bSBarry Smith 258*b97cf49bSBarry Smith #undef __FUNC__ 259*b97cf49bSBarry Smith #define __FUNC__ "MatMarkDiag_SeqAdj" 260*b97cf49bSBarry Smith int MatMarkDiag_SeqAdj(Mat A) 261*b97cf49bSBarry Smith { 262*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 263*b97cf49bSBarry Smith int i,j, *diag, m = a->m; 264*b97cf49bSBarry Smith 265*b97cf49bSBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 266*b97cf49bSBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 267*b97cf49bSBarry Smith for ( i=0; i<a->m; i++ ) { 268*b97cf49bSBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 269*b97cf49bSBarry Smith if (a->j[j] == i) { 270*b97cf49bSBarry Smith diag[i] = j; 271*b97cf49bSBarry Smith break; 272*b97cf49bSBarry Smith } 273*b97cf49bSBarry Smith } 274*b97cf49bSBarry Smith } 275*b97cf49bSBarry Smith a->diag = diag; 276*b97cf49bSBarry Smith return 0; 277*b97cf49bSBarry Smith } 278*b97cf49bSBarry Smith 279*b97cf49bSBarry Smith 280*b97cf49bSBarry Smith #undef __FUNC__ 281*b97cf49bSBarry Smith #define __FUNC__ "MatGetInfo_SeqAdj" 282*b97cf49bSBarry Smith int MatGetInfo_SeqAdj(Mat A,MatInfoType flag,MatInfo *info) 283*b97cf49bSBarry Smith { 284*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 285*b97cf49bSBarry Smith 286*b97cf49bSBarry Smith info->rows_global = (double)a->m; 287*b97cf49bSBarry Smith info->columns_global = (double)a->n; 288*b97cf49bSBarry Smith info->rows_local = (double)a->m; 289*b97cf49bSBarry Smith info->columns_local = (double)a->n; 290*b97cf49bSBarry Smith info->block_size = 1.0; 291*b97cf49bSBarry Smith info->nz_allocated = (double)a->nz; 292*b97cf49bSBarry Smith info->nz_used = (double)a->nz; 293*b97cf49bSBarry Smith info->nz_unneeded = 0.0; 294*b97cf49bSBarry Smith /* if (info->nz_unneeded != A->info.nz_unneeded) 295*b97cf49bSBarry Smith printf("space descrepancy: maxnz-nz = %d, nz_unneeded = %d\n",(int)info->nz_unneeded,(int)A->info.nz_unneeded); */ 296*b97cf49bSBarry Smith info->assemblies = 0.0; 297*b97cf49bSBarry Smith info->mallocs = 0.0; 298*b97cf49bSBarry Smith info->memory = A->mem; 299*b97cf49bSBarry Smith if (A->factor) { 300*b97cf49bSBarry Smith info->fill_ratio_given = A->info.fill_ratio_given; 301*b97cf49bSBarry Smith info->fill_ratio_needed = A->info.fill_ratio_needed; 302*b97cf49bSBarry Smith info->factor_mallocs = A->info.factor_mallocs; 303*b97cf49bSBarry Smith } else { 304*b97cf49bSBarry Smith info->fill_ratio_given = 0; 305*b97cf49bSBarry Smith info->fill_ratio_needed = 0; 306*b97cf49bSBarry Smith info->factor_mallocs = 0; 307*b97cf49bSBarry Smith } 308*b97cf49bSBarry Smith return 0; 309*b97cf49bSBarry Smith } 310*b97cf49bSBarry Smith 311*b97cf49bSBarry Smith #undef __FUNC__ 312*b97cf49bSBarry Smith #define __FUNC__ "MatGetSize_SeqAdj" 313*b97cf49bSBarry Smith int MatGetSize_SeqAdj(Mat A,int *m,int *n) 314*b97cf49bSBarry Smith { 315*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 316*b97cf49bSBarry Smith *m = a->m; *n = a->n; 317*b97cf49bSBarry Smith return 0; 318*b97cf49bSBarry Smith } 319*b97cf49bSBarry Smith 320*b97cf49bSBarry Smith #undef __FUNC__ 321*b97cf49bSBarry Smith #define __FUNC__ "MatGetOwnershipRange_SeqAdj" 322*b97cf49bSBarry Smith int MatGetOwnershipRange_SeqAdj(Mat A,int *m,int *n) 323*b97cf49bSBarry Smith { 324*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 325*b97cf49bSBarry Smith *m = 0; *n = a->m; 326*b97cf49bSBarry Smith return 0; 327*b97cf49bSBarry Smith } 328*b97cf49bSBarry Smith 329*b97cf49bSBarry Smith #undef __FUNC__ 330*b97cf49bSBarry Smith #define __FUNC__ "MatGetRow_SeqAdj" 331*b97cf49bSBarry Smith int MatGetRow_SeqAdj(Mat A,int row,int *nz,int **idx,Scalar **v) 332*b97cf49bSBarry Smith { 333*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 334*b97cf49bSBarry Smith int *itmp; 335*b97cf49bSBarry Smith 336*b97cf49bSBarry Smith if (row < 0 || row >= a->m) SETERRQ(1,0,"Row out of range"); 337*b97cf49bSBarry Smith 338*b97cf49bSBarry Smith *nz = a->i[row+1] - a->i[row]; 339*b97cf49bSBarry Smith if (v) *v = PETSC_NULL; 340*b97cf49bSBarry Smith if (idx) { 341*b97cf49bSBarry Smith itmp = a->j + a->i[row]; 342*b97cf49bSBarry Smith if (*nz) { 343*b97cf49bSBarry Smith *idx = itmp; 344*b97cf49bSBarry Smith } 345*b97cf49bSBarry Smith else *idx = 0; 346*b97cf49bSBarry Smith } 347*b97cf49bSBarry Smith return 0; 348*b97cf49bSBarry Smith } 349*b97cf49bSBarry Smith 350*b97cf49bSBarry Smith #undef __FUNC__ 351*b97cf49bSBarry Smith #define __FUNC__ "MatRestoreRow_SeqAdj" 352*b97cf49bSBarry Smith int MatRestoreRow_SeqAdj(Mat A,int row,int *nz,int **idx,Scalar **v) 353*b97cf49bSBarry Smith { 354*b97cf49bSBarry Smith return 0; 355*b97cf49bSBarry Smith } 356*b97cf49bSBarry Smith 357*b97cf49bSBarry Smith #undef __FUNC__ 358*b97cf49bSBarry Smith #define __FUNC__ "MatGetBlockSize_SeqAdj" 359*b97cf49bSBarry Smith int MatGetBlockSize_SeqAdj(Mat A, int *bs) 360*b97cf49bSBarry Smith { 361*b97cf49bSBarry Smith *bs = 1; 362*b97cf49bSBarry Smith return 0; 363*b97cf49bSBarry Smith } 364*b97cf49bSBarry Smith 365*b97cf49bSBarry Smith #undef __FUNC__ 366*b97cf49bSBarry Smith #define __FUNC__ "MatIncreaseOverlap_SeqAdj" 367*b97cf49bSBarry Smith int MatIncreaseOverlap_SeqAdj(Mat A, int is_max, IS *is, int ov) 368*b97cf49bSBarry Smith { 369*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 370*b97cf49bSBarry Smith int row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val; 371*b97cf49bSBarry Smith int start, end, *ai, *aj; 372*b97cf49bSBarry Smith char *table; 373*b97cf49bSBarry Smith 374*b97cf49bSBarry Smith m = a->m; 375*b97cf49bSBarry Smith ai = a->i; 376*b97cf49bSBarry Smith aj = a->j; 377*b97cf49bSBarry Smith 378*b97cf49bSBarry Smith if (ov < 0) SETERRQ(1,0,"illegal overlap value used"); 379*b97cf49bSBarry Smith 380*b97cf49bSBarry Smith table = (char *) PetscMalloc((m/BITSPERBYTE +1)*sizeof(char)); CHKPTRQ(table); 381*b97cf49bSBarry Smith nidx = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(nidx); 382*b97cf49bSBarry Smith 383*b97cf49bSBarry Smith for ( i=0; i<is_max; i++ ) { 384*b97cf49bSBarry Smith /* Initialize the two local arrays */ 385*b97cf49bSBarry Smith isz = 0; 386*b97cf49bSBarry Smith PetscMemzero(table,(m/BITSPERBYTE +1)*sizeof(char)); 387*b97cf49bSBarry Smith 388*b97cf49bSBarry Smith /* Extract the indices, assume there can be duplicate entries */ 389*b97cf49bSBarry Smith ierr = ISGetIndices(is[i],&idx); CHKERRQ(ierr); 390*b97cf49bSBarry Smith ierr = ISGetSize(is[i],&n); CHKERRQ(ierr); 391*b97cf49bSBarry Smith 392*b97cf49bSBarry Smith /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 393*b97cf49bSBarry Smith for ( j=0; j<n ; ++j){ 394*b97cf49bSBarry Smith if(!BT_LOOKUP(table, idx[j])) { nidx[isz++] = idx[j];} 395*b97cf49bSBarry Smith } 396*b97cf49bSBarry Smith ierr = ISRestoreIndices(is[i],&idx); CHKERRQ(ierr); 397*b97cf49bSBarry Smith ierr = ISDestroy(is[i]); CHKERRQ(ierr); 398*b97cf49bSBarry Smith 399*b97cf49bSBarry Smith k = 0; 400*b97cf49bSBarry Smith for ( j=0; j<ov; j++){ /* for each overlap */ 401*b97cf49bSBarry Smith n = isz; 402*b97cf49bSBarry Smith for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 403*b97cf49bSBarry Smith row = nidx[k]; 404*b97cf49bSBarry Smith start = ai[row]; 405*b97cf49bSBarry Smith end = ai[row+1]; 406*b97cf49bSBarry Smith for ( l = start; l<end ; l++){ 407*b97cf49bSBarry Smith val = aj[l]; 408*b97cf49bSBarry Smith if (!BT_LOOKUP(table,val)) {nidx[isz++] = val;} 409*b97cf49bSBarry Smith } 410*b97cf49bSBarry Smith } 411*b97cf49bSBarry Smith } 412*b97cf49bSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF, isz, nidx, (is+i)); CHKERRQ(ierr); 413*b97cf49bSBarry Smith } 414*b97cf49bSBarry Smith PetscFree(table); 415*b97cf49bSBarry Smith PetscFree(nidx); 416*b97cf49bSBarry Smith return 0; 417*b97cf49bSBarry Smith } 418*b97cf49bSBarry Smith 419*b97cf49bSBarry Smith #undef __FUNC__ 420*b97cf49bSBarry Smith #define __FUNC__ "MatEqual_SeqAdj" 421*b97cf49bSBarry Smith int MatEqual_SeqAdj(Mat A,Mat B, PetscTruth* flg) 422*b97cf49bSBarry Smith { 423*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *)A->data, *b = (Mat_SeqAdj *)B->data; 424*b97cf49bSBarry Smith 425*b97cf49bSBarry Smith if (B->type != MATSEQADJ) SETERRQ(1,0,"Matrices must be same type"); 426*b97cf49bSBarry Smith 427*b97cf49bSBarry Smith /* If the matrix dimensions are not equal, or no of nonzeros */ 428*b97cf49bSBarry Smith if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)) { 429*b97cf49bSBarry Smith *flg = PETSC_FALSE; return 0; 430*b97cf49bSBarry Smith } 431*b97cf49bSBarry Smith 432*b97cf49bSBarry Smith /* if the a->i are the same */ 433*b97cf49bSBarry Smith if (PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int))) { 434*b97cf49bSBarry Smith *flg = PETSC_FALSE; return 0; 435*b97cf49bSBarry Smith } 436*b97cf49bSBarry Smith 437*b97cf49bSBarry Smith /* if a->j are the same */ 438*b97cf49bSBarry Smith if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) { 439*b97cf49bSBarry Smith *flg = PETSC_FALSE; return 0; 440*b97cf49bSBarry Smith } 441*b97cf49bSBarry Smith 442*b97cf49bSBarry Smith *flg = PETSC_TRUE; 443*b97cf49bSBarry Smith return 0; 444*b97cf49bSBarry Smith } 445*b97cf49bSBarry Smith 446*b97cf49bSBarry Smith #undef __FUNC__ 447*b97cf49bSBarry Smith #define __FUNC__ "MatPermute_SeqAdj" 448*b97cf49bSBarry Smith int MatPermute_SeqAdj(Mat A, IS rowp, IS colp, Mat *B) 449*b97cf49bSBarry Smith { 450*b97cf49bSBarry Smith Mat_SeqAdj *a = (Mat_SeqAdj *) A->data; 451*b97cf49bSBarry Smith Scalar *vwork; 452*b97cf49bSBarry Smith int i, ierr, nz = a->nz, m = a->m, n = a->n, *cwork,*ii,*jj; 453*b97cf49bSBarry Smith int *row,*col,j,*lens; 454*b97cf49bSBarry Smith IS icolp,irowp; 455*b97cf49bSBarry Smith 456*b97cf49bSBarry Smith ierr = ISInvertPermutation(rowp,&irowp); CHKERRQ(ierr); 457*b97cf49bSBarry Smith ierr = ISGetIndices(irowp,&row); CHKERRQ(ierr); 458*b97cf49bSBarry Smith ierr = ISInvertPermutation(colp,&icolp); CHKERRQ(ierr); 459*b97cf49bSBarry Smith ierr = ISGetIndices(icolp,&col); CHKERRQ(ierr); 460*b97cf49bSBarry Smith 461*b97cf49bSBarry Smith /* determine lengths of permuted rows */ 462*b97cf49bSBarry Smith lens = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(lens); 463*b97cf49bSBarry Smith for (i=0; i<m; i++ ) { 464*b97cf49bSBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 465*b97cf49bSBarry Smith } 466*b97cf49bSBarry Smith 467*b97cf49bSBarry Smith ii = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(ii); 468*b97cf49bSBarry Smith jj = (int *) PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(jj); 469*b97cf49bSBarry Smith ii[0] = 0; 470*b97cf49bSBarry Smith for (i=1; i<=m; i++ ) { 471*b97cf49bSBarry Smith ii[i] = ii[i-1] + lens[i-1]; 472*b97cf49bSBarry Smith } 473*b97cf49bSBarry Smith PetscFree(lens); 474*b97cf49bSBarry Smith 475*b97cf49bSBarry Smith for (i=0; i<m; i++) { 476*b97cf49bSBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 477*b97cf49bSBarry Smith for (j=0; j<nz; j++ ) { jj[j+ii[row[i]]] = col[cwork[j]];} 478*b97cf49bSBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 479*b97cf49bSBarry Smith } 480*b97cf49bSBarry Smith 481*b97cf49bSBarry Smith ierr = MatCreateSeqAdj(A->comm,m,n,ii,jj,B);CHKERRQ(ierr); 482*b97cf49bSBarry Smith 483*b97cf49bSBarry Smith ierr = ISRestoreIndices(irowp,&row); CHKERRQ(ierr); 484*b97cf49bSBarry Smith ierr = ISRestoreIndices(icolp,&col); CHKERRQ(ierr); 485*b97cf49bSBarry Smith ierr = ISDestroy(irowp); CHKERRQ(ierr); 486*b97cf49bSBarry Smith ierr = ISDestroy(icolp); CHKERRQ(ierr); 487*b97cf49bSBarry Smith return 0; 488*b97cf49bSBarry Smith } 489*b97cf49bSBarry Smith 490*b97cf49bSBarry Smith /* -------------------------------------------------------------------*/ 491*b97cf49bSBarry Smith static struct _MatOps MatOps = {0, 492*b97cf49bSBarry Smith MatGetRow_SeqAdj,MatRestoreRow_SeqAdj, 493*b97cf49bSBarry Smith 0,0, 494*b97cf49bSBarry Smith 0,0, 495*b97cf49bSBarry Smith 0,0, 496*b97cf49bSBarry Smith 0,0, 497*b97cf49bSBarry Smith 0,0, 498*b97cf49bSBarry Smith 0, 499*b97cf49bSBarry Smith 0, 500*b97cf49bSBarry Smith MatGetInfo_SeqAdj,MatEqual_SeqAdj, 501*b97cf49bSBarry Smith 0,0,0, 502*b97cf49bSBarry Smith 0,0, 503*b97cf49bSBarry Smith 0, 504*b97cf49bSBarry Smith MatSetOption_SeqAdj,0,0, 505*b97cf49bSBarry Smith 0,0,0,0, 506*b97cf49bSBarry Smith MatGetSize_SeqAdj,MatGetSize_SeqAdj,MatGetOwnershipRange_SeqAdj, 507*b97cf49bSBarry Smith 0,0, 508*b97cf49bSBarry Smith 0,0, 509*b97cf49bSBarry Smith 0,0,0, 510*b97cf49bSBarry Smith 0,0,0, 511*b97cf49bSBarry Smith 0,MatIncreaseOverlap_SeqAdj, 512*b97cf49bSBarry Smith 0,0, 513*b97cf49bSBarry Smith 0, 514*b97cf49bSBarry Smith 0,0,0, 515*b97cf49bSBarry Smith 0, 516*b97cf49bSBarry Smith MatGetBlockSize_SeqAdj, 517*b97cf49bSBarry Smith MatGetRowIJ_SeqAdj, 518*b97cf49bSBarry Smith MatRestoreRowIJ_SeqAdj, 519*b97cf49bSBarry Smith 0, 520*b97cf49bSBarry Smith 0, 521*b97cf49bSBarry Smith 0, 522*b97cf49bSBarry Smith 0, 523*b97cf49bSBarry Smith 0, 524*b97cf49bSBarry Smith MatPermute_SeqAdj}; 525*b97cf49bSBarry Smith 526*b97cf49bSBarry Smith 527*b97cf49bSBarry Smith #undef __FUNC__ 528*b97cf49bSBarry Smith #define __FUNC__ "MatCreateSeqAdj" 529*b97cf49bSBarry Smith /*@C 530*b97cf49bSBarry Smith MatCreateSeqAdj - Creates a sparse matrix representing an adjacency list. 531*b97cf49bSBarry Smith The matrix does not have numerical values associated with it, but is 532*b97cf49bSBarry Smith intended for ordering (to reduce bandwidth etc) and partitioning. 533*b97cf49bSBarry Smith 534*b97cf49bSBarry Smith Input Parameters: 535*b97cf49bSBarry Smith . comm - MPI communicator, set to PETSC_COMM_SELF 536*b97cf49bSBarry Smith . m - number of rows 537*b97cf49bSBarry Smith . n - number of columns 538*b97cf49bSBarry Smith . i - the indices into j for the start of each row 539*b97cf49bSBarry Smith . j - the column indices for each row (sorted for each row) 540*b97cf49bSBarry Smith The indices in i and j start with zero NOT one. 541*b97cf49bSBarry Smith 542*b97cf49bSBarry Smith Output Parameter: 543*b97cf49bSBarry Smith . A - the matrix 544*b97cf49bSBarry Smith 545*b97cf49bSBarry Smith Notes: You must free the ii and jj arrays yourself. PETSc will free them 546*b97cf49bSBarry Smith when the matrix is destroyed. 547*b97cf49bSBarry Smith 548*b97cf49bSBarry Smith . MatSetOptions() possible values - MAT_STRUCTURALLY_SYMMETRIC 549*b97cf49bSBarry Smith 550*b97cf49bSBarry Smith .seealso: MatCreate(), MatCreateMPIADJ(), MatGetReordering() 551*b97cf49bSBarry Smith @*/ 552*b97cf49bSBarry Smith int MatCreateSeqAdj(MPI_Comm comm,int m,int n,int *i,int *j, Mat *A) 553*b97cf49bSBarry Smith { 554*b97cf49bSBarry Smith Mat B; 555*b97cf49bSBarry Smith Mat_SeqAdj *b; 556*b97cf49bSBarry Smith int ierr, flg,size; 557*b97cf49bSBarry Smith 558*b97cf49bSBarry Smith MPI_Comm_size(comm,&size); 559*b97cf49bSBarry Smith if (size > 1) SETERRQ(1,0,"Comm must be of size 1"); 560*b97cf49bSBarry Smith 561*b97cf49bSBarry Smith *A = 0; 562*b97cf49bSBarry Smith PetscHeaderCreate(B,_p_Mat,MAT_COOKIE,MATSEQADJ,comm,MatDestroy,MatView); 563*b97cf49bSBarry Smith PLogObjectCreate(B); 564*b97cf49bSBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqAdj)); CHKPTRQ(b); 565*b97cf49bSBarry Smith PetscMemzero(b,sizeof(Mat_SeqAdj)); 566*b97cf49bSBarry Smith PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps)); 567*b97cf49bSBarry Smith B->destroy = MatDestroy_SeqAdj; 568*b97cf49bSBarry Smith B->view = MatView_SeqAdj; 569*b97cf49bSBarry Smith B->factor = 0; 570*b97cf49bSBarry Smith B->lupivotthreshold = 1.0; 571*b97cf49bSBarry Smith B->mapping = 0; 572*b97cf49bSBarry Smith B->assembled = PETSC_FALSE; 573*b97cf49bSBarry Smith 574*b97cf49bSBarry Smith b->m = m; B->m = m; B->M = m; 575*b97cf49bSBarry Smith b->n = n; B->n = n; B->N = n; 576*b97cf49bSBarry Smith 577*b97cf49bSBarry Smith b->j = j; 578*b97cf49bSBarry Smith b->i = i; 579*b97cf49bSBarry Smith 580*b97cf49bSBarry Smith b->nz = i[m]; 581*b97cf49bSBarry Smith b->diag = 0; 582*b97cf49bSBarry Smith b->symmetric = PETSC_FALSE; 583*b97cf49bSBarry Smith 584*b97cf49bSBarry Smith *A = B; 585*b97cf49bSBarry Smith 586*b97cf49bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 587*b97cf49bSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 588*b97cf49bSBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 589*b97cf49bSBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 590*b97cf49bSBarry Smith return 0; 591*b97cf49bSBarry Smith } 592*b97cf49bSBarry Smith 593*b97cf49bSBarry Smith #undef __FUNC__ 594*b97cf49bSBarry Smith #define __FUNC__ "MatLoad_SeqAdj" 595*b97cf49bSBarry Smith int MatLoad_SeqAdj(Viewer viewer,MatType type,Mat *A) 596*b97cf49bSBarry Smith { 597*b97cf49bSBarry Smith int i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,*ii,*jj; 598*b97cf49bSBarry Smith MPI_Comm comm; 599*b97cf49bSBarry Smith 600*b97cf49bSBarry Smith PetscObjectGetComm((PetscObject) viewer,&comm); 601*b97cf49bSBarry Smith MPI_Comm_size(comm,&size); 602*b97cf49bSBarry Smith if (size > 1) SETERRQ(1,0,"view must have one processor"); 603*b97cf49bSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 604*b97cf49bSBarry Smith ierr = PetscBinaryRead(fd,header,4,BINARY_INT); CHKERRQ(ierr); 605*b97cf49bSBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(1,0,"not matrix object in file"); 606*b97cf49bSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 607*b97cf49bSBarry Smith 608*b97cf49bSBarry Smith /* read in row lengths */ 609*b97cf49bSBarry Smith rowlengths = (int*) PetscMalloc( M*sizeof(int) ); CHKPTRQ(rowlengths); 610*b97cf49bSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,BINARY_INT); CHKERRQ(ierr); 611*b97cf49bSBarry Smith 612*b97cf49bSBarry Smith /* create our matrix */ 613*b97cf49bSBarry Smith ii = (int *) PetscMalloc( (M+1)*sizeof(int) );CHKPTRQ(ii); 614*b97cf49bSBarry Smith jj = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(jj); 615*b97cf49bSBarry Smith 616*b97cf49bSBarry Smith /* read in column indices and adjust for Fortran indexing*/ 617*b97cf49bSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,BINARY_INT); CHKERRQ(ierr); 618*b97cf49bSBarry Smith 619*b97cf49bSBarry Smith /* set matrix "i" values */ 620*b97cf49bSBarry Smith ii[0] = 0; 621*b97cf49bSBarry Smith for ( i=1; i<= M; i++ ) { 622*b97cf49bSBarry Smith ii[i] = ii[i-1] + rowlengths[i-1]; 623*b97cf49bSBarry Smith } 624*b97cf49bSBarry Smith PetscFree(rowlengths); 625*b97cf49bSBarry Smith 626*b97cf49bSBarry Smith ierr = MatCreateSeqAdj(comm,M,N,ii,jj,A); CHKERRQ(ierr); 627*b97cf49bSBarry Smith return 0; 628*b97cf49bSBarry Smith } 629*b97cf49bSBarry Smith 630*b97cf49bSBarry Smith 631