1*b6490206SBarry Smith 22593348eSBarry Smith #ifndef lint 3*b6490206SBarry Smith static char vcid[] = "$Id: baij.c,v 1.1 1996/02/09 21:28:31 bsmith Exp bsmith $"; 42593348eSBarry Smith #endif 52593348eSBarry Smith 62593348eSBarry Smith /* 7*b6490206SBarry Smith Defines the basic matrix operations for the BAIJ (compressed row) 82593348eSBarry Smith matrix storage format. 92593348eSBarry Smith */ 10*b6490206SBarry Smith #include "baij.h" 112593348eSBarry Smith #include "vec/vecimpl.h" 122593348eSBarry Smith #include "inline/spops.h" 132593348eSBarry Smith #include "petsc.h" 142593348eSBarry Smith 15*b6490206SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int**,int**); 162593348eSBarry Smith 17*b6490206SBarry Smith static int MatGetReordering_SeqBAIJ(Mat A,MatOrdering type,IS *rperm,IS *cperm) 182593348eSBarry Smith { 19*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 202593348eSBarry Smith int ierr, *ia, *ja,n,*idx,i; 212593348eSBarry Smith 222593348eSBarry Smith /* 232593348eSBarry Smith this is tacky: In the future when we have written special factorization 242593348eSBarry Smith and solve routines for the identity permutation we should use a 252593348eSBarry Smith stride index set instead of the general one. 262593348eSBarry Smith */ 272593348eSBarry Smith if (type == ORDER_NATURAL) { 282593348eSBarry Smith n = a->n; 292593348eSBarry Smith idx = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(idx); 302593348eSBarry Smith for ( i=0; i<n; i++ ) idx[i] = i; 312593348eSBarry Smith ierr = ISCreateSeq(MPI_COMM_SELF,n,idx,rperm); CHKERRQ(ierr); 322593348eSBarry Smith ierr = ISCreateSeq(MPI_COMM_SELF,n,idx,cperm); CHKERRQ(ierr); 332593348eSBarry Smith PetscFree(idx); 342593348eSBarry Smith ISSetPermutation(*rperm); 352593348eSBarry Smith ISSetPermutation(*cperm); 362593348eSBarry Smith ISSetIdentity(*rperm); 372593348eSBarry Smith ISSetIdentity(*cperm); 382593348eSBarry Smith return 0; 392593348eSBarry Smith } 402593348eSBarry Smith 41*b6490206SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(a->n,a->i,a->j,a->indexshift,&ia,&ja);CHKERRQ(ierr); 422593348eSBarry Smith ierr = MatGetReordering_IJ(a->n,ia,ja,type,rperm,cperm); CHKERRQ(ierr); 432593348eSBarry Smith 442593348eSBarry Smith PetscFree(ia); PetscFree(ja); 452593348eSBarry Smith return 0; 462593348eSBarry Smith } 472593348eSBarry Smith 482593348eSBarry Smith 492593348eSBarry Smith #include "draw.h" 502593348eSBarry Smith #include "pinclude/pviewer.h" 512593348eSBarry Smith #include "sysio.h" 522593348eSBarry Smith 53*b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer) 542593348eSBarry Smith { 55*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 56*b6490206SBarry Smith int i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l; 57*b6490206SBarry Smith Scalar *aa; 582593348eSBarry Smith 592593348eSBarry Smith ierr = ViewerFileGetDescriptor_Private(viewer,&fd); CHKERRQ(ierr); 602593348eSBarry Smith col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) ); CHKPTRQ(col_lens); 612593348eSBarry Smith col_lens[0] = MAT_COOKIE; 622593348eSBarry Smith col_lens[1] = a->m; 632593348eSBarry Smith col_lens[2] = a->n; 64*b6490206SBarry Smith col_lens[3] = a->nz*bs*bs; 652593348eSBarry Smith 662593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 67*b6490206SBarry Smith count = 0; 68*b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 69*b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 70*b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 71*b6490206SBarry Smith } 722593348eSBarry Smith } 732593348eSBarry Smith ierr = SYWrite(fd,col_lens,4+a->m,SYINT,1); CHKERRQ(ierr); 742593348eSBarry Smith PetscFree(col_lens); 752593348eSBarry Smith 762593348eSBarry Smith /* store column indices (zero start index) */ 77*b6490206SBarry Smith jj = (int *) PetscMalloc( a->nz*bs*bs*sizeof(int) ); CHKPTRQ(jj); 78*b6490206SBarry Smith count = 0; 79*b6490206SBarry Smith if (!a->indexshift) { 80*b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 81*b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 82*b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 83*b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 84*b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 85*b6490206SBarry Smith /* printf(" count %d jj %d row %d\n",count-1,jj[count-1],bs*i+j);*/ 862593348eSBarry Smith } 872593348eSBarry Smith } 88*b6490206SBarry Smith } 89*b6490206SBarry Smith } 90*b6490206SBarry Smith } else { 91*b6490206SBarry Smith SETERRQ(1,"Not yet done"); 92*b6490206SBarry Smith } 93*b6490206SBarry Smith ierr = SYWrite(fd,jj,bs*bs*a->nz,SYINT,0); CHKERRQ(ierr); 94*b6490206SBarry Smith PetscFree(jj); 952593348eSBarry Smith 962593348eSBarry Smith /* store nonzero values */ 97*b6490206SBarry Smith aa = (Scalar *) PetscMalloc(a->nz*bs*bs*sizeof(Scalar)); CHKPTRQ(aa); 98*b6490206SBarry Smith count = 0; 99*b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 100*b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 101*b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 102*b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 103*b6490206SBarry Smith aa[count++] = a->a[bs*bs*k + l*bs + j]; 104*b6490206SBarry Smith } 105*b6490206SBarry Smith } 106*b6490206SBarry Smith } 107*b6490206SBarry Smith } 108*b6490206SBarry Smith ierr = SYWrite(fd,aa,bs*bs*a->nz,SYSCALAR,0); CHKERRQ(ierr); 109*b6490206SBarry Smith PetscFree(aa); 1102593348eSBarry Smith return 0; 1112593348eSBarry Smith } 1122593348eSBarry Smith 113*b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer) 1142593348eSBarry Smith { 115*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 116*b6490206SBarry Smith int ierr, i,j, shift = a->indexshift,format,bs = a->bs,k,l; 1172593348eSBarry Smith FILE *fd; 1182593348eSBarry Smith char *outputname; 1192593348eSBarry Smith 1202593348eSBarry Smith ierr = ViewerFileGetPointer(viewer,&fd); CHKERRQ(ierr); 1212593348eSBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname); CHKERRQ(ierr); 1222593348eSBarry Smith ierr = ViewerFileGetFormat_Private(viewer,&format); 1232593348eSBarry Smith if (format == FILE_FORMAT_INFO) { 1242593348eSBarry Smith /* no need to print additional information */ ; 1252593348eSBarry Smith } 1262593348eSBarry Smith else if (format == FILE_FORMAT_MATLAB) { 127*b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ_ASCII:Matlab format not supported"); 1282593348eSBarry Smith } 1292593348eSBarry Smith else { 130*b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 131*b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 132*b6490206SBarry Smith fprintf(fd,"row %d:",i*bs+j); 133*b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 134*b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 135*b6490206SBarry Smith fprintf(fd," %d %g",bs*a->j[k]+l-shift,a->a[bs*bs*k + l*bs + j]); 1362593348eSBarry Smith } 1372593348eSBarry Smith } 1382593348eSBarry Smith fprintf(fd,"\n"); 1392593348eSBarry Smith } 1402593348eSBarry Smith } 141*b6490206SBarry Smith } 1422593348eSBarry Smith fflush(fd); 1432593348eSBarry Smith return 0; 1442593348eSBarry Smith } 1452593348eSBarry Smith 146*b6490206SBarry Smith static int MatView_SeqBAIJ(PetscObject obj,Viewer viewer) 1472593348eSBarry Smith { 1482593348eSBarry Smith Mat A = (Mat) obj; 1492593348eSBarry Smith PetscObject vobj = (PetscObject) viewer; 1502593348eSBarry Smith 1512593348eSBarry Smith if (!viewer) { 1522593348eSBarry Smith viewer = STDOUT_VIEWER_SELF; vobj = (PetscObject) viewer; 1532593348eSBarry Smith } 1542593348eSBarry Smith if (vobj->cookie == VIEWER_COOKIE) { 1552593348eSBarry Smith if (vobj->type == MATLAB_VIEWER) { 156*b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ:Matlab viewer not supported"); 1572593348eSBarry Smith } 1582593348eSBarry Smith else if (vobj->type == ASCII_FILE_VIEWER||vobj->type == ASCII_FILES_VIEWER){ 159*b6490206SBarry Smith return MatView_SeqBAIJ_ASCII(A,viewer); 1602593348eSBarry Smith } 1612593348eSBarry Smith else if (vobj->type == BINARY_FILE_VIEWER) { 162*b6490206SBarry Smith return MatView_SeqBAIJ_Binary(A,viewer); 1632593348eSBarry Smith } 1642593348eSBarry Smith } 1652593348eSBarry Smith else if (vobj->cookie == DRAW_COOKIE) { 1662593348eSBarry Smith if (vobj->type == NULLWINDOW) return 0; 167*b6490206SBarry Smith SETERRQ(1,"MatView_SeqBAIJ:Draw viewer not supported"); 1682593348eSBarry Smith } 1692593348eSBarry Smith return 0; 1702593348eSBarry Smith } 171*b6490206SBarry Smith 172*b6490206SBarry Smith 173*b6490206SBarry Smith static int MatZeroEntries_SeqBAIJ(Mat A) 1742593348eSBarry Smith { 175*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 176*b6490206SBarry Smith PetscMemzero(a->a,a->bs*a->bs*(a->i[a->mbs]+a->indexshift)*sizeof(Scalar)); 1772593348eSBarry Smith return 0; 1782593348eSBarry Smith } 1792593348eSBarry Smith 180*b6490206SBarry Smith int MatDestroy_SeqBAIJ(PetscObject obj) 1812593348eSBarry Smith { 1822593348eSBarry Smith Mat A = (Mat) obj; 183*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1842593348eSBarry Smith 1852593348eSBarry Smith #if defined(PETSC_LOG) 1862593348eSBarry Smith PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 1872593348eSBarry Smith #endif 1882593348eSBarry Smith PetscFree(a->a); 1892593348eSBarry Smith if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 1902593348eSBarry Smith if (a->diag) PetscFree(a->diag); 1912593348eSBarry Smith if (a->ilen) PetscFree(a->ilen); 1922593348eSBarry Smith if (a->imax) PetscFree(a->imax); 1932593348eSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 1942593348eSBarry Smith PetscFree(a); 1952593348eSBarry Smith PLogObjectDestroy(A); 1962593348eSBarry Smith PetscHeaderDestroy(A); 1972593348eSBarry Smith return 0; 1982593348eSBarry Smith } 1992593348eSBarry Smith 200*b6490206SBarry Smith static int MatSetOption_SeqBAIJ(Mat A,MatOption op) 2012593348eSBarry Smith { 202*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 2032593348eSBarry Smith if (op == ROW_ORIENTED) a->roworiented = 1; 2042593348eSBarry Smith else if (op == COLUMN_ORIENTED) a->roworiented = 0; 2052593348eSBarry Smith else if (op == COLUMNS_SORTED) a->sorted = 1; 2062593348eSBarry Smith else if (op == NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 2072593348eSBarry Smith else if (op == YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 2082593348eSBarry Smith else if (op == ROWS_SORTED || 2092593348eSBarry Smith op == SYMMETRIC_MATRIX || 2102593348eSBarry Smith op == STRUCTURALLY_SYMMETRIC_MATRIX || 2112593348eSBarry Smith op == YES_NEW_DIAGONALS) 212*b6490206SBarry Smith PLogInfo((PetscObject)A,"Info:MatSetOption_SeqBAIJ:Option ignored\n"); 2132593348eSBarry Smith else if (op == NO_NEW_DIAGONALS) 214*b6490206SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqBAIJ:NO_NEW_DIAGONALS");} 2152593348eSBarry Smith else 216*b6490206SBarry Smith {SETERRQ(PETSC_ERR_SUP,"MatSetOption_SeqBAIJ:unknown option");} 2172593348eSBarry Smith return 0; 2182593348eSBarry Smith } 2192593348eSBarry Smith 2202593348eSBarry Smith 2212593348eSBarry Smith /* -------------------------------------------------------*/ 2222593348eSBarry Smith /* Should check that shapes of vectors and matrices match */ 2232593348eSBarry Smith /* -------------------------------------------------------*/ 224*b6490206SBarry Smith #include "pinclude/plapack.h" 225*b6490206SBarry Smith 226*b6490206SBarry Smith static int MatMult_SeqBAIJ(Mat A,Vec xx,Vec yy) 2272593348eSBarry Smith { 228*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 229*b6490206SBarry Smith Scalar *xg,*yg; 230*b6490206SBarry Smith register Scalar *x, *y, *v, sum,*xb, sum1,sum2,sum3,sum4,sum5; 231*b6490206SBarry Smith register Scalar x1,x2,x3,x4,x5; 232*b6490206SBarry Smith int mbs = a->mbs, m = a->m, i, *idx,*ii; 233*b6490206SBarry Smith int bs = a->bs,j,n,bs2 = bs*bs; 2342593348eSBarry Smith 235*b6490206SBarry Smith if (a->indexshift) SETERRQ(PETSC_ERR_SUP,"MatMult_SeqBAIJ:index shift no"); 2362593348eSBarry Smith 237*b6490206SBarry Smith VecGetArray(xx,&xg); x = xg; VecGetArray(yy,&yg); y = yg; 238*b6490206SBarry Smith PetscMemzero(y,m*sizeof(Scalar)); 239*b6490206SBarry Smith x = x; 2402593348eSBarry Smith idx = a->j; 2412593348eSBarry Smith v = a->a; 2422593348eSBarry Smith ii = a->i; 243*b6490206SBarry Smith 244*b6490206SBarry Smith switch (bs) { 245*b6490206SBarry Smith case 1: 2462593348eSBarry Smith for ( i=0; i<m; i++ ) { 2472593348eSBarry Smith n = ii[1] - ii[0]; ii++; 2482593348eSBarry Smith sum = 0.0; 2492593348eSBarry Smith while (n--) sum += *v++ * x[*idx++]; 2502593348eSBarry Smith y[i] = sum; 2512593348eSBarry Smith } 2522593348eSBarry Smith break; 253*b6490206SBarry Smith case 2: 254*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 255*b6490206SBarry Smith n = ii[1] - ii[0]; ii++; /* number of blocks in row */ 256*b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; 257*b6490206SBarry Smith for ( j=0; j<n; j++ ) { 258*b6490206SBarry Smith xb = x + 2*(*idx++); x1 = xb[0]; x2 = xb[1]; 259*b6490206SBarry Smith sum1 += v[0]*x1 + v[2]*x2; 260*b6490206SBarry Smith sum2 += v[1]*x1 + v[3]*x2; 261*b6490206SBarry Smith v += 4; 262*b6490206SBarry Smith } 263*b6490206SBarry Smith y[0] += sum1; y[1] += sum2; 264*b6490206SBarry Smith y += 2; 265*b6490206SBarry Smith } 266*b6490206SBarry Smith break; 267*b6490206SBarry Smith case 3: 268*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 269*b6490206SBarry Smith n = ii[1] - ii[0]; ii++; /* number of blocks in row */ 270*b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; 271*b6490206SBarry Smith for ( j=0; j<n; j++ ) { 272*b6490206SBarry Smith xb = x + 3*(*idx++); x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; 273*b6490206SBarry Smith sum1 += v[0]*x1 + v[3]*x2 + v[6]*x3; 274*b6490206SBarry Smith sum2 += v[1]*x1 + v[4]*x2 + v[7]*x3; 275*b6490206SBarry Smith sum3 += v[2]*x1 + v[5]*x2 + v[8]*x3; 276*b6490206SBarry Smith v += 9; 277*b6490206SBarry Smith } 278*b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; 279*b6490206SBarry Smith y += 3; 280*b6490206SBarry Smith } 281*b6490206SBarry Smith break; 282*b6490206SBarry Smith case 4: 283*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 284*b6490206SBarry Smith n = ii[1] - ii[0]; ii++; /* number of blocks in row */ 285*b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; 286*b6490206SBarry Smith for ( j=0; j<n; j++ ) { 287*b6490206SBarry Smith xb = x + 4*(*idx++); 288*b6490206SBarry Smith x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; x4 = xb[3]; 289*b6490206SBarry Smith sum1 += v[0]*x1 + v[4]*x2 + v[8]*x3 + v[12]*x4; 290*b6490206SBarry Smith sum2 += v[1]*x1 + v[5]*x2 + v[9]*x3 + v[13]*x4; 291*b6490206SBarry Smith sum3 += v[2]*x1 + v[6]*x2 + v[10]*x3 + v[14]*x4; 292*b6490206SBarry Smith sum4 += v[3]*x1 + v[7]*x2 + v[11]*x3 + v[15]*x4; 293*b6490206SBarry Smith v += 16; 294*b6490206SBarry Smith } 295*b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; y[3] += sum4; 296*b6490206SBarry Smith y += 4; 297*b6490206SBarry Smith } 298*b6490206SBarry Smith break; 299*b6490206SBarry Smith case 5: 300*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 301*b6490206SBarry Smith n = ii[1] - ii[0]; ii++; /* number of blocks in row */ 302*b6490206SBarry Smith sum1 = 0.0; sum2 = 0.0; sum3 = 0.0; sum4 = 0.0; sum5 = 0.0; 303*b6490206SBarry Smith for ( j=0; j<n; j++ ) { 304*b6490206SBarry Smith xb = x + 5*(*idx++); 305*b6490206SBarry Smith x1 = xb[0]; x2 = xb[1]; x3 = xb[2]; x4 = xb[3]; x5 = xb[4]; 306*b6490206SBarry Smith sum1 += v[0]*x1 + v[5]*x2 + v[10]*x3 + v[15]*x4 + v[20]*x5; 307*b6490206SBarry Smith sum2 += v[1]*x1 + v[6]*x2 + v[11]*x3 + v[16]*x4 + v[21]*x5; 308*b6490206SBarry Smith sum3 += v[2]*x1 + v[7]*x2 + v[12]*x3 + v[17]*x4 + v[22]*x5; 309*b6490206SBarry Smith sum4 += v[3]*x1 + v[8]*x2 + v[13]*x3 + v[18]*x4 + v[23]*x5; 310*b6490206SBarry Smith sum5 += v[4]*x1 + v[9]*x2 + v[14]*x3 + v[19]*x4 + v[24]*x5; 311*b6490206SBarry Smith v += 25; 312*b6490206SBarry Smith } 313*b6490206SBarry Smith y[0] += sum1; y[1] += sum2; y[2] += sum3; y[3] += sum4; y[4] += sum5; 314*b6490206SBarry Smith y += 5; 315*b6490206SBarry Smith } 316*b6490206SBarry Smith break; 317*b6490206SBarry Smith /* block sizes larger then 5 by 5 are handled by BLAS */ 318*b6490206SBarry Smith default: { 319*b6490206SBarry Smith int _One = 1; Scalar _DOne = 1.0; 320*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 321*b6490206SBarry Smith n = ii[1] - ii[0]; ii++; /* number of blocks in row */ 322*b6490206SBarry Smith for ( j=0; j<n; j++ ) { 323*b6490206SBarry Smith xb = x + bs*(*idx++); 324*b6490206SBarry Smith /* do dense mat-vec product */ 325*b6490206SBarry Smith LAgemv_("N",&bs,&bs,&_DOne,v,&bs,xb,&_One,&_DOne,y,&_One); 326*b6490206SBarry Smith v += bs2; 327*b6490206SBarry Smith } 328*b6490206SBarry Smith y += bs; 3292593348eSBarry Smith } 3302593348eSBarry Smith } 3312593348eSBarry Smith } 332*b6490206SBarry Smith PLogFlops(2*bs2*a->nz - m); 3332593348eSBarry Smith return 0; 3342593348eSBarry Smith } 3352593348eSBarry Smith 336*b6490206SBarry Smith static int MatGetInfo_SeqBAIJ(Mat A,MatInfoType flag,int *nz,int *nzalloc,int *mem) 3372593348eSBarry Smith { 338*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3392593348eSBarry Smith *nz = a->nz; 3402593348eSBarry Smith *nzalloc = a->maxnz; 3412593348eSBarry Smith *mem = (int)A->mem; 3422593348eSBarry Smith return 0; 3432593348eSBarry Smith } 3442593348eSBarry Smith 345*b6490206SBarry Smith extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 346*b6490206SBarry Smith extern int MatLUFactorNumeric_SeqBAIJ(Mat,Mat*); 347*b6490206SBarry Smith extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 348*b6490206SBarry Smith extern int MatSolve_SeqBAIJ(Mat,Vec,Vec); 3492593348eSBarry Smith 350*b6490206SBarry Smith static int MatGetSize_SeqBAIJ(Mat A,int *m,int *n) 3512593348eSBarry Smith { 352*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3532593348eSBarry Smith *m = a->m; *n = a->n; 3542593348eSBarry Smith return 0; 3552593348eSBarry Smith } 3562593348eSBarry Smith 357*b6490206SBarry Smith static int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 3582593348eSBarry Smith { 359*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3602593348eSBarry Smith *m = 0; *n = a->m; 3612593348eSBarry Smith return 0; 3622593348eSBarry Smith } 363*b6490206SBarry Smith 364*b6490206SBarry Smith static int MatNorm_SeqBAIJ(Mat A,NormType type,double *norm) 3652593348eSBarry Smith { 366*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3672593348eSBarry Smith Scalar *v = a->a; 3682593348eSBarry Smith double sum = 0.0; 369*b6490206SBarry Smith int i; 3702593348eSBarry Smith 3712593348eSBarry Smith if (type == NORM_FROBENIUS) { 3722593348eSBarry Smith for (i=0; i<a->nz; i++ ) { 3732593348eSBarry Smith #if defined(PETSC_COMPLEX) 3742593348eSBarry Smith sum += real(conj(*v)*(*v)); v++; 3752593348eSBarry Smith #else 3762593348eSBarry Smith sum += (*v)*(*v); v++; 3772593348eSBarry Smith #endif 3782593348eSBarry Smith } 3792593348eSBarry Smith *norm = sqrt(sum); 3802593348eSBarry Smith } 3812593348eSBarry Smith else { 382*b6490206SBarry Smith SETERRQ(1,"MatNorm_SeqBAIJ:No support for this norm yet"); 3832593348eSBarry Smith } 3842593348eSBarry Smith return 0; 3852593348eSBarry Smith } 3862593348eSBarry Smith 3872593348eSBarry Smith 3882593348eSBarry Smith /* 3892593348eSBarry Smith note: This can only work for identity for row and col. It would 3902593348eSBarry Smith be good to check this and otherwise generate an error. 3912593348eSBarry Smith */ 392*b6490206SBarry Smith static int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill) 3932593348eSBarry Smith { 394*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 3952593348eSBarry Smith int ierr; 3962593348eSBarry Smith Mat outA; 3972593348eSBarry Smith 398*b6490206SBarry Smith if (fill != 0) SETERRQ(1,"MatILUFactor_SeqBAIJ:Only fill=0 supported"); 3992593348eSBarry Smith 4002593348eSBarry Smith outA = inA; 4012593348eSBarry Smith inA->factor = FACTOR_LU; 4022593348eSBarry Smith a->row = row; 4032593348eSBarry Smith a->col = col; 4042593348eSBarry Smith 4052593348eSBarry Smith a->solve_work = (Scalar *) PetscMalloc((a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work); 4062593348eSBarry Smith 407*b6490206SBarry Smith /* 4082593348eSBarry Smith if (!a->diag) { 409*b6490206SBarry Smith ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 4102593348eSBarry Smith } 411*b6490206SBarry Smith ierr = MatLUFactorNumeric_SeqBAIJ(inA,&outA); CHKERRQ(ierr); 412*b6490206SBarry Smith */ 4132593348eSBarry Smith return 0; 4142593348eSBarry Smith } 4152593348eSBarry Smith 4162593348eSBarry Smith #include "pinclude/plapack.h" 417*b6490206SBarry Smith static int MatScale_SeqBAIJ(Scalar *alpha,Mat inA) 4182593348eSBarry Smith { 419*b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 420*b6490206SBarry Smith int one = 1, totalnz = a->bs*a->bs*a->nz; 421*b6490206SBarry Smith BLscal_( &totalnz, alpha, a->a, &one ); 422*b6490206SBarry Smith PLogFlops(totalnz); 4232593348eSBarry Smith return 0; 4242593348eSBarry Smith } 4252593348eSBarry Smith 426*b6490206SBarry Smith int MatPrintHelp_SeqBAIJ(Mat A) 4272593348eSBarry Smith { 4282593348eSBarry Smith static int called = 0; 4292593348eSBarry Smith MPI_Comm comm = A->comm; 4302593348eSBarry Smith 4312593348eSBarry Smith if (called) return 0; else called = 1; 432*b6490206SBarry Smith MPIU_printf(comm," Options for MATSeqBAIJ and MATMPIAIJ matrix formats (the defaults):\n"); 4332593348eSBarry Smith MPIU_printf(comm," -mat_lu_pivotthreshold <threshold>\n"); 4342593348eSBarry Smith MPIU_printf(comm," -mat_aij_oneindex - internal indices begin at 1 instead of the default 0.\n"); 4352593348eSBarry Smith return 0; 4362593348eSBarry Smith } 4372593348eSBarry Smith /* -------------------------------------------------------------------*/ 438*b6490206SBarry Smith static struct _MatOps MatOps = {0, 439*b6490206SBarry Smith 0,0, 440*b6490206SBarry Smith MatMult_SeqBAIJ,0, 441*b6490206SBarry Smith 0,0, 442*b6490206SBarry Smith /*MatSolve_SeqBAIJ*/ 0,0, 443*b6490206SBarry Smith 0,0, 444*b6490206SBarry Smith /*MatLUFactor_SeqBAIJ*/0,0, 445*b6490206SBarry Smith 0, 446*b6490206SBarry Smith 0, 447*b6490206SBarry Smith MatGetInfo_SeqBAIJ,0, 448*b6490206SBarry Smith 0,0,MatNorm_SeqBAIJ, 449*b6490206SBarry Smith 0,0, 450*b6490206SBarry Smith 0, 451*b6490206SBarry Smith MatSetOption_SeqBAIJ,MatZeroEntries_SeqBAIJ,0, 452*b6490206SBarry Smith MatGetReordering_SeqBAIJ, 453*b6490206SBarry Smith /*MatLUFactorSymbolic_SeqBAIJ */0,/* MatLUFactorNumeric_SeqBAIJ*/ 0,0,0, 454*b6490206SBarry Smith MatGetSize_SeqBAIJ,MatGetSize_SeqBAIJ,MatGetOwnershipRange_SeqBAIJ, 455*b6490206SBarry Smith /* MatILUFactorSymbolic_SeqBAIJ */ 0,0, 456*b6490206SBarry Smith 0,0,/*MatConvert_SeqBAIJ*/ 0, 457*b6490206SBarry Smith 0,0, 458*b6490206SBarry Smith MatConvertSameType_SeqBAIJ,0,0, 459*b6490206SBarry Smith MatILUFactor_SeqBAIJ,0,0, 460*b6490206SBarry Smith 0,0, 461*b6490206SBarry Smith 0,0, 462*b6490206SBarry Smith MatPrintHelp_SeqBAIJ,MatScale_SeqBAIJ, 463*b6490206SBarry Smith 0}; 4642593348eSBarry Smith 4652593348eSBarry Smith /*@C 466*b6490206SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in AIJ (compressed row) format 4672593348eSBarry Smith (the default parallel PETSc format). For good matrix assembly performance 4682593348eSBarry Smith the user should preallocate the matrix storage by setting the parameter nz 4692593348eSBarry Smith (or nzz). By setting these parameters accurately, performance can be 4702593348eSBarry Smith increased by more than a factor of 50. 4712593348eSBarry Smith 4722593348eSBarry Smith Input Parameters: 4732593348eSBarry Smith . comm - MPI communicator, set to MPI_COMM_SELF 474*b6490206SBarry Smith . bs - size of block 4752593348eSBarry Smith . m - number of rows 4762593348eSBarry Smith . n - number of columns 477*b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 478*b6490206SBarry Smith . nzz - number of block nonzeros per block row or PETSC_NULL 479*b6490206SBarry Smith (possibly different for each row) 4802593348eSBarry Smith 4812593348eSBarry Smith Output Parameter: 4822593348eSBarry Smith . A - the matrix 4832593348eSBarry Smith 4842593348eSBarry Smith Notes: 485*b6490206SBarry Smith The BAIJ format, is fully compatible with standard Fortran 77 4862593348eSBarry Smith storage. That is, the stored row and column indices can begin at 4872593348eSBarry Smith either one (as in Fortran) or zero. See the users manual for details. 4882593348eSBarry Smith 4892593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 4902593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 4912593348eSBarry Smith allocation. For additional details, see the users manual chapter on 4922593348eSBarry Smith matrices and the file $(PETSC_DIR)/Performance. 4932593348eSBarry Smith 4942593348eSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues() 4952593348eSBarry Smith @*/ 496*b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 4972593348eSBarry Smith { 4982593348eSBarry Smith Mat B; 499*b6490206SBarry Smith Mat_SeqBAIJ *b; 500*b6490206SBarry Smith int i,len,ierr, flg,mbs = m/bs; 501*b6490206SBarry Smith 502*b6490206SBarry Smith if (mbs*bs != m) 503*b6490206SBarry Smith SETERRQ(1,"MatCreateSeqBAIJ:Number rows must be divisible by blocksize"); 5042593348eSBarry Smith 5052593348eSBarry Smith *A = 0; 506*b6490206SBarry Smith PetscHeaderCreate(B,_Mat,MAT_COOKIE,MATSEQBAIJ,comm); 5072593348eSBarry Smith PLogObjectCreate(B); 508*b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 5092593348eSBarry Smith PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps)); 510*b6490206SBarry Smith B->destroy = MatDestroy_SeqBAIJ; 511*b6490206SBarry Smith B->view = MatView_SeqBAIJ; 5122593348eSBarry Smith B->factor = 0; 5132593348eSBarry Smith B->lupivotthreshold = 1.0; 5142593348eSBarry Smith ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold, \ 5152593348eSBarry Smith &flg); CHKERRQ(ierr); 5162593348eSBarry Smith b->row = 0; 5172593348eSBarry Smith b->col = 0; 5182593348eSBarry Smith b->indexshift = 0; 5192593348eSBarry Smith b->reallocs = 0; 5202593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg); CHKERRQ(ierr); 5212593348eSBarry Smith if (flg) b->indexshift = -1; 5222593348eSBarry Smith 5232593348eSBarry Smith b->m = m; 524*b6490206SBarry Smith b->mbs = mbs; 5252593348eSBarry Smith b->n = n; 526*b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 5272593348eSBarry Smith if (nnz == PETSC_NULL) { 5282593348eSBarry Smith if (nz == PETSC_DEFAULT) nz = 10; 5292593348eSBarry Smith else if (nz <= 0) nz = 1; 530*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 531*b6490206SBarry Smith nz = nz*mbs; 5322593348eSBarry Smith } 5332593348eSBarry Smith else { 5342593348eSBarry Smith nz = 0; 535*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 5362593348eSBarry Smith } 5372593348eSBarry Smith 5382593348eSBarry Smith /* allocate the matrix space */ 539*b6490206SBarry Smith len = nz*sizeof(int) + nz*bs*bs*sizeof(Scalar) + (b->m+1)*sizeof(int); 5402593348eSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 541*b6490206SBarry Smith PetscMemzero(b->a,nz*bs*bs*sizeof(Scalar)); 542*b6490206SBarry Smith b->j = (int *) (b->a + nz*bs*bs); 5432593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 5442593348eSBarry Smith b->i = b->j + nz; 5452593348eSBarry Smith b->singlemalloc = 1; 5462593348eSBarry Smith 5472593348eSBarry Smith b->i[0] = -b->indexshift; 548*b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 5492593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 5502593348eSBarry Smith } 5512593348eSBarry Smith 552*b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 553*b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 554*b6490206SBarry Smith PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqBAIJ)); 555*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 5562593348eSBarry Smith 557*b6490206SBarry Smith b->bs = bs; 558*b6490206SBarry Smith b->mbs = mbs; 5592593348eSBarry Smith b->nz = 0; 5602593348eSBarry Smith b->maxnz = nz; 5612593348eSBarry Smith b->sorted = 0; 5622593348eSBarry Smith b->roworiented = 1; 5632593348eSBarry Smith b->nonew = 0; 5642593348eSBarry Smith b->diag = 0; 5652593348eSBarry Smith b->solve_work = 0; 5662593348eSBarry Smith b->spptr = 0; 5672593348eSBarry Smith 5682593348eSBarry Smith *A = B; 5692593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 5702593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 5712593348eSBarry Smith return 0; 5722593348eSBarry Smith } 5732593348eSBarry Smith 574*b6490206SBarry Smith int MatConvertSameType_SeqBAIJ(Mat A,Mat *B,int cpvalues) 5752593348eSBarry Smith { 5762593348eSBarry Smith Mat C; 577*b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 578*b6490206SBarry Smith int i,len, shift = a->indexshift, mbs = a->mbs, bs = a->bs; 5792593348eSBarry Smith 5802593348eSBarry Smith *B = 0; 581*b6490206SBarry Smith PetscHeaderCreate(C,_Mat,MAT_COOKIE,MATSEQBAIJ,A->comm); 5822593348eSBarry Smith PLogObjectCreate(C); 583*b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 5842593348eSBarry Smith PetscMemcpy(&C->ops,&A->ops,sizeof(struct _MatOps)); 585*b6490206SBarry Smith C->destroy = MatDestroy_SeqBAIJ; 586*b6490206SBarry Smith C->view = MatView_SeqBAIJ; 5872593348eSBarry Smith C->factor = A->factor; 5882593348eSBarry Smith c->row = 0; 5892593348eSBarry Smith c->col = 0; 5902593348eSBarry Smith c->indexshift = shift; 5912593348eSBarry Smith C->assembled = PETSC_TRUE; 5922593348eSBarry Smith 5932593348eSBarry Smith c->m = a->m; 5942593348eSBarry Smith c->n = a->n; 595*b6490206SBarry Smith c->bs = a->bs; 596*b6490206SBarry Smith c->mbs = a->mbs; 597*b6490206SBarry Smith c->nbs = a->nbs; 5982593348eSBarry Smith 599*b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 600*b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 601*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 6022593348eSBarry Smith c->imax[i] = a->imax[i]; 6032593348eSBarry Smith c->ilen[i] = a->ilen[i]; 6042593348eSBarry Smith } 6052593348eSBarry Smith 6062593348eSBarry Smith /* allocate the matrix space */ 6072593348eSBarry Smith c->singlemalloc = 1; 608*b6490206SBarry Smith len = (mbs+1)*sizeof(int)+(a->i[mbs])*(bs*bs*sizeof(Scalar)+sizeof(int)); 6092593348eSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 610*b6490206SBarry Smith c->j = (int *) (c->a + a->i[mbs]*bs*bs + shift); 611*b6490206SBarry Smith c->i = c->j + a->i[mbs] + shift; 612*b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 613*b6490206SBarry Smith if (mbs > 0) { 614*b6490206SBarry Smith PetscMemcpy(c->j,a->j,(a->i[mbs]+shift)*sizeof(int)); 6152593348eSBarry Smith if (cpvalues == COPY_VALUES) { 616*b6490206SBarry Smith PetscMemcpy(c->a,a->a,(bs*bs*a->i[mbs]+shift)*sizeof(Scalar)); 6172593348eSBarry Smith } 6182593348eSBarry Smith } 6192593348eSBarry Smith 620*b6490206SBarry Smith PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _Mat)+sizeof(Mat_SeqBAIJ)); 6212593348eSBarry Smith c->sorted = a->sorted; 6222593348eSBarry Smith c->roworiented = a->roworiented; 6232593348eSBarry Smith c->nonew = a->nonew; 6242593348eSBarry Smith 6252593348eSBarry Smith if (a->diag) { 626*b6490206SBarry Smith c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag); 627*b6490206SBarry Smith PLogObjectMemory(C,(mbs+1)*sizeof(int)); 628*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 6292593348eSBarry Smith c->diag[i] = a->diag[i]; 6302593348eSBarry Smith } 6312593348eSBarry Smith } 6322593348eSBarry Smith else c->diag = 0; 6332593348eSBarry Smith c->nz = a->nz; 6342593348eSBarry Smith c->maxnz = a->maxnz; 6352593348eSBarry Smith c->solve_work = 0; 6362593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 6372593348eSBarry Smith 6382593348eSBarry Smith *B = C; 6392593348eSBarry Smith return 0; 6402593348eSBarry Smith } 6412593348eSBarry Smith 642*b6490206SBarry Smith int MatLoad_SeqBAIJ(Viewer bview,MatType type,Mat *A) 6432593348eSBarry Smith { 644*b6490206SBarry Smith Mat_SeqBAIJ *a; 6452593348eSBarry Smith Mat B; 646*b6490206SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,shift,bs=1,flg; 647*b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 648*b6490206SBarry Smith int kmax,jcount,block,idx,point,nzcountb; 649*b6490206SBarry Smith Scalar *aa; 6502593348eSBarry Smith PetscObject vobj = (PetscObject) bview; 6512593348eSBarry Smith MPI_Comm comm = vobj->comm; 6522593348eSBarry Smith 653*b6490206SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_baij_bs",&bs,&flg);CHKERRQ(ierr); 654*b6490206SBarry Smith 6552593348eSBarry Smith MPI_Comm_size(comm,&size); 656*b6490206SBarry Smith if (size > 1) SETERRQ(1,"MatLoad_SeqBAIJ:view must have one processor"); 6572593348eSBarry Smith ierr = ViewerFileGetDescriptor_Private(bview,&fd); CHKERRQ(ierr); 6582593348eSBarry Smith ierr = SYRead(fd,header,4,SYINT); CHKERRQ(ierr); 659*b6490206SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(1,"MatLoad_SeqBAIJ:not Mat object in file"); 6602593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 6612593348eSBarry Smith 662*b6490206SBarry Smith if (M != N) SETERRQ(1,"MatLoad_SeqBAIJ:Can only do square matrices"); 663*b6490206SBarry Smith mbs = M/bs; 664*b6490206SBarry Smith if (bs*mbs != M) SETERRQ(1,"MatLoad_SeqBAIJ:Rows not divisble by blocksize"); 665*b6490206SBarry Smith 6662593348eSBarry Smith /* read in row lengths */ 6672593348eSBarry Smith rowlengths = (int*) PetscMalloc( M*sizeof(int) ); CHKPTRQ(rowlengths); 6682593348eSBarry Smith ierr = SYRead(fd,rowlengths,M,SYINT); CHKERRQ(ierr); 6692593348eSBarry Smith 670*b6490206SBarry Smith /* read in column indices */ 671*b6490206SBarry Smith jj = (int*) PetscMalloc( nz*sizeof(int) ); CHKPTRQ(jj); 672*b6490206SBarry Smith ierr = SYRead(fd,jj,nz,SYINT); CHKERRQ(ierr); 673*b6490206SBarry Smith 674*b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 675*b6490206SBarry Smith browlengths = (int *) PetscMalloc( mbs*sizeof(int) );CHKPTRQ(browlengths); 676*b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 677*b6490206SBarry Smith mask = (int *) PetscMalloc( mbs*sizeof(int) ); CHKPTRQ(mask); 678*b6490206SBarry Smith rowcount = 0; nzcount = 0; 679*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 680*b6490206SBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 681*b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 682*b6490206SBarry Smith kmax = rowlengths[rowcount]; 683*b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 684*b6490206SBarry Smith mask[jj[nzcount++]/bs] = 1; 685*b6490206SBarry Smith } 686*b6490206SBarry Smith rowcount++; 687*b6490206SBarry Smith } 688*b6490206SBarry Smith for ( j=0; j<mbs; j++ ) { 689*b6490206SBarry Smith if (mask[j]) browlengths[i]++; 690*b6490206SBarry Smith } 691*b6490206SBarry Smith } 692*b6490206SBarry Smith 6932593348eSBarry Smith /* create our matrix */ 694*b6490206SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M,N,0,browlengths,A); CHKERRQ(ierr); 6952593348eSBarry Smith B = *A; 696*b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 6972593348eSBarry Smith shift = a->indexshift; 6982593348eSBarry Smith 6992593348eSBarry Smith /* set matrix "i" values */ 7002593348eSBarry Smith a->i[0] = -shift; 701*b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 702*b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 703*b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 7042593348eSBarry Smith } 705*b6490206SBarry Smith a->nz = 0; 706*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 7072593348eSBarry Smith 708*b6490206SBarry Smith /* read in nonzero values */ 709*b6490206SBarry Smith aa = (Scalar *) PetscMalloc( nz*sizeof(Scalar) ); CHKPTRQ(aa); 710*b6490206SBarry Smith ierr = SYRead(fd,aa,nz,SYSCALAR); CHKERRQ(ierr); 711*b6490206SBarry Smith 712*b6490206SBarry Smith /* set "a" and "j" values into matrix */ 713*b6490206SBarry Smith nzcount = 0; jcount = 0; 714*b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 715*b6490206SBarry Smith nzcountb = nzcount; 716*b6490206SBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 717*b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 718*b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 719*b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 720*b6490206SBarry Smith mask[jj[nzcount++]/bs] = 1; 721*b6490206SBarry Smith } 722*b6490206SBarry Smith rowcount++; 723*b6490206SBarry Smith } 724*b6490206SBarry Smith /* set "j" values into matrix */ 725*b6490206SBarry Smith maskcount = 1; 726*b6490206SBarry Smith for ( j=0; j<mbs; j++ ) { 727*b6490206SBarry Smith if (mask[j]) { 728*b6490206SBarry Smith a->j[jcount++] = j; 729*b6490206SBarry Smith mask[j] = maskcount++; /* what nonzero block in this row is j */ 730*b6490206SBarry Smith } 731*b6490206SBarry Smith } 732*b6490206SBarry Smith /* set "a" values into matrix */ 733*b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 734*b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 735*b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 736*b6490206SBarry Smith block = mask[jj[nzcountb]/bs] - 1; 737*b6490206SBarry Smith point = jj[nzcountb] - bs*(jj[nzcountb]/bs); 738*b6490206SBarry Smith idx = bs*bs*(a->i[i] + block) + j + bs*(point); 739*b6490206SBarry Smith /* printf("block row %d subrow %d cold %d block %d idx %d val %g a->i[i] %d point %d\n",i,j,k,block,idx, 740*b6490206SBarry Smith aa[nzcountb],a->i[i],point); */ 741*b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 742*b6490206SBarry Smith } 743*b6490206SBarry Smith } 744*b6490206SBarry Smith } 745*b6490206SBarry Smith if (jcount != a->nz) SETERRQ(1,"MatLoad_SeqBAIJ:Bad new"); 746*b6490206SBarry Smith 747*b6490206SBarry Smith PetscFree(rowlengths); 748*b6490206SBarry Smith PetscFree(browlengths); 749*b6490206SBarry Smith PetscFree(aa); 750*b6490206SBarry Smith PetscFree(jj); 751*b6490206SBarry Smith PetscFree(mask); 752*b6490206SBarry Smith 753*b6490206SBarry Smith B->assembled = PETSC_TRUE; 754*b6490206SBarry Smith 755*b6490206SBarry Smith /* MatView(*A,STDOUT_VIEWER_SELF); */ 7562593348eSBarry Smith return 0; 7572593348eSBarry Smith } 7582593348eSBarry Smith 7592593348eSBarry Smith 7602593348eSBarry Smith 761