1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*cc2dc46cSBarry Smith static char vcid[] = "$Id: baij.c,v 1.138 1998/05/29 22:49:30 balay Exp bsmith $"; 32593348eSBarry Smith #endif 42593348eSBarry Smith 52593348eSBarry Smith /* 6b6490206SBarry Smith Defines the basic matrix operations for the BAIJ (compressed row) 72593348eSBarry Smith matrix storage format. 82593348eSBarry Smith */ 93369ce9aSBarry Smith 103369ce9aSBarry Smith #include "pinclude/pviewer.h" 113369ce9aSBarry Smith #include "sys.h" 1270f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h" 131a6a6d98SBarry Smith #include "src/vec/vecimpl.h" 141a6a6d98SBarry Smith #include "src/inline/spops.h" 152593348eSBarry Smith #include "petsc.h" 163b547af2SSatish Balay 172d61bbb3SSatish Balay #define CHUNKSIZE 10 18de6a44a3SBarry Smith 195615d1e5SSatish Balay #undef __FUNC__ 205615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqBAIJ" 21de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A) 22de6a44a3SBarry Smith { 23de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 247fc0212eSBarry Smith int i,j, *diag, m = a->mbs; 25de6a44a3SBarry Smith 263a40ed3dSBarry Smith PetscFunctionBegin; 27de6a44a3SBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 28de6a44a3SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 297fc0212eSBarry Smith for ( i=0; i<m; i++ ) { 30de6a44a3SBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 31de6a44a3SBarry Smith if (a->j[j] == i) { 32de6a44a3SBarry Smith diag[i] = j; 33de6a44a3SBarry Smith break; 34de6a44a3SBarry Smith } 35de6a44a3SBarry Smith } 36de6a44a3SBarry Smith } 37de6a44a3SBarry Smith a->diag = diag; 383a40ed3dSBarry Smith PetscFunctionReturn(0); 39de6a44a3SBarry Smith } 402593348eSBarry Smith 412593348eSBarry Smith 423b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 433b2fbd54SBarry Smith 445615d1e5SSatish Balay #undef __FUNC__ 455615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqBAIJ" 463b2fbd54SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 473b2fbd54SBarry Smith PetscTruth *done) 483b2fbd54SBarry Smith { 493b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 503b2fbd54SBarry Smith int ierr, n = a->mbs,i; 513b2fbd54SBarry Smith 523a40ed3dSBarry Smith PetscFunctionBegin; 533b2fbd54SBarry Smith *nn = n; 543a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 553b2fbd54SBarry Smith if (symmetric) { 563b2fbd54SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 573b2fbd54SBarry Smith } else if (oshift == 1) { 583b2fbd54SBarry Smith /* temporarily add 1 to i and j indices */ 593b2fbd54SBarry Smith int nz = a->i[n] + 1; 603b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]++; 613b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]++; 623b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 633b2fbd54SBarry Smith } else { 643b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 653b2fbd54SBarry Smith } 663b2fbd54SBarry Smith 673a40ed3dSBarry Smith PetscFunctionReturn(0); 683b2fbd54SBarry Smith } 693b2fbd54SBarry Smith 705615d1e5SSatish Balay #undef __FUNC__ 71d4bb536fSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ" 723b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 733b2fbd54SBarry Smith PetscTruth *done) 743b2fbd54SBarry Smith { 753b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 763b2fbd54SBarry Smith int i,n = a->mbs; 773b2fbd54SBarry Smith 783a40ed3dSBarry Smith PetscFunctionBegin; 793a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 803b2fbd54SBarry Smith if (symmetric) { 813b2fbd54SBarry Smith PetscFree(*ia); 823b2fbd54SBarry Smith PetscFree(*ja); 83af5da2bfSBarry Smith } else if (oshift == 1) { 843b2fbd54SBarry Smith int nz = a->i[n]; 853b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]--; 863b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]--; 873b2fbd54SBarry Smith } 883a40ed3dSBarry Smith PetscFunctionReturn(0); 893b2fbd54SBarry Smith } 903b2fbd54SBarry Smith 912d61bbb3SSatish Balay #undef __FUNC__ 922d61bbb3SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqBAIJ" 932d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat, int *bs) 942d61bbb3SSatish Balay { 952d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *) mat->data; 962d61bbb3SSatish Balay 972d61bbb3SSatish Balay PetscFunctionBegin; 982d61bbb3SSatish Balay *bs = baij->bs; 992d61bbb3SSatish Balay PetscFunctionReturn(0); 1002d61bbb3SSatish Balay } 1012d61bbb3SSatish Balay 1022d61bbb3SSatish Balay 1032d61bbb3SSatish Balay #undef __FUNC__ 1042d61bbb3SSatish Balay #define __FUNC__ "MatDestroy_SeqBAIJ" 105e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A) 1062d61bbb3SSatish Balay { 1072d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 108e51c0b9cSSatish Balay int ierr; 1092d61bbb3SSatish Balay 11094d884c6SBarry Smith if (--A->refct > 0) PetscFunctionReturn(0); 11194d884c6SBarry Smith 11294d884c6SBarry Smith if (A->mapping) { 11394d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping); CHKERRQ(ierr); 11494d884c6SBarry Smith } 11594d884c6SBarry Smith if (A->bmapping) { 11694d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->bmapping); CHKERRQ(ierr); 11794d884c6SBarry Smith } 1182d61bbb3SSatish Balay #if defined(USE_PETSC_LOG) 119e1311b90SBarry Smith PLogObjectState((PetscObject) A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 1202d61bbb3SSatish Balay #endif 1212d61bbb3SSatish Balay PetscFree(a->a); 1222d61bbb3SSatish Balay if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 1232d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 1242d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 1252d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 1262d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 1272d61bbb3SSatish Balay if (a->mult_work) PetscFree(a->mult_work); 128e51c0b9cSSatish Balay if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 1292d61bbb3SSatish Balay PetscFree(a); 1302d61bbb3SSatish Balay PLogObjectDestroy(A); 1312d61bbb3SSatish Balay PetscHeaderDestroy(A); 1322d61bbb3SSatish Balay PetscFunctionReturn(0); 1332d61bbb3SSatish Balay } 1342d61bbb3SSatish Balay 1352d61bbb3SSatish Balay #undef __FUNC__ 1362d61bbb3SSatish Balay #define __FUNC__ "MatSetOption_SeqBAIJ" 1372d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1382d61bbb3SSatish Balay { 1392d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1402d61bbb3SSatish Balay 1412d61bbb3SSatish Balay PetscFunctionBegin; 1422d61bbb3SSatish Balay if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 1432d61bbb3SSatish Balay else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 1442d61bbb3SSatish Balay else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 1452d61bbb3SSatish Balay else if (op == MAT_COLUMNS_UNSORTED) a->sorted = 0; 1462d61bbb3SSatish Balay else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 1472d61bbb3SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERROR) a->nonew = -1; 1482d61bbb3SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERROR) a->nonew = -2; 1492d61bbb3SSatish Balay else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 1502d61bbb3SSatish Balay else if (op == MAT_ROWS_SORTED || 1512d61bbb3SSatish Balay op == MAT_ROWS_UNSORTED || 1522d61bbb3SSatish Balay op == MAT_SYMMETRIC || 1532d61bbb3SSatish Balay op == MAT_STRUCTURALLY_SYMMETRIC || 1542d61bbb3SSatish Balay op == MAT_YES_NEW_DIAGONALS || 155b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES || 156b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) { 157981c4779SBarry Smith PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 1582d61bbb3SSatish Balay } else if (op == MAT_NO_NEW_DIAGONALS) { 1592d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 1602d61bbb3SSatish Balay } else { 1612d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 1622d61bbb3SSatish Balay } 1632d61bbb3SSatish Balay PetscFunctionReturn(0); 1642d61bbb3SSatish Balay } 1652d61bbb3SSatish Balay 1662d61bbb3SSatish Balay 1672d61bbb3SSatish Balay #undef __FUNC__ 1682d61bbb3SSatish Balay #define __FUNC__ "MatGetSize_SeqBAIJ" 1692d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n) 1702d61bbb3SSatish Balay { 1712d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1722d61bbb3SSatish Balay 1732d61bbb3SSatish Balay PetscFunctionBegin; 1742d61bbb3SSatish Balay if (m) *m = a->m; 1752d61bbb3SSatish Balay if (n) *n = a->n; 1762d61bbb3SSatish Balay PetscFunctionReturn(0); 1772d61bbb3SSatish Balay } 1782d61bbb3SSatish Balay 1792d61bbb3SSatish Balay #undef __FUNC__ 1802d61bbb3SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ" 1812d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 1822d61bbb3SSatish Balay { 1832d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1842d61bbb3SSatish Balay 1852d61bbb3SSatish Balay PetscFunctionBegin; 1862d61bbb3SSatish Balay *m = 0; *n = a->m; 1872d61bbb3SSatish Balay PetscFunctionReturn(0); 1882d61bbb3SSatish Balay } 1892d61bbb3SSatish Balay 1902d61bbb3SSatish Balay #undef __FUNC__ 1912d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ" 1922d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 1932d61bbb3SSatish Balay { 1942d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1952d61bbb3SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2; 1962d61bbb3SSatish Balay Scalar *aa,*v_i,*aa_i; 1972d61bbb3SSatish Balay 1982d61bbb3SSatish Balay PetscFunctionBegin; 1992d61bbb3SSatish Balay bs = a->bs; 2002d61bbb3SSatish Balay ai = a->i; 2012d61bbb3SSatish Balay aj = a->j; 2022d61bbb3SSatish Balay aa = a->a; 2032d61bbb3SSatish Balay bs2 = a->bs2; 2042d61bbb3SSatish Balay 2052d61bbb3SSatish Balay if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 2062d61bbb3SSatish Balay 2072d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2082d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2092d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2102d61bbb3SSatish Balay *nz = bs*M; 2112d61bbb3SSatish Balay 2122d61bbb3SSatish Balay if (v) { 2132d61bbb3SSatish Balay *v = 0; 2142d61bbb3SSatish Balay if (*nz) { 2152d61bbb3SSatish Balay *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v); 2162d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2172d61bbb3SSatish Balay v_i = *v + i*bs; 2182d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2192d61bbb3SSatish Balay for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];} 2202d61bbb3SSatish Balay } 2212d61bbb3SSatish Balay } 2222d61bbb3SSatish Balay } 2232d61bbb3SSatish Balay 2242d61bbb3SSatish Balay if (idx) { 2252d61bbb3SSatish Balay *idx = 0; 2262d61bbb3SSatish Balay if (*nz) { 2272d61bbb3SSatish Balay *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 2282d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2292d61bbb3SSatish Balay idx_i = *idx + i*bs; 2302d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2312d61bbb3SSatish Balay for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;} 2322d61bbb3SSatish Balay } 2332d61bbb3SSatish Balay } 2342d61bbb3SSatish Balay } 2352d61bbb3SSatish Balay PetscFunctionReturn(0); 2362d61bbb3SSatish Balay } 2372d61bbb3SSatish Balay 2382d61bbb3SSatish Balay #undef __FUNC__ 2392d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ" 2402d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2412d61bbb3SSatish Balay { 2422d61bbb3SSatish Balay PetscFunctionBegin; 2432d61bbb3SSatish Balay if (idx) {if (*idx) PetscFree(*idx);} 2442d61bbb3SSatish Balay if (v) {if (*v) PetscFree(*v);} 2452d61bbb3SSatish Balay PetscFunctionReturn(0); 2462d61bbb3SSatish Balay } 2472d61bbb3SSatish Balay 2482d61bbb3SSatish Balay #undef __FUNC__ 2492d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ" 2502d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2512d61bbb3SSatish Balay { 2522d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2532d61bbb3SSatish Balay Mat C; 2542d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 2552d61bbb3SSatish Balay int *rows,*cols,bs2=a->bs2; 2562d61bbb3SSatish Balay Scalar *array=a->a; 2572d61bbb3SSatish Balay 2582d61bbb3SSatish Balay PetscFunctionBegin; 2592d61bbb3SSatish Balay if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place"); 2602d61bbb3SSatish Balay col = (int *) PetscMalloc((1+nbs)*sizeof(int)); CHKPTRQ(col); 2612d61bbb3SSatish Balay PetscMemzero(col,(1+nbs)*sizeof(int)); 2622d61bbb3SSatish Balay 2632d61bbb3SSatish Balay for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1; 2642d61bbb3SSatish Balay ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C); CHKERRQ(ierr); 2652d61bbb3SSatish Balay PetscFree(col); 2662d61bbb3SSatish Balay rows = (int *) PetscMalloc(2*bs*sizeof(int)); CHKPTRQ(rows); 2672d61bbb3SSatish Balay cols = rows + bs; 2682d61bbb3SSatish Balay for ( i=0; i<mbs; i++ ) { 2692d61bbb3SSatish Balay cols[0] = i*bs; 2702d61bbb3SSatish Balay for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1; 2712d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 2722d61bbb3SSatish Balay for ( j=0; j<len; j++ ) { 2732d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 2742d61bbb3SSatish Balay for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1; 2752d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES); CHKERRQ(ierr); 2762d61bbb3SSatish Balay array += bs2; 2772d61bbb3SSatish Balay } 2782d61bbb3SSatish Balay } 2792d61bbb3SSatish Balay PetscFree(rows); 2802d61bbb3SSatish Balay 2812d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2822d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2832d61bbb3SSatish Balay 2842d61bbb3SSatish Balay if (B != PETSC_NULL) { 2852d61bbb3SSatish Balay *B = C; 2862d61bbb3SSatish Balay } else { 287f830108cSBarry Smith PetscOps *Abops; 288*cc2dc46cSBarry Smith MatOps Aops; 289f830108cSBarry Smith 2902d61bbb3SSatish Balay /* This isn't really an in-place transpose */ 2912d61bbb3SSatish Balay PetscFree(a->a); 2922d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);} 2932d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 2942d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 2952d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 2962d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 2972d61bbb3SSatish Balay PetscFree(a); 298f830108cSBarry Smith 299f830108cSBarry Smith /* 300f830108cSBarry Smith This is horrible, horrible code. We need to keep the 301f830108cSBarry Smith A pointers for the bops and ops but copy everything 302f830108cSBarry Smith else from C. 303f830108cSBarry Smith */ 304f830108cSBarry Smith Abops = A->bops; 305f830108cSBarry Smith Aops = A->ops; 3062d61bbb3SSatish Balay PetscMemcpy(A,C,sizeof(struct _p_Mat)); 307f830108cSBarry Smith A->bops = Abops; 308f830108cSBarry Smith A->ops = Aops; 30927a8da17SBarry Smith A->qlist = 0; 310f830108cSBarry Smith 3112d61bbb3SSatish Balay PetscHeaderDestroy(C); 3122d61bbb3SSatish Balay } 3132d61bbb3SSatish Balay PetscFunctionReturn(0); 3142d61bbb3SSatish Balay } 3152d61bbb3SSatish Balay 3162d61bbb3SSatish Balay 3172d61bbb3SSatish Balay 3183b2fbd54SBarry Smith 3195615d1e5SSatish Balay #undef __FUNC__ 320d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary" 321b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer) 3222593348eSBarry Smith { 323b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3249df24120SSatish Balay int i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 325b6490206SBarry Smith Scalar *aa; 3262593348eSBarry Smith 3273a40ed3dSBarry Smith PetscFunctionBegin; 32890ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 3292593348eSBarry Smith col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 3302593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3313b2fbd54SBarry Smith 3322593348eSBarry Smith col_lens[1] = a->m; 3332593348eSBarry Smith col_lens[2] = a->n; 3347e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3352593348eSBarry Smith 3362593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 337b6490206SBarry Smith count = 0; 338b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 339b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 340b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 341b6490206SBarry Smith } 3422593348eSBarry Smith } 3430752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr); 3442593348eSBarry Smith PetscFree(col_lens); 3452593348eSBarry Smith 3462593348eSBarry Smith /* store column indices (zero start index) */ 34766963ce1SSatish Balay jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) ); CHKPTRQ(jj); 348b6490206SBarry Smith count = 0; 349b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 350b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 351b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 352b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 353b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3542593348eSBarry Smith } 3552593348eSBarry Smith } 356b6490206SBarry Smith } 357b6490206SBarry Smith } 3580752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0); CHKERRQ(ierr); 359b6490206SBarry Smith PetscFree(jj); 3602593348eSBarry Smith 3612593348eSBarry Smith /* store nonzero values */ 36266963ce1SSatish Balay aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar)); CHKPTRQ(aa); 363b6490206SBarry Smith count = 0; 364b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 365b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 366b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 367b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 3687e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 369b6490206SBarry Smith } 370b6490206SBarry Smith } 371b6490206SBarry Smith } 372b6490206SBarry Smith } 3730752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0); CHKERRQ(ierr); 374b6490206SBarry Smith PetscFree(aa); 3753a40ed3dSBarry Smith PetscFunctionReturn(0); 3762593348eSBarry Smith } 3772593348eSBarry Smith 3785615d1e5SSatish Balay #undef __FUNC__ 379d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII" 380b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer) 3812593348eSBarry Smith { 382b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3839df24120SSatish Balay int ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2; 3842593348eSBarry Smith FILE *fd; 3852593348eSBarry Smith char *outputname; 3862593348eSBarry Smith 3873a40ed3dSBarry Smith PetscFunctionBegin; 38890ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 3892593348eSBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname);CHKERRQ(ierr); 39090ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 391639f9d9dSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) { 3927ddc982cSLois Curfman McInnes fprintf(fd," block size is %d\n",bs); 3932593348eSBarry Smith } 394639f9d9dSBarry Smith else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 395a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported"); 3962593348eSBarry Smith } 397639f9d9dSBarry Smith else if (format == VIEWER_FORMAT_ASCII_COMMON) { 39844cd7ae7SLois Curfman McInnes for ( i=0; i<a->mbs; i++ ) { 39944cd7ae7SLois Curfman McInnes for ( j=0; j<bs; j++ ) { 40044cd7ae7SLois Curfman McInnes fprintf(fd,"row %d:",i*bs+j); 40144cd7ae7SLois Curfman McInnes for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 40244cd7ae7SLois Curfman McInnes for ( l=0; l<bs; l++ ) { 4033a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 404e20fef11SSatish Balay if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) 40544cd7ae7SLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 406e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j])); 407e20fef11SSatish Balay else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) 408766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 409e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 410e20fef11SSatish Balay else if (PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) 411e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 41244cd7ae7SLois Curfman McInnes #else 41344cd7ae7SLois Curfman McInnes if (a->a[bs2*k + l*bs + j] != 0.0) 41444cd7ae7SLois Curfman McInnes fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 41544cd7ae7SLois Curfman McInnes #endif 41644cd7ae7SLois Curfman McInnes } 41744cd7ae7SLois Curfman McInnes } 41844cd7ae7SLois Curfman McInnes fprintf(fd,"\n"); 41944cd7ae7SLois Curfman McInnes } 42044cd7ae7SLois Curfman McInnes } 42144cd7ae7SLois Curfman McInnes } 4222593348eSBarry Smith else { 423b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 424b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 425b6490206SBarry Smith fprintf(fd,"row %d:",i*bs+j); 426b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 427b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 4283a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 429e20fef11SSatish Balay if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0) { 43088685aaeSLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 431e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j])); 43288685aaeSLois Curfman McInnes } 433e20fef11SSatish Balay else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0) { 434766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 435e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 436766eeae4SLois Curfman McInnes } 43788685aaeSLois Curfman McInnes else { 438e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 43988685aaeSLois Curfman McInnes } 44088685aaeSLois Curfman McInnes #else 4417e67e3f9SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 44288685aaeSLois Curfman McInnes #endif 4432593348eSBarry Smith } 4442593348eSBarry Smith } 4452593348eSBarry Smith fprintf(fd,"\n"); 4462593348eSBarry Smith } 4472593348eSBarry Smith } 448b6490206SBarry Smith } 4492593348eSBarry Smith fflush(fd); 4503a40ed3dSBarry Smith PetscFunctionReturn(0); 4512593348eSBarry Smith } 4522593348eSBarry Smith 4535615d1e5SSatish Balay #undef __FUNC__ 454d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw" 4553270192aSSatish Balay static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer) 4563270192aSSatish Balay { 4573270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *) A->data; 4583270192aSSatish Balay int row,ierr,i,j,k,l,mbs=a->mbs,pause,color,bs=a->bs,bs2=a->bs2; 4593270192aSSatish Balay double xl,yl,xr,yr,w,h,xc,yc,scale = 1.0,x_l,x_r,y_l,y_r; 4603270192aSSatish Balay Scalar *aa; 4613270192aSSatish Balay Draw draw; 4623270192aSSatish Balay DrawButton button; 4633270192aSSatish Balay PetscTruth isnull; 4643270192aSSatish Balay 4653a40ed3dSBarry Smith PetscFunctionBegin; 4663a40ed3dSBarry Smith ierr = ViewerDrawGetDraw(viewer,&draw);CHKERRQ(ierr); 4673a40ed3dSBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 4683270192aSSatish Balay 4693270192aSSatish Balay xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 4703270192aSSatish Balay xr += w; yr += h; xl = -w; yl = -h; 4713270192aSSatish Balay ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 4723270192aSSatish Balay /* loop over matrix elements drawing boxes */ 4733270192aSSatish Balay color = DRAW_BLUE; 4743270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 4753270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 4763270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 4773270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4783270192aSSatish Balay aa = a->a + j*bs2; 4793270192aSSatish Balay for ( k=0; k<bs; k++ ) { 4803270192aSSatish Balay for ( l=0; l<bs; l++ ) { 4813270192aSSatish Balay if (PetscReal(*aa++) >= 0.) continue; 482b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 4833270192aSSatish Balay } 4843270192aSSatish Balay } 4853270192aSSatish Balay } 4863270192aSSatish Balay } 4873270192aSSatish Balay color = DRAW_CYAN; 4883270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 4893270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 4903270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 4913270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4923270192aSSatish Balay aa = a->a + j*bs2; 4933270192aSSatish Balay for ( k=0; k<bs; k++ ) { 4943270192aSSatish Balay for ( l=0; l<bs; l++ ) { 4953270192aSSatish Balay if (PetscReal(*aa++) != 0.) continue; 496b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 4973270192aSSatish Balay } 4983270192aSSatish Balay } 4993270192aSSatish Balay } 5003270192aSSatish Balay } 5013270192aSSatish Balay 5023270192aSSatish Balay color = DRAW_RED; 5033270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5043270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5053270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5063270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5073270192aSSatish Balay aa = a->a + j*bs2; 5083270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5093270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5103270192aSSatish Balay if (PetscReal(*aa++) <= 0.) continue; 511b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5123270192aSSatish Balay } 5133270192aSSatish Balay } 5143270192aSSatish Balay } 5153270192aSSatish Balay } 5163270192aSSatish Balay 51755843e3eSBarry Smith DrawSynchronizedFlush(draw); 5183270192aSSatish Balay DrawGetPause(draw,&pause); 5193a40ed3dSBarry Smith if (pause >= 0) { PetscSleep(pause); PetscFunctionReturn(0);} 5203270192aSSatish Balay 5213270192aSSatish Balay /* allow the matrix to zoom or shrink */ 52255843e3eSBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0); 5233270192aSSatish Balay while (button != BUTTON_RIGHT) { 52455843e3eSBarry Smith DrawSynchronizedClear(draw); 5253270192aSSatish Balay if (button == BUTTON_LEFT) scale = .5; 5263270192aSSatish Balay else if (button == BUTTON_CENTER) scale = 2.; 5273270192aSSatish Balay xl = scale*(xl + w - xc) + xc - w*scale; 5283270192aSSatish Balay xr = scale*(xr - w - xc) + xc + w*scale; 5293270192aSSatish Balay yl = scale*(yl + h - yc) + yc - h*scale; 5303270192aSSatish Balay yr = scale*(yr - h - yc) + yc + h*scale; 5313270192aSSatish Balay w *= scale; h *= scale; 5323270192aSSatish Balay ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 5333270192aSSatish Balay color = DRAW_BLUE; 5343270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5353270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5363270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5373270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5383270192aSSatish Balay aa = a->a + j*bs2; 5393270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5403270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5413270192aSSatish Balay if (PetscReal(*aa++) >= 0.) continue; 542b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5433270192aSSatish Balay } 5443270192aSSatish Balay } 5453270192aSSatish Balay } 5463270192aSSatish Balay } 5473270192aSSatish Balay color = DRAW_CYAN; 5483270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5493270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5503270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5513270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5523270192aSSatish Balay aa = a->a + j*bs2; 5533270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5543270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5553270192aSSatish Balay if (PetscReal(*aa++) != 0.) continue; 556b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5573270192aSSatish Balay } 5583270192aSSatish Balay } 5593270192aSSatish Balay } 5603270192aSSatish Balay } 5613270192aSSatish Balay 5623270192aSSatish Balay color = DRAW_RED; 5633270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5643270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5653270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5663270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5673270192aSSatish Balay aa = a->a + j*bs2; 5683270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5693270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5703270192aSSatish Balay if (PetscReal(*aa++) <= 0.) continue; 571b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5723270192aSSatish Balay } 5733270192aSSatish Balay } 5743270192aSSatish Balay } 5753270192aSSatish Balay } 57655843e3eSBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0); 5773270192aSSatish Balay } 5783a40ed3dSBarry Smith PetscFunctionReturn(0); 5793270192aSSatish Balay } 5803270192aSSatish Balay 5815615d1e5SSatish Balay #undef __FUNC__ 582d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ" 583e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer) 5842593348eSBarry Smith { 58519bcc07fSBarry Smith ViewerType vtype; 58619bcc07fSBarry Smith int ierr; 5872593348eSBarry Smith 5883a40ed3dSBarry Smith PetscFunctionBegin; 58919bcc07fSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 59019bcc07fSBarry Smith if (vtype == MATLAB_VIEWER) { 591a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Matlab viewer not supported"); 5923a40ed3dSBarry Smith } else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){ 5933a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5943a40ed3dSBarry Smith } else if (vtype == BINARY_FILE_VIEWER) { 5953a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 5963a40ed3dSBarry Smith } else if (vtype == DRAW_VIEWER) { 5973a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 5985cd90555SBarry Smith } else { 5995cd90555SBarry Smith SETERRQ(1,1,"Viewer type not supported by PETSc object"); 6002593348eSBarry Smith } 6013a40ed3dSBarry Smith PetscFunctionReturn(0); 6022593348eSBarry Smith } 603b6490206SBarry Smith 604cd0e1443SSatish Balay 6055615d1e5SSatish Balay #undef __FUNC__ 6062d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ" 6072d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 608cd0e1443SSatish Balay { 609cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6102d61bbb3SSatish Balay int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 6112d61bbb3SSatish Balay int *ai = a->i, *ailen = a->ilen; 6122d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 6132d61bbb3SSatish Balay Scalar *ap, *aa = a->a, zero = 0.0; 614cd0e1443SSatish Balay 6153a40ed3dSBarry Smith PetscFunctionBegin; 6162d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over rows */ 617cd0e1443SSatish Balay row = im[k]; brow = row/bs; 618a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 619a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 6202d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 6212c3acbe9SBarry Smith nrow = ailen[brow]; 6222d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over columns */ 623a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 624a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 6252d61bbb3SSatish Balay col = in[l] ; 6262d61bbb3SSatish Balay bcol = col/bs; 6272d61bbb3SSatish Balay cidx = col%bs; 6282d61bbb3SSatish Balay ridx = row%bs; 6292d61bbb3SSatish Balay high = nrow; 6302d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6312d61bbb3SSatish Balay while (high-low > 5) { 632cd0e1443SSatish Balay t = (low+high)/2; 633cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 634cd0e1443SSatish Balay else low = t; 635cd0e1443SSatish Balay } 636cd0e1443SSatish Balay for ( i=low; i<high; i++ ) { 637cd0e1443SSatish Balay if (rp[i] > bcol) break; 638cd0e1443SSatish Balay if (rp[i] == bcol) { 6392d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6402d61bbb3SSatish Balay goto finished; 641cd0e1443SSatish Balay } 642cd0e1443SSatish Balay } 6432d61bbb3SSatish Balay *v++ = zero; 6442d61bbb3SSatish Balay finished:; 645cd0e1443SSatish Balay } 646cd0e1443SSatish Balay } 6473a40ed3dSBarry Smith PetscFunctionReturn(0); 648cd0e1443SSatish Balay } 649cd0e1443SSatish Balay 6502d61bbb3SSatish Balay 6515615d1e5SSatish Balay #undef __FUNC__ 65205a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 65392c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 65492c4ed94SBarry Smith { 65592c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6568a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 657dd9472c6SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented; 658dd9472c6SBarry Smith int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval; 6590e324ae4SSatish Balay Scalar *ap,*value=v,*aa=a->a,*bap; 66092c4ed94SBarry Smith 6613a40ed3dSBarry Smith PetscFunctionBegin; 6620e324ae4SSatish Balay if (roworiented) { 6630e324ae4SSatish Balay stepval = (n-1)*bs; 6640e324ae4SSatish Balay } else { 6650e324ae4SSatish Balay stepval = (m-1)*bs; 6660e324ae4SSatish Balay } 66792c4ed94SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 66892c4ed94SBarry Smith row = im[k]; 6693a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 670a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 671a8c6a408SBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 67292c4ed94SBarry Smith #endif 67392c4ed94SBarry Smith rp = aj + ai[row]; 67492c4ed94SBarry Smith ap = aa + bs2*ai[row]; 67592c4ed94SBarry Smith rmax = imax[row]; 67692c4ed94SBarry Smith nrow = ailen[row]; 67792c4ed94SBarry Smith low = 0; 67892c4ed94SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 6793a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 680a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 681a8c6a408SBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 68292c4ed94SBarry Smith #endif 68392c4ed94SBarry Smith col = in[l]; 68492c4ed94SBarry Smith if (roworiented) { 6850e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 6860e324ae4SSatish Balay } else { 6870e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 68892c4ed94SBarry Smith } 68992c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 69092c4ed94SBarry Smith while (high-low > 7) { 69192c4ed94SBarry Smith t = (low+high)/2; 69292c4ed94SBarry Smith if (rp[t] > col) high = t; 69392c4ed94SBarry Smith else low = t; 69492c4ed94SBarry Smith } 69592c4ed94SBarry Smith for ( i=low; i<high; i++ ) { 69692c4ed94SBarry Smith if (rp[i] > col) break; 69792c4ed94SBarry Smith if (rp[i] == col) { 6988a84c255SSatish Balay bap = ap + bs2*i; 6990e324ae4SSatish Balay if (roworiented) { 7008a84c255SSatish Balay if (is == ADD_VALUES) { 701dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 702dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7038a84c255SSatish Balay bap[jj] += *value++; 704dd9472c6SBarry Smith } 705dd9472c6SBarry Smith } 7060e324ae4SSatish Balay } else { 707dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 708dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7090e324ae4SSatish Balay bap[jj] = *value++; 7108a84c255SSatish Balay } 711dd9472c6SBarry Smith } 712dd9472c6SBarry Smith } 7130e324ae4SSatish Balay } else { 7140e324ae4SSatish Balay if (is == ADD_VALUES) { 715dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 716dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7170e324ae4SSatish Balay *bap++ += *value++; 718dd9472c6SBarry Smith } 719dd9472c6SBarry Smith } 7200e324ae4SSatish Balay } else { 721dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 722dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7230e324ae4SSatish Balay *bap++ = *value++; 7240e324ae4SSatish Balay } 7258a84c255SSatish Balay } 726dd9472c6SBarry Smith } 727dd9472c6SBarry Smith } 728f1241b54SBarry Smith goto noinsert2; 72992c4ed94SBarry Smith } 73092c4ed94SBarry Smith } 73189280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 732a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 73392c4ed94SBarry Smith if (nrow >= rmax) { 73492c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 73592c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 73692c4ed94SBarry Smith Scalar *new_a; 73792c4ed94SBarry Smith 738a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 73989280ab3SLois Curfman McInnes 74092c4ed94SBarry Smith /* malloc new storage space */ 74192c4ed94SBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int); 74292c4ed94SBarry Smith new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 74392c4ed94SBarry Smith new_j = (int *) (new_a + bs2*new_nz); 74492c4ed94SBarry Smith new_i = new_j + new_nz; 74592c4ed94SBarry Smith 74692c4ed94SBarry Smith /* copy over old data into new slots */ 74792c4ed94SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 74892c4ed94SBarry Smith for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 74992c4ed94SBarry Smith PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int)); 75092c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 751dd9472c6SBarry Smith PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int)); 75292c4ed94SBarry Smith PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(Scalar)); 75392c4ed94SBarry Smith PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(Scalar)); 754dd9472c6SBarry Smith PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(Scalar)); 75592c4ed94SBarry Smith /* free up old matrix storage */ 75692c4ed94SBarry Smith PetscFree(a->a); 75792c4ed94SBarry Smith if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 75892c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 75992c4ed94SBarry Smith a->singlemalloc = 1; 76092c4ed94SBarry Smith 76192c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 76292c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 76392c4ed94SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar))); 76492c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 76592c4ed94SBarry Smith a->reallocs++; 76692c4ed94SBarry Smith a->nz++; 76792c4ed94SBarry Smith } 76892c4ed94SBarry Smith N = nrow++ - 1; 76992c4ed94SBarry Smith /* shift up all the later entries in this row */ 77092c4ed94SBarry Smith for ( ii=N; ii>=i; ii-- ) { 77192c4ed94SBarry Smith rp[ii+1] = rp[ii]; 77292c4ed94SBarry Smith PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar)); 77392c4ed94SBarry Smith } 77492c4ed94SBarry Smith if (N >= i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar)); 77592c4ed94SBarry Smith rp[i] = col; 7768a84c255SSatish Balay bap = ap + bs2*i; 7770e324ae4SSatish Balay if (roworiented) { 778dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval) { 779dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7800e324ae4SSatish Balay bap[jj] = *value++; 781dd9472c6SBarry Smith } 782dd9472c6SBarry Smith } 7830e324ae4SSatish Balay } else { 784dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 785dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7860e324ae4SSatish Balay *bap++ = *value++; 7870e324ae4SSatish Balay } 788dd9472c6SBarry Smith } 789dd9472c6SBarry Smith } 790f1241b54SBarry Smith noinsert2:; 79192c4ed94SBarry Smith low = i; 79292c4ed94SBarry Smith } 79392c4ed94SBarry Smith ailen[row] = nrow; 79492c4ed94SBarry Smith } 7953a40ed3dSBarry Smith PetscFunctionReturn(0); 79692c4ed94SBarry Smith } 79792c4ed94SBarry Smith 798f2501298SSatish Balay 7995615d1e5SSatish Balay #undef __FUNC__ 8005615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ" 8018f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 802584200bdSSatish Balay { 803584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 804584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax; 805a7c10996SSatish Balay int m = a->m,*ip, N, *ailen = a->ilen; 80643ee02c3SBarry Smith int mbs = a->mbs, bs2 = a->bs2,rmax = 0; 807584200bdSSatish Balay Scalar *aa = a->a, *ap; 808584200bdSSatish Balay 8093a40ed3dSBarry Smith PetscFunctionBegin; 8103a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 811584200bdSSatish Balay 81243ee02c3SBarry Smith if (m) rmax = ailen[0]; 813584200bdSSatish Balay for ( i=1; i<mbs; i++ ) { 814584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 815584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 816d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 817584200bdSSatish Balay if (fshift) { 818a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 819584200bdSSatish Balay N = ailen[i]; 820584200bdSSatish Balay for ( j=0; j<N; j++ ) { 821584200bdSSatish Balay ip[j-fshift] = ip[j]; 8227e67e3f9SSatish Balay PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(Scalar)); 823584200bdSSatish Balay } 824584200bdSSatish Balay } 825584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 826584200bdSSatish Balay } 827584200bdSSatish Balay if (mbs) { 828584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 829584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 830584200bdSSatish Balay } 831584200bdSSatish Balay /* reset ilen and imax for each row */ 832584200bdSSatish Balay for ( i=0; i<mbs; i++ ) { 833584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 834584200bdSSatish Balay } 835a7c10996SSatish Balay a->nz = ai[mbs]; 836584200bdSSatish Balay 837584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 838584200bdSSatish Balay if (fshift && a->diag) { 839584200bdSSatish Balay PetscFree(a->diag); 840584200bdSSatish Balay PLogObjectMemory(A,-(m+1)*sizeof(int)); 841584200bdSSatish Balay a->diag = 0; 842584200bdSSatish Balay } 8433d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 844219d9a1aSLois Curfman McInnes m,a->n,a->bs,fshift*bs2,a->nz*bs2); 8453d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 846584200bdSSatish Balay a->reallocs); 847d402145bSBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 848e2f3b5e9SSatish Balay a->reallocs = 0; 8494e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift*bs2; 8504e220ebcSLois Curfman McInnes 8513a40ed3dSBarry Smith PetscFunctionReturn(0); 852584200bdSSatish Balay } 853584200bdSSatish Balay 8545a838052SSatish Balay 855d9b7c43dSSatish Balay /* idx should be of length atlease bs */ 8565615d1e5SSatish Balay #undef __FUNC__ 8575615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Block" 858d9b7c43dSSatish Balay static int MatZeroRows_SeqBAIJ_Check_Block(int *idx, int bs, PetscTruth *flg) 859d9b7c43dSSatish Balay { 860d9b7c43dSSatish Balay int i,row; 8613a40ed3dSBarry Smith 8623a40ed3dSBarry Smith PetscFunctionBegin; 863d9b7c43dSSatish Balay row = idx[0]; 8643a40ed3dSBarry Smith if (row%bs!=0) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 865d9b7c43dSSatish Balay 866d9b7c43dSSatish Balay for ( i=1; i<bs; i++ ) { 8673a40ed3dSBarry Smith if (row+i != idx[i]) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 868d9b7c43dSSatish Balay } 869d9b7c43dSSatish Balay *flg = PETSC_TRUE; 8703a40ed3dSBarry Smith PetscFunctionReturn(0); 871d9b7c43dSSatish Balay } 872d9b7c43dSSatish Balay 8735615d1e5SSatish Balay #undef __FUNC__ 8745615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ" 8758f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag) 876d9b7c43dSSatish Balay { 877d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 878d9b7c43dSSatish Balay IS is_local; 879d9b7c43dSSatish Balay int ierr,i,j,count,m=baij->m,is_n,*is_idx,*rows,bs=baij->bs,bs2=baij->bs2; 880d9b7c43dSSatish Balay PetscTruth flg; 881d9b7c43dSSatish Balay Scalar zero = 0.0,*aa; 882d9b7c43dSSatish Balay 8833a40ed3dSBarry Smith PetscFunctionBegin; 884d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 885d9b7c43dSSatish Balay ierr = ISGetSize(is,&is_n);CHKERRQ(ierr); 886d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 887537820f0SBarry Smith ierr = ISCreateGeneral(A->comm,is_n,is_idx,&is_local); CHKERRQ(ierr); 888d9b7c43dSSatish Balay ierr = ISSort(is_local); CHKERRQ(ierr); 889d9b7c43dSSatish Balay ierr = ISGetIndices(is_local,&rows); CHKERRQ(ierr); 890d9b7c43dSSatish Balay 891d9b7c43dSSatish Balay i = 0; 892d9b7c43dSSatish Balay while (i < is_n) { 893a8c6a408SBarry Smith if (rows[i]<0 || rows[i]>m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 894d9b7c43dSSatish Balay flg = PETSC_FALSE; 895d9b7c43dSSatish Balay if (i+bs <= is_n) {ierr = MatZeroRows_SeqBAIJ_Check_Block(rows+i,bs,&flg); CHKERRQ(ierr); } 896d9b7c43dSSatish Balay count = (baij->i[rows[i]/bs +1] - baij->i[rows[i]/bs])*bs; 897d9b7c43dSSatish Balay aa = baij->a + baij->i[rows[i]/bs]*bs2 + (rows[i]%bs); 8982d61bbb3SSatish Balay if (flg) { /* There exists a block of rows to be Zerowed */ 899a07cd24cSSatish Balay if (baij->ilen[rows[i]/bs] > 0) { 9002d61bbb3SSatish Balay PetscMemzero(aa,count*bs*sizeof(Scalar)); 9012d61bbb3SSatish Balay baij->ilen[rows[i]/bs] = 1; 9022d61bbb3SSatish Balay baij->j[baij->i[rows[i]/bs]] = rows[i]/bs; 903a07cd24cSSatish Balay } 9042d61bbb3SSatish Balay i += bs; 9052d61bbb3SSatish Balay } else { /* Zero out only the requested row */ 906d9b7c43dSSatish Balay for ( j=0; j<count; j++ ) { 907d9b7c43dSSatish Balay aa[0] = zero; 908d9b7c43dSSatish Balay aa+=bs; 909d9b7c43dSSatish Balay } 910d9b7c43dSSatish Balay i++; 911d9b7c43dSSatish Balay } 912d9b7c43dSSatish Balay } 913d9b7c43dSSatish Balay if (diag) { 914d9b7c43dSSatish Balay for ( j=0; j<is_n; j++ ) { 915f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 9162d61bbb3SSatish Balay /* ierr = MatSetValues(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); */ 917d9b7c43dSSatish Balay } 918d9b7c43dSSatish Balay } 919d9b7c43dSSatish Balay ierr = ISRestoreIndices(is,&is_idx); CHKERRQ(ierr); 920d9b7c43dSSatish Balay ierr = ISRestoreIndices(is_local,&rows); CHKERRQ(ierr); 921d9b7c43dSSatish Balay ierr = ISDestroy(is_local); CHKERRQ(ierr); 9229a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 9233a40ed3dSBarry Smith PetscFunctionReturn(0); 924d9b7c43dSSatish Balay } 9251c351548SSatish Balay 9265615d1e5SSatish Balay #undef __FUNC__ 9272d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ" 9282d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9292d61bbb3SSatish Balay { 9302d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 9312d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 9322d61bbb3SSatish Balay int *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 9332d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 9342d61bbb3SSatish Balay int ridx,cidx,bs2=a->bs2; 9352d61bbb3SSatish Balay Scalar *ap,value,*aa=a->a,*bap; 9362d61bbb3SSatish Balay 9372d61bbb3SSatish Balay PetscFunctionBegin; 9382d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over added rows */ 9392d61bbb3SSatish Balay row = im[k]; brow = row/bs; 9402d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9412d61bbb3SSatish Balay if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 9422d61bbb3SSatish Balay if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 9432d61bbb3SSatish Balay #endif 9442d61bbb3SSatish Balay rp = aj + ai[brow]; 9452d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 9462d61bbb3SSatish Balay rmax = imax[brow]; 9472d61bbb3SSatish Balay nrow = ailen[brow]; 9482d61bbb3SSatish Balay low = 0; 9492d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over added columns */ 9502d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9512d61bbb3SSatish Balay if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 9522d61bbb3SSatish Balay if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 9532d61bbb3SSatish Balay #endif 9542d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 9552d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 9562d61bbb3SSatish Balay if (roworiented) { 9572d61bbb3SSatish Balay value = *v++; 9582d61bbb3SSatish Balay } else { 9592d61bbb3SSatish Balay value = v[k + l*m]; 9602d61bbb3SSatish Balay } 9612d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 9622d61bbb3SSatish Balay while (high-low > 7) { 9632d61bbb3SSatish Balay t = (low+high)/2; 9642d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 9652d61bbb3SSatish Balay else low = t; 9662d61bbb3SSatish Balay } 9672d61bbb3SSatish Balay for ( i=low; i<high; i++ ) { 9682d61bbb3SSatish Balay if (rp[i] > bcol) break; 9692d61bbb3SSatish Balay if (rp[i] == bcol) { 9702d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 9712d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 9722d61bbb3SSatish Balay else *bap = value; 9732d61bbb3SSatish Balay goto noinsert1; 9742d61bbb3SSatish Balay } 9752d61bbb3SSatish Balay } 9762d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 9772d61bbb3SSatish Balay else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9782d61bbb3SSatish Balay if (nrow >= rmax) { 9792d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 9802d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 9812d61bbb3SSatish Balay Scalar *new_a; 9822d61bbb3SSatish Balay 9832d61bbb3SSatish Balay if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9842d61bbb3SSatish Balay 9852d61bbb3SSatish Balay /* Malloc new storage space */ 9862d61bbb3SSatish Balay len = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int); 9872d61bbb3SSatish Balay new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 9882d61bbb3SSatish Balay new_j = (int *) (new_a + bs2*new_nz); 9892d61bbb3SSatish Balay new_i = new_j + new_nz; 9902d61bbb3SSatish Balay 9912d61bbb3SSatish Balay /* copy over old data into new slots */ 9922d61bbb3SSatish Balay for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];} 9932d61bbb3SSatish Balay for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 9942d61bbb3SSatish Balay PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int)); 9952d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 9962d61bbb3SSatish Balay PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow, 9972d61bbb3SSatish Balay len*sizeof(int)); 9982d61bbb3SSatish Balay PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(Scalar)); 9992d61bbb3SSatish Balay PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(Scalar)); 10002d61bbb3SSatish Balay PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE), 10012d61bbb3SSatish Balay aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(Scalar)); 10022d61bbb3SSatish Balay /* free up old matrix storage */ 10032d61bbb3SSatish Balay PetscFree(a->a); 10042d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 10052d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 10062d61bbb3SSatish Balay a->singlemalloc = 1; 10072d61bbb3SSatish Balay 10082d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 10092d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 10102d61bbb3SSatish Balay PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar))); 10112d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 10122d61bbb3SSatish Balay a->reallocs++; 10132d61bbb3SSatish Balay a->nz++; 10142d61bbb3SSatish Balay } 10152d61bbb3SSatish Balay N = nrow++ - 1; 10162d61bbb3SSatish Balay /* shift up all the later entries in this row */ 10172d61bbb3SSatish Balay for ( ii=N; ii>=i; ii-- ) { 10182d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 10192d61bbb3SSatish Balay PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar)); 10202d61bbb3SSatish Balay } 10212d61bbb3SSatish Balay if (N>=i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar)); 10222d61bbb3SSatish Balay rp[i] = bcol; 10232d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10242d61bbb3SSatish Balay noinsert1:; 10252d61bbb3SSatish Balay low = i; 10262d61bbb3SSatish Balay } 10272d61bbb3SSatish Balay ailen[brow] = nrow; 10282d61bbb3SSatish Balay } 10292d61bbb3SSatish Balay PetscFunctionReturn(0); 10302d61bbb3SSatish Balay } 10312d61bbb3SSatish Balay 10322d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 10332d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 10342d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 1035d3825aa8SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatGetSubMatrixCall,Mat*); 10362d61bbb3SSatish Balay extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatGetSubMatrixCall,Mat**); 10372d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec); 10382d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 10392d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat); 10402d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *); 10412d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*); 10422d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec); 10432d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 10442d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 10452d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat); 10462d61bbb3SSatish Balay 10472d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 10482d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 10492d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 10502d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 10512d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 10522d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 10532d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 10542d61bbb3SSatish Balay 10552d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 10562d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 10572d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 10582d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 10592d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 10602d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 10612d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4_NaturalOrdering(Mat,Vec,Vec); 10622d61bbb3SSatish Balay 10632d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 10642d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 10652d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 10662d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 10672d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 10682d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 10692d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 10702d61bbb3SSatish Balay 10712d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 10722d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 10732d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 10742d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 10752d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 10762d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 10772d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 10782d61bbb3SSatish Balay 10792d61bbb3SSatish Balay /* 10802d61bbb3SSatish Balay note: This can only work for identity for row and col. It would 10812d61bbb3SSatish Balay be good to check this and otherwise generate an error. 10822d61bbb3SSatish Balay */ 10832d61bbb3SSatish Balay #undef __FUNC__ 10842d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ" 10852d61bbb3SSatish Balay int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill) 10862d61bbb3SSatish Balay { 10872d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 10882d61bbb3SSatish Balay Mat outA; 10892d61bbb3SSatish Balay int ierr; 10902d61bbb3SSatish Balay 10912d61bbb3SSatish Balay PetscFunctionBegin; 10922d61bbb3SSatish Balay if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported"); 10932d61bbb3SSatish Balay 10942d61bbb3SSatish Balay outA = inA; 10952d61bbb3SSatish Balay inA->factor = FACTOR_LU; 10962d61bbb3SSatish Balay a->row = row; 10972d61bbb3SSatish Balay a->col = col; 10982d61bbb3SSatish Balay 1099e51c0b9cSSatish Balay /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 1100e51c0b9cSSatish Balay ierr = ISInvertPermutation(col,&(a->icol)); CHKERRQ(ierr); 11011e4dd532SSatish Balay PLogObjectParent(inA,a->icol); 1102e51c0b9cSSatish Balay 11032d61bbb3SSatish Balay if (!a->solve_work) { 11042d61bbb3SSatish Balay a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work); 11052d61bbb3SSatish Balay PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar)); 11062d61bbb3SSatish Balay } 11072d61bbb3SSatish Balay 11082d61bbb3SSatish Balay if (!a->diag) { 11092d61bbb3SSatish Balay ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 11102d61bbb3SSatish Balay } 11112d61bbb3SSatish Balay ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr); 11122d61bbb3SSatish Balay 11132d61bbb3SSatish Balay /* 11142d61bbb3SSatish Balay Blocksize 4 has a special faster solver for ILU(0) factorization 11152d61bbb3SSatish Balay with natural ordering 11162d61bbb3SSatish Balay */ 11172d61bbb3SSatish Balay if (a->bs == 4) { 1118f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 11192d61bbb3SSatish Balay } 11202d61bbb3SSatish Balay 11212d61bbb3SSatish Balay PetscFunctionReturn(0); 11222d61bbb3SSatish Balay } 11232d61bbb3SSatish Balay #undef __FUNC__ 1124d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ" 1125ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1126ba4ca20aSSatish Balay { 1127ba4ca20aSSatish Balay static int called = 0; 1128ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1129ba4ca20aSSatish Balay 11303a40ed3dSBarry Smith PetscFunctionBegin; 11313a40ed3dSBarry Smith if (called) {PetscFunctionReturn(0);} else called = 1; 113276be9ce4SBarry Smith (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n"); 113376be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n"); 11343a40ed3dSBarry Smith PetscFunctionReturn(0); 1135ba4ca20aSSatish Balay } 1136d9b7c43dSSatish Balay 113727a8da17SBarry Smith #undef __FUNC__ 113827a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 113927a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 114027a8da17SBarry Smith { 114127a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 114227a8da17SBarry Smith int i,nz,n; 114327a8da17SBarry Smith 114427a8da17SBarry Smith PetscFunctionBegin; 114527a8da17SBarry Smith nz = baij->maxnz; 114627a8da17SBarry Smith n = baij->n; 114727a8da17SBarry Smith for (i=0; i<nz; i++) { 114827a8da17SBarry Smith baij->j[i] = indices[i]; 114927a8da17SBarry Smith } 115027a8da17SBarry Smith baij->nz = nz; 115127a8da17SBarry Smith for ( i=0; i<n; i++ ) { 115227a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 115327a8da17SBarry Smith } 115427a8da17SBarry Smith 115527a8da17SBarry Smith PetscFunctionReturn(0); 115627a8da17SBarry Smith } 115727a8da17SBarry Smith 115827a8da17SBarry Smith #undef __FUNC__ 115927a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices" 116027a8da17SBarry Smith /*@ 116127a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 116227a8da17SBarry Smith in the matrix. 116327a8da17SBarry Smith 116427a8da17SBarry Smith Input Parameters: 116527a8da17SBarry Smith + mat - the SeqBAIJ matrix 116627a8da17SBarry Smith - indices - the column indices 116727a8da17SBarry Smith 116827a8da17SBarry Smith Notes: 116927a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 117027a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 117127a8da17SBarry Smith of the MatSetValues() operation. 117227a8da17SBarry Smith 117327a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 117427a8da17SBarry Smith MatCreateSeqBAIJ(). 117527a8da17SBarry Smith 117627a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 117727a8da17SBarry Smith 117827a8da17SBarry Smith @*/ 117927a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 118027a8da17SBarry Smith { 118127a8da17SBarry Smith int ierr,(*f)(Mat,int *); 118227a8da17SBarry Smith 118327a8da17SBarry Smith PetscFunctionBegin; 118427a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 118527a8da17SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f); 118627a8da17SBarry Smith CHKERRQ(ierr); 118727a8da17SBarry Smith if (f) { 118827a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 118927a8da17SBarry Smith } else { 119027a8da17SBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 119127a8da17SBarry Smith } 119227a8da17SBarry Smith PetscFunctionReturn(0); 119327a8da17SBarry Smith } 119427a8da17SBarry Smith 11952593348eSBarry Smith /* -------------------------------------------------------------------*/ 1196*cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1197*cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1198*cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1199*cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1200*cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 1201*cc2dc46cSBarry Smith MatMultTrans_SeqBAIJ, 1202*cc2dc46cSBarry Smith MatMultTransAdd_SeqBAIJ, 1203*cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1204*cc2dc46cSBarry Smith 0, 1205*cc2dc46cSBarry Smith 0, 1206*cc2dc46cSBarry Smith 0, 1207*cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1208*cc2dc46cSBarry Smith 0, 1209b6490206SBarry Smith 0, 1210f2501298SSatish Balay MatTranspose_SeqBAIJ, 1211*cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1212*cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1213*cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1214*cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1215*cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1216b6490206SBarry Smith 0, 1217*cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1218*cc2dc46cSBarry Smith 0, 1219*cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1220*cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1221*cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1222*cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1223*cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1224*cc2dc46cSBarry Smith 0, 1225*cc2dc46cSBarry Smith 0, 1226*cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1227*cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1228*cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1229*cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1230*cc2dc46cSBarry Smith 0, 1231*cc2dc46cSBarry Smith 0, 1232*cc2dc46cSBarry Smith 0, 1233*cc2dc46cSBarry Smith MatConvertSameType_SeqBAIJ, 1234*cc2dc46cSBarry Smith 0, 1235*cc2dc46cSBarry Smith 0, 1236*cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1237*cc2dc46cSBarry Smith 0, 1238*cc2dc46cSBarry Smith 0, 1239*cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1240*cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1241*cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1242*cc2dc46cSBarry Smith 0, 1243*cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1244*cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1245*cc2dc46cSBarry Smith 0, 1246*cc2dc46cSBarry Smith 0, 1247*cc2dc46cSBarry Smith 0, 1248*cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 12493b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 125092c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1251*cc2dc46cSBarry Smith 0, 1252*cc2dc46cSBarry Smith 0, 1253*cc2dc46cSBarry Smith 0, 1254*cc2dc46cSBarry Smith 0, 1255*cc2dc46cSBarry Smith 0, 1256*cc2dc46cSBarry Smith 0, 1257d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1258*cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1259*cc2dc46cSBarry Smith 0, 1260*cc2dc46cSBarry Smith 0, 1261*cc2dc46cSBarry Smith MatGetMaps_Petsc}; 12622593348eSBarry Smith 12635615d1e5SSatish Balay #undef __FUNC__ 12645615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ" 12652593348eSBarry Smith /*@C 126644cd7ae7SLois Curfman McInnes MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 126744cd7ae7SLois Curfman McInnes compressed row) format. For good matrix assembly performance the 126844cd7ae7SLois Curfman McInnes user should preallocate the matrix storage by setting the parameter nz 12692bd5e0b2SLois Curfman McInnes (or the array nzz). By setting these parameters accurately, performance 12702bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 12712593348eSBarry Smith 1272db81eaa0SLois Curfman McInnes Collective on MPI_Comm 1273db81eaa0SLois Curfman McInnes 12742593348eSBarry Smith Input Parameters: 1275db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 1276b6490206SBarry Smith . bs - size of block 12772593348eSBarry Smith . m - number of rows 12782593348eSBarry Smith . n - number of columns 1279b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1280db81eaa0SLois Curfman McInnes - nzz - array containing the number of block nonzeros in the various block rows 12812bd5e0b2SLois Curfman McInnes (possibly different for each block row) or PETSC_NULL 12822593348eSBarry Smith 12832593348eSBarry Smith Output Parameter: 12842593348eSBarry Smith . A - the matrix 12852593348eSBarry Smith 12860513a670SBarry Smith Options Database Keys: 1287db81eaa0SLois Curfman McInnes . -mat_no_unroll - uses code that does not unroll the loops in the 1288db81eaa0SLois Curfman McInnes block calculations (much slower) 1289db81eaa0SLois Curfman McInnes . -mat_block_size - size of the blocks to use 12900513a670SBarry Smith 12912593348eSBarry Smith Notes: 129244cd7ae7SLois Curfman McInnes The block AIJ format is fully compatible with standard Fortran 77 12932593348eSBarry Smith storage. That is, the stored row and column indices can begin at 129444cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 12952593348eSBarry Smith 12962593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 12972593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 12982593348eSBarry Smith allocation. For additional details, see the users manual chapter on 12996da5968aSLois Curfman McInnes matrices. 13002593348eSBarry Smith 1301db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 13022593348eSBarry Smith @*/ 1303b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 13042593348eSBarry Smith { 13052593348eSBarry Smith Mat B; 1306b6490206SBarry Smith Mat_SeqBAIJ *b; 13073b2fbd54SBarry Smith int i,len,ierr,flg,mbs=m/bs,nbs=n/bs,bs2=bs*bs,size; 13083b2fbd54SBarry Smith 13093a40ed3dSBarry Smith PetscFunctionBegin; 13103b2fbd54SBarry Smith MPI_Comm_size(comm,&size); 1311a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1"); 1312b6490206SBarry Smith 13130513a670SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 13140513a670SBarry Smith 13153a40ed3dSBarry Smith if (mbs*bs!=m || nbs*bs!=n) { 1316a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize"); 13173a40ed3dSBarry Smith } 13182593348eSBarry Smith 13192593348eSBarry Smith *A = 0; 1320f830108cSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,comm,MatDestroy,MatView); 13212593348eSBarry Smith PLogObjectCreate(B); 1322b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 132344cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_SeqBAIJ)); 1324*cc2dc46cSBarry Smith PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); 13251a6a6d98SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg); CHKERRQ(ierr); 13261a6a6d98SBarry Smith if (!flg) { 13277fc0212eSBarry Smith switch (bs) { 13287fc0212eSBarry Smith case 1: 1329f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1330f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1331f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1332f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 13337fc0212eSBarry Smith break; 13344eeb42bcSBarry Smith case 2: 1335f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1336f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1337f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1338f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 13396d84be18SBarry Smith break; 1340f327dd97SBarry Smith case 3: 1341f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1342f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1343f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1344f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 13454eeb42bcSBarry Smith break; 13466d84be18SBarry Smith case 4: 1347f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1348f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1349f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1350f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 13516d84be18SBarry Smith break; 13526d84be18SBarry Smith case 5: 1353f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1354f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1355f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1356f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 13576d84be18SBarry Smith break; 135848e9ddb2SSatish Balay case 7: 1359f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1360f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1361f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 136248e9ddb2SSatish Balay break; 13637fc0212eSBarry Smith } 13641a6a6d98SBarry Smith } 1365e1311b90SBarry Smith B->ops->destroy = MatDestroy_SeqBAIJ; 1366e1311b90SBarry Smith B->ops->view = MatView_SeqBAIJ; 13672593348eSBarry Smith B->factor = 0; 13682593348eSBarry Smith B->lupivotthreshold = 1.0; 136990f02eecSBarry Smith B->mapping = 0; 13702593348eSBarry Smith b->row = 0; 13712593348eSBarry Smith b->col = 0; 1372e51c0b9cSSatish Balay b->icol = 0; 13732593348eSBarry Smith b->reallocs = 0; 13742593348eSBarry Smith 137544cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 137644cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 1377b6490206SBarry Smith b->mbs = mbs; 1378f2501298SSatish Balay b->nbs = nbs; 1379b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 13802593348eSBarry Smith if (nnz == PETSC_NULL) { 1381119a934aSSatish Balay if (nz == PETSC_DEFAULT) nz = 5; 13822593348eSBarry Smith else if (nz <= 0) nz = 1; 1383b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 1384b6490206SBarry Smith nz = nz*mbs; 13853a40ed3dSBarry Smith } else { 13862593348eSBarry Smith nz = 0; 1387b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 13882593348eSBarry Smith } 13892593348eSBarry Smith 13902593348eSBarry Smith /* allocate the matrix space */ 13917e67e3f9SSatish Balay len = nz*sizeof(int) + nz*bs2*sizeof(Scalar) + (b->m+1)*sizeof(int); 13922593348eSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 13937e67e3f9SSatish Balay PetscMemzero(b->a,nz*bs2*sizeof(Scalar)); 13947e67e3f9SSatish Balay b->j = (int *) (b->a + nz*bs2); 13952593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 13962593348eSBarry Smith b->i = b->j + nz; 13972593348eSBarry Smith b->singlemalloc = 1; 13982593348eSBarry Smith 1399de6a44a3SBarry Smith b->i[0] = 0; 1400b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 14012593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 14022593348eSBarry Smith } 14032593348eSBarry Smith 1404b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 1405b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 1406f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1407b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 14082593348eSBarry Smith 1409b6490206SBarry Smith b->bs = bs; 14109df24120SSatish Balay b->bs2 = bs2; 1411b6490206SBarry Smith b->mbs = mbs; 14122593348eSBarry Smith b->nz = 0; 141318e7b8e4SLois Curfman McInnes b->maxnz = nz*bs2; 14142593348eSBarry Smith b->sorted = 0; 14152593348eSBarry Smith b->roworiented = 1; 14162593348eSBarry Smith b->nonew = 0; 14172593348eSBarry Smith b->diag = 0; 14182593348eSBarry Smith b->solve_work = 0; 1419de6a44a3SBarry Smith b->mult_work = 0; 14202593348eSBarry Smith b->spptr = 0; 14214e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 14224e220ebcSLois Curfman McInnes 14232593348eSBarry Smith *A = B; 14242593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 14252593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 142627a8da17SBarry Smith 142727a8da17SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 142827a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 142927a8da17SBarry Smith (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 143027a8da17SBarry Smith 14313a40ed3dSBarry Smith PetscFunctionReturn(0); 14322593348eSBarry Smith } 14332593348eSBarry Smith 14345615d1e5SSatish Balay #undef __FUNC__ 14355615d1e5SSatish Balay #define __FUNC__ "MatConvertSameType_SeqBAIJ" 1436b6490206SBarry Smith int MatConvertSameType_SeqBAIJ(Mat A,Mat *B,int cpvalues) 14372593348eSBarry Smith { 14382593348eSBarry Smith Mat C; 1439b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 144027a8da17SBarry Smith int i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1441de6a44a3SBarry Smith 14423a40ed3dSBarry Smith PetscFunctionBegin; 1443a8c6a408SBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix"); 14442593348eSBarry Smith 14452593348eSBarry Smith *B = 0; 1446f830108cSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,A->comm,MatDestroy,MatView); 14472593348eSBarry Smith PLogObjectCreate(C); 1448b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 1449c3c66ee5SSatish Balay PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps)); 1450e1311b90SBarry Smith C->ops->destroy = MatDestroy_SeqBAIJ; 1451e1311b90SBarry Smith C->ops->view = MatView_SeqBAIJ; 14522593348eSBarry Smith C->factor = A->factor; 14532593348eSBarry Smith c->row = 0; 14542593348eSBarry Smith c->col = 0; 14552593348eSBarry Smith C->assembled = PETSC_TRUE; 14562593348eSBarry Smith 145744cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 145844cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 145944cd7ae7SLois Curfman McInnes C->M = a->m; 146044cd7ae7SLois Curfman McInnes C->N = a->n; 146144cd7ae7SLois Curfman McInnes 1462b6490206SBarry Smith c->bs = a->bs; 14639df24120SSatish Balay c->bs2 = a->bs2; 1464b6490206SBarry Smith c->mbs = a->mbs; 1465b6490206SBarry Smith c->nbs = a->nbs; 14662593348eSBarry Smith 1467b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 1468b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 1469b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 14702593348eSBarry Smith c->imax[i] = a->imax[i]; 14712593348eSBarry Smith c->ilen[i] = a->ilen[i]; 14722593348eSBarry Smith } 14732593348eSBarry Smith 14742593348eSBarry Smith /* allocate the matrix space */ 14752593348eSBarry Smith c->singlemalloc = 1; 14767e67e3f9SSatish Balay len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(Scalar) + sizeof(int)); 14772593348eSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 14787e67e3f9SSatish Balay c->j = (int *) (c->a + nz*bs2); 1479de6a44a3SBarry Smith c->i = c->j + nz; 1480b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 1481b6490206SBarry Smith if (mbs > 0) { 1482de6a44a3SBarry Smith PetscMemcpy(c->j,a->j,nz*sizeof(int)); 14832593348eSBarry Smith if (cpvalues == COPY_VALUES) { 14847e67e3f9SSatish Balay PetscMemcpy(c->a,a->a,bs2*nz*sizeof(Scalar)); 14852593348eSBarry Smith } 14862593348eSBarry Smith } 14872593348eSBarry Smith 1488f09e8eb9SSatish Balay PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 14892593348eSBarry Smith c->sorted = a->sorted; 14902593348eSBarry Smith c->roworiented = a->roworiented; 14912593348eSBarry Smith c->nonew = a->nonew; 14922593348eSBarry Smith 14932593348eSBarry Smith if (a->diag) { 1494b6490206SBarry Smith c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag); 1495b6490206SBarry Smith PLogObjectMemory(C,(mbs+1)*sizeof(int)); 1496b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 14972593348eSBarry Smith c->diag[i] = a->diag[i]; 14982593348eSBarry Smith } 14992593348eSBarry Smith } 15002593348eSBarry Smith else c->diag = 0; 15012593348eSBarry Smith c->nz = a->nz; 15022593348eSBarry Smith c->maxnz = a->maxnz; 15032593348eSBarry Smith c->solve_work = 0; 15042593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 15057fc0212eSBarry Smith c->mult_work = 0; 15062593348eSBarry Smith *B = C; 150727a8da17SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)C,"MatSeqBAIJSetColumnIndices_C", 150827a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 150927a8da17SBarry Smith (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 15103a40ed3dSBarry Smith PetscFunctionReturn(0); 15112593348eSBarry Smith } 15122593348eSBarry Smith 15135615d1e5SSatish Balay #undef __FUNC__ 15145615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ" 151519bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A) 15162593348eSBarry Smith { 1517b6490206SBarry Smith Mat_SeqBAIJ *a; 15182593348eSBarry Smith Mat B; 1519de6a44a3SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg; 1520b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 152135aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1522a7c10996SSatish Balay int *masked, nmask,tmp,bs2,ishift; 1523b6490206SBarry Smith Scalar *aa; 152419bcc07fSBarry Smith MPI_Comm comm = ((PetscObject) viewer)->comm; 15252593348eSBarry Smith 15263a40ed3dSBarry Smith PetscFunctionBegin; 15271a6a6d98SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,&flg);CHKERRQ(ierr); 1528de6a44a3SBarry Smith bs2 = bs*bs; 1529b6490206SBarry Smith 15302593348eSBarry Smith MPI_Comm_size(comm,&size); 1531cc0fae11SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor"); 153290ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 15330752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr); 1534a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object"); 15352593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 15362593348eSBarry Smith 1537d64ed03dSBarry Smith if (header[3] < 0) { 1538a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ"); 1539d64ed03dSBarry Smith } 1540d64ed03dSBarry Smith 1541a8c6a408SBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices"); 154235aab85fSBarry Smith 154335aab85fSBarry Smith /* 154435aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 154535aab85fSBarry Smith divisible by the blocksize 154635aab85fSBarry Smith */ 1547b6490206SBarry Smith mbs = M/bs; 154835aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 154935aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 155035aab85fSBarry Smith else mbs++; 155135aab85fSBarry Smith if (extra_rows) { 1552537820f0SBarry Smith PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 155335aab85fSBarry Smith } 1554b6490206SBarry Smith 15552593348eSBarry Smith /* read in row lengths */ 155635aab85fSBarry Smith rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths); 15570752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr); 155835aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1; 15592593348eSBarry Smith 1560b6490206SBarry Smith /* read in column indices */ 156135aab85fSBarry Smith jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj); 15620752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT); CHKERRQ(ierr); 156335aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i; 1564b6490206SBarry Smith 1565b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1566b6490206SBarry Smith browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths); 1567b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 156835aab85fSBarry Smith mask = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask); 156935aab85fSBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 157035aab85fSBarry Smith masked = mask + mbs; 1571b6490206SBarry Smith rowcount = 0; nzcount = 0; 1572b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 157335aab85fSBarry Smith nmask = 0; 1574b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1575b6490206SBarry Smith kmax = rowlengths[rowcount]; 1576b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 157735aab85fSBarry Smith tmp = jj[nzcount++]/bs; 157835aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1579b6490206SBarry Smith } 1580b6490206SBarry Smith rowcount++; 1581b6490206SBarry Smith } 158235aab85fSBarry Smith browlengths[i] += nmask; 158335aab85fSBarry Smith /* zero out the mask elements we set */ 158435aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1585b6490206SBarry Smith } 1586b6490206SBarry Smith 15872593348eSBarry Smith /* create our matrix */ 15883eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 15892593348eSBarry Smith B = *A; 1590b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 15912593348eSBarry Smith 15922593348eSBarry Smith /* set matrix "i" values */ 1593de6a44a3SBarry Smith a->i[0] = 0; 1594b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 1595b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1596b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 15972593348eSBarry Smith } 1598b6490206SBarry Smith a->nz = 0; 1599b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 16002593348eSBarry Smith 1601b6490206SBarry Smith /* read in nonzero values */ 160235aab85fSBarry Smith aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa); 16030752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR); CHKERRQ(ierr); 160435aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0; 1605b6490206SBarry Smith 1606b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1607b6490206SBarry Smith nzcount = 0; jcount = 0; 1608b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 1609b6490206SBarry Smith nzcountb = nzcount; 161035aab85fSBarry Smith nmask = 0; 1611b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1612b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1613b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 161435aab85fSBarry Smith tmp = jj[nzcount++]/bs; 161535aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1616b6490206SBarry Smith } 1617b6490206SBarry Smith rowcount++; 1618b6490206SBarry Smith } 1619de6a44a3SBarry Smith /* sort the masked values */ 162077c4ece6SBarry Smith PetscSortInt(nmask,masked); 1621de6a44a3SBarry Smith 1622b6490206SBarry Smith /* set "j" values into matrix */ 1623b6490206SBarry Smith maskcount = 1; 162435aab85fSBarry Smith for ( j=0; j<nmask; j++ ) { 162535aab85fSBarry Smith a->j[jcount++] = masked[j]; 1626de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1627b6490206SBarry Smith } 1628b6490206SBarry Smith /* set "a" values into matrix */ 1629de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1630b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1631b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1632b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 1633de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1634de6a44a3SBarry Smith block = mask[tmp] - 1; 1635de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1636de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1637b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 1638b6490206SBarry Smith } 1639b6490206SBarry Smith } 164035aab85fSBarry Smith /* zero out the mask elements we set */ 164135aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1642b6490206SBarry Smith } 1643a8c6a408SBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix"); 1644b6490206SBarry Smith 1645b6490206SBarry Smith PetscFree(rowlengths); 1646b6490206SBarry Smith PetscFree(browlengths); 1647b6490206SBarry Smith PetscFree(aa); 1648b6490206SBarry Smith PetscFree(jj); 1649b6490206SBarry Smith PetscFree(mask); 1650b6490206SBarry Smith 1651b6490206SBarry Smith B->assembled = PETSC_TRUE; 1652de6a44a3SBarry Smith 16539c01be13SBarry Smith ierr = MatView_Private(B); CHKERRQ(ierr); 16543a40ed3dSBarry Smith PetscFunctionReturn(0); 16552593348eSBarry Smith } 16562593348eSBarry Smith 16572593348eSBarry Smith 16582593348eSBarry Smith 1659