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