1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*7dce120fSSatish Balay static char vcid[] = "$Id: baij.c,v 1.148 1998/12/03 04:01:06 bsmith Exp balay $"; 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 #include "sys.h" 1070f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h" 111a6a6d98SBarry Smith #include "src/vec/vecimpl.h" 121a6a6d98SBarry Smith #include "src/inline/spops.h" 133b547af2SSatish Balay 142d61bbb3SSatish Balay #define CHUNKSIZE 10 15de6a44a3SBarry Smith 165615d1e5SSatish Balay #undef __FUNC__ 175615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqBAIJ" 18de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A) 19de6a44a3SBarry Smith { 20de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 217fc0212eSBarry Smith int i,j, *diag, m = a->mbs; 22de6a44a3SBarry Smith 233a40ed3dSBarry Smith PetscFunctionBegin; 24de6a44a3SBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 25de6a44a3SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 267fc0212eSBarry Smith for ( i=0; i<m; i++ ) { 27ecc615b2SBarry Smith diag[i] = a->i[i+1]; 28de6a44a3SBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 29de6a44a3SBarry Smith if (a->j[j] == i) { 30de6a44a3SBarry Smith diag[i] = j; 31de6a44a3SBarry Smith break; 32de6a44a3SBarry Smith } 33de6a44a3SBarry Smith } 34de6a44a3SBarry Smith } 35de6a44a3SBarry Smith a->diag = diag; 363a40ed3dSBarry Smith PetscFunctionReturn(0); 37de6a44a3SBarry Smith } 382593348eSBarry Smith 392593348eSBarry Smith 403b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 413b2fbd54SBarry Smith 425615d1e5SSatish Balay #undef __FUNC__ 435615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqBAIJ" 443b2fbd54SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 453b2fbd54SBarry Smith PetscTruth *done) 463b2fbd54SBarry Smith { 473b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 483b2fbd54SBarry Smith int ierr, n = a->mbs,i; 493b2fbd54SBarry Smith 503a40ed3dSBarry Smith PetscFunctionBegin; 513b2fbd54SBarry Smith *nn = n; 523a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 533b2fbd54SBarry Smith if (symmetric) { 543b2fbd54SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 553b2fbd54SBarry Smith } else if (oshift == 1) { 563b2fbd54SBarry Smith /* temporarily add 1 to i and j indices */ 573b2fbd54SBarry Smith int nz = a->i[n] + 1; 583b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]++; 593b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]++; 603b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 613b2fbd54SBarry Smith } else { 623b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 633b2fbd54SBarry Smith } 643b2fbd54SBarry Smith 653a40ed3dSBarry Smith PetscFunctionReturn(0); 663b2fbd54SBarry Smith } 673b2fbd54SBarry Smith 685615d1e5SSatish Balay #undef __FUNC__ 69d4bb536fSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ" 703b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 713b2fbd54SBarry Smith PetscTruth *done) 723b2fbd54SBarry Smith { 733b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 743b2fbd54SBarry Smith int i,n = a->mbs; 753b2fbd54SBarry Smith 763a40ed3dSBarry Smith PetscFunctionBegin; 773a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 783b2fbd54SBarry Smith if (symmetric) { 793b2fbd54SBarry Smith PetscFree(*ia); 803b2fbd54SBarry Smith PetscFree(*ja); 81af5da2bfSBarry Smith } else if (oshift == 1) { 823b2fbd54SBarry Smith int nz = a->i[n]; 833b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]--; 843b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]--; 853b2fbd54SBarry Smith } 863a40ed3dSBarry Smith PetscFunctionReturn(0); 873b2fbd54SBarry Smith } 883b2fbd54SBarry Smith 892d61bbb3SSatish Balay #undef __FUNC__ 902d61bbb3SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqBAIJ" 912d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat, int *bs) 922d61bbb3SSatish Balay { 932d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *) mat->data; 942d61bbb3SSatish Balay 952d61bbb3SSatish Balay PetscFunctionBegin; 962d61bbb3SSatish Balay *bs = baij->bs; 972d61bbb3SSatish Balay PetscFunctionReturn(0); 982d61bbb3SSatish Balay } 992d61bbb3SSatish Balay 1002d61bbb3SSatish Balay 1012d61bbb3SSatish Balay #undef __FUNC__ 1022d61bbb3SSatish Balay #define __FUNC__ "MatDestroy_SeqBAIJ" 103e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A) 1042d61bbb3SSatish Balay { 1052d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 106e51c0b9cSSatish Balay int ierr; 1072d61bbb3SSatish Balay 10894d884c6SBarry Smith if (--A->refct > 0) PetscFunctionReturn(0); 10994d884c6SBarry Smith 11094d884c6SBarry Smith if (A->mapping) { 11194d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping); CHKERRQ(ierr); 11294d884c6SBarry Smith } 11394d884c6SBarry Smith if (A->bmapping) { 11494d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->bmapping); CHKERRQ(ierr); 11594d884c6SBarry Smith } 11661b13de0SBarry Smith if (A->rmap) { 11761b13de0SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 11861b13de0SBarry Smith } 11961b13de0SBarry Smith if (A->cmap) { 12061b13de0SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 12161b13de0SBarry Smith } 1222d61bbb3SSatish Balay #if defined(USE_PETSC_LOG) 123e1311b90SBarry Smith PLogObjectState((PetscObject) A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 1242d61bbb3SSatish Balay #endif 1252d61bbb3SSatish Balay PetscFree(a->a); 1262d61bbb3SSatish Balay if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 1272d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 1282d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 1292d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 1302d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 1312d61bbb3SSatish Balay if (a->mult_work) PetscFree(a->mult_work); 132e51c0b9cSSatish Balay if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 1332d61bbb3SSatish Balay PetscFree(a); 1342d61bbb3SSatish Balay PLogObjectDestroy(A); 1352d61bbb3SSatish Balay PetscHeaderDestroy(A); 1362d61bbb3SSatish Balay PetscFunctionReturn(0); 1372d61bbb3SSatish Balay } 1382d61bbb3SSatish Balay 1392d61bbb3SSatish Balay #undef __FUNC__ 1402d61bbb3SSatish Balay #define __FUNC__ "MatSetOption_SeqBAIJ" 1412d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1422d61bbb3SSatish Balay { 1432d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1442d61bbb3SSatish Balay 1452d61bbb3SSatish Balay PetscFunctionBegin; 1462d61bbb3SSatish Balay if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 1472d61bbb3SSatish Balay else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 1482d61bbb3SSatish Balay else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 1492d61bbb3SSatish Balay else if (op == MAT_COLUMNS_UNSORTED) a->sorted = 0; 1502d61bbb3SSatish Balay else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 1512d61bbb3SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERROR) a->nonew = -1; 1522d61bbb3SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERROR) a->nonew = -2; 1532d61bbb3SSatish Balay else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 1542d61bbb3SSatish Balay else if (op == MAT_ROWS_SORTED || 1552d61bbb3SSatish Balay op == MAT_ROWS_UNSORTED || 1562d61bbb3SSatish Balay op == MAT_SYMMETRIC || 1572d61bbb3SSatish Balay op == MAT_STRUCTURALLY_SYMMETRIC || 1582d61bbb3SSatish Balay op == MAT_YES_NEW_DIAGONALS || 159b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES || 160b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) { 161981c4779SBarry Smith PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 1622d61bbb3SSatish Balay } else if (op == MAT_NO_NEW_DIAGONALS) { 1632d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 1642d61bbb3SSatish Balay } else { 1652d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 1662d61bbb3SSatish Balay } 1672d61bbb3SSatish Balay PetscFunctionReturn(0); 1682d61bbb3SSatish Balay } 1692d61bbb3SSatish Balay 1702d61bbb3SSatish Balay 1712d61bbb3SSatish Balay #undef __FUNC__ 1722d61bbb3SSatish Balay #define __FUNC__ "MatGetSize_SeqBAIJ" 1732d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n) 1742d61bbb3SSatish Balay { 1752d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1762d61bbb3SSatish Balay 1772d61bbb3SSatish Balay PetscFunctionBegin; 1782d61bbb3SSatish Balay if (m) *m = a->m; 1792d61bbb3SSatish Balay if (n) *n = a->n; 1802d61bbb3SSatish Balay PetscFunctionReturn(0); 1812d61bbb3SSatish Balay } 1822d61bbb3SSatish Balay 1832d61bbb3SSatish Balay #undef __FUNC__ 1842d61bbb3SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ" 1852d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 1862d61bbb3SSatish Balay { 1872d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1882d61bbb3SSatish Balay 1892d61bbb3SSatish Balay PetscFunctionBegin; 1902d61bbb3SSatish Balay *m = 0; *n = a->m; 1912d61bbb3SSatish Balay PetscFunctionReturn(0); 1922d61bbb3SSatish Balay } 1932d61bbb3SSatish Balay 1942d61bbb3SSatish Balay #undef __FUNC__ 1952d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ" 1962d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 1972d61bbb3SSatish Balay { 1982d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1992d61bbb3SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2; 2002d61bbb3SSatish Balay Scalar *aa,*v_i,*aa_i; 2012d61bbb3SSatish Balay 2022d61bbb3SSatish Balay PetscFunctionBegin; 2032d61bbb3SSatish Balay bs = a->bs; 2042d61bbb3SSatish Balay ai = a->i; 2052d61bbb3SSatish Balay aj = a->j; 2062d61bbb3SSatish Balay aa = a->a; 2072d61bbb3SSatish Balay bs2 = a->bs2; 2082d61bbb3SSatish Balay 2092d61bbb3SSatish Balay if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 2102d61bbb3SSatish Balay 2112d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2122d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2132d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2142d61bbb3SSatish Balay *nz = bs*M; 2152d61bbb3SSatish Balay 2162d61bbb3SSatish Balay if (v) { 2172d61bbb3SSatish Balay *v = 0; 2182d61bbb3SSatish Balay if (*nz) { 2192d61bbb3SSatish Balay *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v); 2202d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2212d61bbb3SSatish Balay v_i = *v + i*bs; 2222d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2232d61bbb3SSatish Balay for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];} 2242d61bbb3SSatish Balay } 2252d61bbb3SSatish Balay } 2262d61bbb3SSatish Balay } 2272d61bbb3SSatish Balay 2282d61bbb3SSatish Balay if (idx) { 2292d61bbb3SSatish Balay *idx = 0; 2302d61bbb3SSatish Balay if (*nz) { 2312d61bbb3SSatish Balay *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 2322d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2332d61bbb3SSatish Balay idx_i = *idx + i*bs; 2342d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2352d61bbb3SSatish Balay for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;} 2362d61bbb3SSatish Balay } 2372d61bbb3SSatish Balay } 2382d61bbb3SSatish Balay } 2392d61bbb3SSatish Balay PetscFunctionReturn(0); 2402d61bbb3SSatish Balay } 2412d61bbb3SSatish Balay 2422d61bbb3SSatish Balay #undef __FUNC__ 2432d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ" 2442d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2452d61bbb3SSatish Balay { 2462d61bbb3SSatish Balay PetscFunctionBegin; 2472d61bbb3SSatish Balay if (idx) {if (*idx) PetscFree(*idx);} 2482d61bbb3SSatish Balay if (v) {if (*v) PetscFree(*v);} 2492d61bbb3SSatish Balay PetscFunctionReturn(0); 2502d61bbb3SSatish Balay } 2512d61bbb3SSatish Balay 2522d61bbb3SSatish Balay #undef __FUNC__ 2532d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ" 2542d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2552d61bbb3SSatish Balay { 2562d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2572d61bbb3SSatish Balay Mat C; 2582d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 2592d61bbb3SSatish Balay int *rows,*cols,bs2=a->bs2; 2602d61bbb3SSatish Balay Scalar *array=a->a; 2612d61bbb3SSatish Balay 2622d61bbb3SSatish Balay PetscFunctionBegin; 2632d61bbb3SSatish Balay if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place"); 2642d61bbb3SSatish Balay col = (int *) PetscMalloc((1+nbs)*sizeof(int)); CHKPTRQ(col); 2652d61bbb3SSatish Balay PetscMemzero(col,(1+nbs)*sizeof(int)); 2662d61bbb3SSatish Balay 2672d61bbb3SSatish Balay for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1; 2682d61bbb3SSatish Balay ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C); CHKERRQ(ierr); 2692d61bbb3SSatish Balay PetscFree(col); 2702d61bbb3SSatish Balay rows = (int *) PetscMalloc(2*bs*sizeof(int)); CHKPTRQ(rows); 2712d61bbb3SSatish Balay cols = rows + bs; 2722d61bbb3SSatish Balay for ( i=0; i<mbs; i++ ) { 2732d61bbb3SSatish Balay cols[0] = i*bs; 2742d61bbb3SSatish Balay for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1; 2752d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 2762d61bbb3SSatish Balay for ( j=0; j<len; j++ ) { 2772d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 2782d61bbb3SSatish Balay for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1; 2792d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES); CHKERRQ(ierr); 2802d61bbb3SSatish Balay array += bs2; 2812d61bbb3SSatish Balay } 2822d61bbb3SSatish Balay } 2832d61bbb3SSatish Balay PetscFree(rows); 2842d61bbb3SSatish Balay 2852d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2862d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2872d61bbb3SSatish Balay 2882d61bbb3SSatish Balay if (B != PETSC_NULL) { 2892d61bbb3SSatish Balay *B = C; 2902d61bbb3SSatish Balay } else { 291f830108cSBarry Smith PetscOps *Abops; 292cc2dc46cSBarry Smith MatOps Aops; 293f830108cSBarry Smith 2942d61bbb3SSatish Balay /* This isn't really an in-place transpose */ 2952d61bbb3SSatish Balay PetscFree(a->a); 2962d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);} 2972d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 2982d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 2992d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 3002d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 3012d61bbb3SSatish Balay PetscFree(a); 302f830108cSBarry Smith 3037413bad6SBarry Smith 3047413bad6SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 3057413bad6SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 3067413bad6SBarry Smith 307f830108cSBarry Smith /* 308f830108cSBarry Smith This is horrible, horrible code. We need to keep the 309f830108cSBarry Smith A pointers for the bops and ops but copy everything 310f830108cSBarry Smith else from C. 311f830108cSBarry Smith */ 312f830108cSBarry Smith Abops = A->bops; 313f830108cSBarry Smith Aops = A->ops; 3142d61bbb3SSatish Balay PetscMemcpy(A,C,sizeof(struct _p_Mat)); 315f830108cSBarry Smith A->bops = Abops; 316f830108cSBarry Smith A->ops = Aops; 31727a8da17SBarry Smith A->qlist = 0; 318f830108cSBarry Smith 3192d61bbb3SSatish Balay PetscHeaderDestroy(C); 3202d61bbb3SSatish Balay } 3212d61bbb3SSatish Balay PetscFunctionReturn(0); 3222d61bbb3SSatish Balay } 3232d61bbb3SSatish Balay 3242d61bbb3SSatish Balay 3252d61bbb3SSatish Balay 3263b2fbd54SBarry Smith 3275615d1e5SSatish Balay #undef __FUNC__ 328d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary" 329b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer) 3302593348eSBarry Smith { 331b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3329df24120SSatish Balay int i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 333b6490206SBarry Smith Scalar *aa; 3342593348eSBarry Smith 3353a40ed3dSBarry Smith PetscFunctionBegin; 33690ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 3372593348eSBarry Smith col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 3382593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3393b2fbd54SBarry Smith 3402593348eSBarry Smith col_lens[1] = a->m; 3412593348eSBarry Smith col_lens[2] = a->n; 3427e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3432593348eSBarry Smith 3442593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 345b6490206SBarry Smith count = 0; 346b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 347b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 348b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 349b6490206SBarry Smith } 3502593348eSBarry Smith } 3510752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr); 3522593348eSBarry Smith PetscFree(col_lens); 3532593348eSBarry Smith 3542593348eSBarry Smith /* store column indices (zero start index) */ 35566963ce1SSatish Balay jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) ); CHKPTRQ(jj); 356b6490206SBarry Smith count = 0; 357b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 358b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 359b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 360b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 361b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3622593348eSBarry Smith } 3632593348eSBarry Smith } 364b6490206SBarry Smith } 365b6490206SBarry Smith } 3660752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0); CHKERRQ(ierr); 367b6490206SBarry Smith PetscFree(jj); 3682593348eSBarry Smith 3692593348eSBarry Smith /* store nonzero values */ 37066963ce1SSatish Balay aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar)); CHKPTRQ(aa); 371b6490206SBarry Smith count = 0; 372b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 373b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 374b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 375b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 3767e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 377b6490206SBarry Smith } 378b6490206SBarry Smith } 379b6490206SBarry Smith } 380b6490206SBarry Smith } 3810752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0); CHKERRQ(ierr); 382b6490206SBarry Smith PetscFree(aa); 3833a40ed3dSBarry Smith PetscFunctionReturn(0); 3842593348eSBarry Smith } 3852593348eSBarry Smith 3865615d1e5SSatish Balay #undef __FUNC__ 387d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII" 388b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer) 3892593348eSBarry Smith { 390b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3919df24120SSatish Balay int ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2; 3922593348eSBarry Smith FILE *fd; 3932593348eSBarry Smith char *outputname; 3942593348eSBarry Smith 3953a40ed3dSBarry Smith PetscFunctionBegin; 39690ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 39777ed5343SBarry Smith ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr); 39890ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 399639f9d9dSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) { 4007ddc982cSLois Curfman McInnes fprintf(fd," block size is %d\n",bs); 4012593348eSBarry Smith } 402639f9d9dSBarry Smith else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 403a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported"); 4042593348eSBarry Smith } 405639f9d9dSBarry Smith else if (format == VIEWER_FORMAT_ASCII_COMMON) { 40644cd7ae7SLois Curfman McInnes for ( i=0; i<a->mbs; i++ ) { 40744cd7ae7SLois Curfman McInnes for ( j=0; j<bs; j++ ) { 40844cd7ae7SLois Curfman McInnes fprintf(fd,"row %d:",i*bs+j); 40944cd7ae7SLois Curfman McInnes for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 41044cd7ae7SLois Curfman McInnes for ( l=0; l<bs; l++ ) { 4113a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 412e20fef11SSatish Balay if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) 41344cd7ae7SLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 414e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j])); 415e20fef11SSatish Balay else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) 416766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 417e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 418e20fef11SSatish Balay else if (PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) 419e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 42044cd7ae7SLois Curfman McInnes #else 42144cd7ae7SLois Curfman McInnes if (a->a[bs2*k + l*bs + j] != 0.0) 42244cd7ae7SLois Curfman McInnes fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 42344cd7ae7SLois Curfman McInnes #endif 42444cd7ae7SLois Curfman McInnes } 42544cd7ae7SLois Curfman McInnes } 42644cd7ae7SLois Curfman McInnes fprintf(fd,"\n"); 42744cd7ae7SLois Curfman McInnes } 42844cd7ae7SLois Curfman McInnes } 42944cd7ae7SLois Curfman McInnes } 4302593348eSBarry Smith else { 431b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 432b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 433b6490206SBarry Smith fprintf(fd,"row %d:",i*bs+j); 434b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 435b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 4363a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 437e20fef11SSatish Balay if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0) { 43888685aaeSLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 439e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j])); 44088685aaeSLois Curfman McInnes } 441e20fef11SSatish Balay else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0) { 442766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 443e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 444766eeae4SLois Curfman McInnes } 44588685aaeSLois Curfman McInnes else { 446e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 44788685aaeSLois Curfman McInnes } 44888685aaeSLois Curfman McInnes #else 4497e67e3f9SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 45088685aaeSLois Curfman McInnes #endif 4512593348eSBarry Smith } 4522593348eSBarry Smith } 4532593348eSBarry Smith fprintf(fd,"\n"); 4542593348eSBarry Smith } 4552593348eSBarry Smith } 456b6490206SBarry Smith } 4572593348eSBarry Smith fflush(fd); 4583a40ed3dSBarry Smith PetscFunctionReturn(0); 4592593348eSBarry Smith } 4602593348eSBarry Smith 4615615d1e5SSatish Balay #undef __FUNC__ 46277ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom" 46377ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa) 4643270192aSSatish Balay { 46577ed5343SBarry Smith Mat A = (Mat) Aa; 4663270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *) A->data; 467*7dce120fSSatish Balay int row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2,rank; 468*7dce120fSSatish Balay double xl,yl,xr,yr,yc,x_l,x_r,y_l,y_r; 4693270192aSSatish Balay Scalar *aa; 4703270192aSSatish Balay PetscTruth isnull; 47177ed5343SBarry Smith MPI_Comm comm; 47277ed5343SBarry Smith Viewer viewer; 4733270192aSSatish Balay 4743a40ed3dSBarry Smith PetscFunctionBegin; 47577ed5343SBarry Smith /* 47677ed5343SBarry Smith This is nasty. If this is called from an originally parallel matrix 47777ed5343SBarry Smith then all processes call this, but only the first has the matrix so the 47877ed5343SBarry Smith rest should return immediately. 47977ed5343SBarry Smith */ 48077ed5343SBarry Smith ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 48177ed5343SBarry Smith MPI_Comm_rank(comm,&rank); 48277ed5343SBarry Smith if (rank) PetscFunctionReturn(0); 4833270192aSSatish Balay 48477ed5343SBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr); 48577ed5343SBarry Smith 48677ed5343SBarry Smith ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr); CHKERRQ(ierr); 48777ed5343SBarry Smith 4883270192aSSatish Balay /* loop over matrix elements drawing boxes */ 4893270192aSSatish Balay color = DRAW_BLUE; 4903270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 4913270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 4923270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 4933270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4943270192aSSatish Balay aa = a->a + j*bs2; 4953270192aSSatish Balay for ( k=0; k<bs; k++ ) { 4963270192aSSatish Balay for ( l=0; l<bs; l++ ) { 4973270192aSSatish Balay if (PetscReal(*aa++) >= 0.) continue; 498b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 4993270192aSSatish Balay } 5003270192aSSatish Balay } 5013270192aSSatish Balay } 5023270192aSSatish Balay } 5033270192aSSatish Balay color = DRAW_CYAN; 5043270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5053270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5063270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5073270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5083270192aSSatish Balay aa = a->a + j*bs2; 5093270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5103270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5113270192aSSatish Balay if (PetscReal(*aa++) != 0.) continue; 512b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5133270192aSSatish Balay } 5143270192aSSatish Balay } 5153270192aSSatish Balay } 5163270192aSSatish Balay } 5173270192aSSatish Balay 5183270192aSSatish Balay color = DRAW_RED; 5193270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5203270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5213270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5223270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5233270192aSSatish Balay aa = a->a + j*bs2; 5243270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5253270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5263270192aSSatish Balay if (PetscReal(*aa++) <= 0.) continue; 527b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5283270192aSSatish Balay } 5293270192aSSatish Balay } 5303270192aSSatish Balay } 5313270192aSSatish Balay } 53277ed5343SBarry Smith PetscFunctionReturn(0); 53377ed5343SBarry Smith } 5343270192aSSatish Balay 53577ed5343SBarry Smith #undef __FUNC__ 53677ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw" 53777ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer) 53877ed5343SBarry Smith { 53977ed5343SBarry Smith Mat_SeqBAIJ *a=(Mat_SeqBAIJ *) A->data; 540*7dce120fSSatish Balay int ierr; 541*7dce120fSSatish Balay double xl,yl,xr,yr,w,h; 54277ed5343SBarry Smith Draw draw; 54377ed5343SBarry Smith PetscTruth isnull; 5443270192aSSatish Balay 54577ed5343SBarry Smith PetscFunctionBegin; 54677ed5343SBarry Smith 54777ed5343SBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 54877ed5343SBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 54977ed5343SBarry Smith 55077ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 55177ed5343SBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 55277ed5343SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 5533270192aSSatish Balay ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 55477ed5343SBarry Smith ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A); CHKERRQ(ierr); 55577ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5563a40ed3dSBarry Smith PetscFunctionReturn(0); 5573270192aSSatish Balay } 5583270192aSSatish Balay 5595615d1e5SSatish Balay #undef __FUNC__ 560d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ" 561e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer) 5622593348eSBarry Smith { 56319bcc07fSBarry Smith ViewerType vtype; 56419bcc07fSBarry Smith int ierr; 5652593348eSBarry Smith 5663a40ed3dSBarry Smith PetscFunctionBegin; 56719bcc07fSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 56877ed5343SBarry Smith if (!PetscStrcmp(vtype,MATLAB_VIEWER)) { 569a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Matlab viewer not supported"); 57077ed5343SBarry Smith } else if (!PetscStrcmp(vtype,ASCII_VIEWER)){ 5713a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 57277ed5343SBarry Smith } else if (!PetscStrcmp(vtype,BINARY_VIEWER)) { 5733a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 57477ed5343SBarry Smith } else if (!PetscStrcmp(vtype,DRAW_VIEWER)) { 5753a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 5765cd90555SBarry Smith } else { 5775cd90555SBarry Smith SETERRQ(1,1,"Viewer type not supported by PETSc object"); 5782593348eSBarry Smith } 5793a40ed3dSBarry Smith PetscFunctionReturn(0); 5802593348eSBarry Smith } 581b6490206SBarry Smith 582cd0e1443SSatish Balay 5835615d1e5SSatish Balay #undef __FUNC__ 5842d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ" 5852d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 586cd0e1443SSatish Balay { 587cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 5882d61bbb3SSatish Balay int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 5892d61bbb3SSatish Balay int *ai = a->i, *ailen = a->ilen; 5902d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 5912d61bbb3SSatish Balay Scalar *ap, *aa = a->a, zero = 0.0; 592cd0e1443SSatish Balay 5933a40ed3dSBarry Smith PetscFunctionBegin; 5942d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over rows */ 595cd0e1443SSatish Balay row = im[k]; brow = row/bs; 596a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 597a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 5982d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 5992c3acbe9SBarry Smith nrow = ailen[brow]; 6002d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over columns */ 601a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 602a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 6032d61bbb3SSatish Balay col = in[l] ; 6042d61bbb3SSatish Balay bcol = col/bs; 6052d61bbb3SSatish Balay cidx = col%bs; 6062d61bbb3SSatish Balay ridx = row%bs; 6072d61bbb3SSatish Balay high = nrow; 6082d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6092d61bbb3SSatish Balay while (high-low > 5) { 610cd0e1443SSatish Balay t = (low+high)/2; 611cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 612cd0e1443SSatish Balay else low = t; 613cd0e1443SSatish Balay } 614cd0e1443SSatish Balay for ( i=low; i<high; i++ ) { 615cd0e1443SSatish Balay if (rp[i] > bcol) break; 616cd0e1443SSatish Balay if (rp[i] == bcol) { 6172d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6182d61bbb3SSatish Balay goto finished; 619cd0e1443SSatish Balay } 620cd0e1443SSatish Balay } 6212d61bbb3SSatish Balay *v++ = zero; 6222d61bbb3SSatish Balay finished:; 623cd0e1443SSatish Balay } 624cd0e1443SSatish Balay } 6253a40ed3dSBarry Smith PetscFunctionReturn(0); 626cd0e1443SSatish Balay } 627cd0e1443SSatish Balay 6282d61bbb3SSatish Balay 6295615d1e5SSatish Balay #undef __FUNC__ 63005a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 63192c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 63292c4ed94SBarry Smith { 63392c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6348a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 635dd9472c6SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented; 636dd9472c6SBarry Smith int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval; 6370e324ae4SSatish Balay Scalar *ap,*value=v,*aa=a->a,*bap; 63892c4ed94SBarry Smith 6393a40ed3dSBarry Smith PetscFunctionBegin; 6400e324ae4SSatish Balay if (roworiented) { 6410e324ae4SSatish Balay stepval = (n-1)*bs; 6420e324ae4SSatish Balay } else { 6430e324ae4SSatish Balay stepval = (m-1)*bs; 6440e324ae4SSatish Balay } 64592c4ed94SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 64692c4ed94SBarry Smith row = im[k]; 6473a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 648a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 649a8c6a408SBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 65092c4ed94SBarry Smith #endif 65192c4ed94SBarry Smith rp = aj + ai[row]; 65292c4ed94SBarry Smith ap = aa + bs2*ai[row]; 65392c4ed94SBarry Smith rmax = imax[row]; 65492c4ed94SBarry Smith nrow = ailen[row]; 65592c4ed94SBarry Smith low = 0; 65692c4ed94SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 6573a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 658a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 659a8c6a408SBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 66092c4ed94SBarry Smith #endif 66192c4ed94SBarry Smith col = in[l]; 66292c4ed94SBarry Smith if (roworiented) { 6630e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 6640e324ae4SSatish Balay } else { 6650e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 66692c4ed94SBarry Smith } 66792c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 66892c4ed94SBarry Smith while (high-low > 7) { 66992c4ed94SBarry Smith t = (low+high)/2; 67092c4ed94SBarry Smith if (rp[t] > col) high = t; 67192c4ed94SBarry Smith else low = t; 67292c4ed94SBarry Smith } 67392c4ed94SBarry Smith for ( i=low; i<high; i++ ) { 67492c4ed94SBarry Smith if (rp[i] > col) break; 67592c4ed94SBarry Smith if (rp[i] == col) { 6768a84c255SSatish Balay bap = ap + bs2*i; 6770e324ae4SSatish Balay if (roworiented) { 6788a84c255SSatish Balay if (is == ADD_VALUES) { 679dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 680dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 6818a84c255SSatish Balay bap[jj] += *value++; 682dd9472c6SBarry Smith } 683dd9472c6SBarry Smith } 6840e324ae4SSatish Balay } else { 685dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 686dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 6870e324ae4SSatish Balay bap[jj] = *value++; 6888a84c255SSatish Balay } 689dd9472c6SBarry Smith } 690dd9472c6SBarry Smith } 6910e324ae4SSatish Balay } else { 6920e324ae4SSatish Balay if (is == ADD_VALUES) { 693dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 694dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 6950e324ae4SSatish Balay *bap++ += *value++; 696dd9472c6SBarry Smith } 697dd9472c6SBarry Smith } 6980e324ae4SSatish Balay } else { 699dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 700dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7010e324ae4SSatish Balay *bap++ = *value++; 7020e324ae4SSatish Balay } 7038a84c255SSatish Balay } 704dd9472c6SBarry Smith } 705dd9472c6SBarry Smith } 706f1241b54SBarry Smith goto noinsert2; 70792c4ed94SBarry Smith } 70892c4ed94SBarry Smith } 70989280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 710a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 71192c4ed94SBarry Smith if (nrow >= rmax) { 71292c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 71392c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 71492c4ed94SBarry Smith Scalar *new_a; 71592c4ed94SBarry Smith 716a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 71789280ab3SLois Curfman McInnes 71892c4ed94SBarry Smith /* malloc new storage space */ 71992c4ed94SBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int); 72092c4ed94SBarry Smith new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 72192c4ed94SBarry Smith new_j = (int *) (new_a + bs2*new_nz); 72292c4ed94SBarry Smith new_i = new_j + new_nz; 72392c4ed94SBarry Smith 72492c4ed94SBarry Smith /* copy over old data into new slots */ 72592c4ed94SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 72692c4ed94SBarry Smith for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 72792c4ed94SBarry Smith PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int)); 72892c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 729dd9472c6SBarry Smith PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int)); 73092c4ed94SBarry Smith PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(Scalar)); 73192c4ed94SBarry Smith PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(Scalar)); 732dd9472c6SBarry Smith PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(Scalar)); 73392c4ed94SBarry Smith /* free up old matrix storage */ 73492c4ed94SBarry Smith PetscFree(a->a); 73592c4ed94SBarry Smith if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 73692c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 73792c4ed94SBarry Smith a->singlemalloc = 1; 73892c4ed94SBarry Smith 73992c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 74092c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 74192c4ed94SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar))); 74292c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 74392c4ed94SBarry Smith a->reallocs++; 74492c4ed94SBarry Smith a->nz++; 74592c4ed94SBarry Smith } 74692c4ed94SBarry Smith N = nrow++ - 1; 74792c4ed94SBarry Smith /* shift up all the later entries in this row */ 74892c4ed94SBarry Smith for ( ii=N; ii>=i; ii-- ) { 74992c4ed94SBarry Smith rp[ii+1] = rp[ii]; 75092c4ed94SBarry Smith PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar)); 75192c4ed94SBarry Smith } 75292c4ed94SBarry Smith if (N >= i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar)); 75392c4ed94SBarry Smith rp[i] = col; 7548a84c255SSatish Balay bap = ap + bs2*i; 7550e324ae4SSatish Balay if (roworiented) { 756dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval) { 757dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7580e324ae4SSatish Balay bap[jj] = *value++; 759dd9472c6SBarry Smith } 760dd9472c6SBarry Smith } 7610e324ae4SSatish Balay } else { 762dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 763dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7640e324ae4SSatish Balay *bap++ = *value++; 7650e324ae4SSatish Balay } 766dd9472c6SBarry Smith } 767dd9472c6SBarry Smith } 768f1241b54SBarry Smith noinsert2:; 76992c4ed94SBarry Smith low = i; 77092c4ed94SBarry Smith } 77192c4ed94SBarry Smith ailen[row] = nrow; 77292c4ed94SBarry Smith } 7733a40ed3dSBarry Smith PetscFunctionReturn(0); 77492c4ed94SBarry Smith } 77592c4ed94SBarry Smith 776f2501298SSatish Balay 7775615d1e5SSatish Balay #undef __FUNC__ 7785615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ" 7798f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 780584200bdSSatish Balay { 781584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 782584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax; 783a7c10996SSatish Balay int m = a->m,*ip, N, *ailen = a->ilen; 78443ee02c3SBarry Smith int mbs = a->mbs, bs2 = a->bs2,rmax = 0; 785584200bdSSatish Balay Scalar *aa = a->a, *ap; 786584200bdSSatish Balay 7873a40ed3dSBarry Smith PetscFunctionBegin; 7883a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 789584200bdSSatish Balay 79043ee02c3SBarry Smith if (m) rmax = ailen[0]; 791584200bdSSatish Balay for ( i=1; i<mbs; i++ ) { 792584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 793584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 794d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 795584200bdSSatish Balay if (fshift) { 796a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 797584200bdSSatish Balay N = ailen[i]; 798584200bdSSatish Balay for ( j=0; j<N; j++ ) { 799584200bdSSatish Balay ip[j-fshift] = ip[j]; 8007e67e3f9SSatish Balay PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(Scalar)); 801584200bdSSatish Balay } 802584200bdSSatish Balay } 803584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 804584200bdSSatish Balay } 805584200bdSSatish Balay if (mbs) { 806584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 807584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 808584200bdSSatish Balay } 809584200bdSSatish Balay /* reset ilen and imax for each row */ 810584200bdSSatish Balay for ( i=0; i<mbs; i++ ) { 811584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 812584200bdSSatish Balay } 813a7c10996SSatish Balay a->nz = ai[mbs]; 814584200bdSSatish Balay 815584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 816584200bdSSatish Balay if (fshift && a->diag) { 817584200bdSSatish Balay PetscFree(a->diag); 818584200bdSSatish Balay PLogObjectMemory(A,-(m+1)*sizeof(int)); 819584200bdSSatish Balay a->diag = 0; 820584200bdSSatish Balay } 8213d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 822219d9a1aSLois Curfman McInnes m,a->n,a->bs,fshift*bs2,a->nz*bs2); 8233d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 824584200bdSSatish Balay a->reallocs); 825d402145bSBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 826e2f3b5e9SSatish Balay a->reallocs = 0; 8274e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift*bs2; 8284e220ebcSLois Curfman McInnes 8293a40ed3dSBarry Smith PetscFunctionReturn(0); 830584200bdSSatish Balay } 831584200bdSSatish Balay 8325a838052SSatish Balay 833d9b7c43dSSatish Balay /* idx should be of length atlease bs */ 8345615d1e5SSatish Balay #undef __FUNC__ 8355615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Block" 836d9b7c43dSSatish Balay static int MatZeroRows_SeqBAIJ_Check_Block(int *idx, int bs, PetscTruth *flg) 837d9b7c43dSSatish Balay { 838d9b7c43dSSatish Balay int i,row; 8393a40ed3dSBarry Smith 8403a40ed3dSBarry Smith PetscFunctionBegin; 841d9b7c43dSSatish Balay row = idx[0]; 8423a40ed3dSBarry Smith if (row%bs!=0) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 843d9b7c43dSSatish Balay 844d9b7c43dSSatish Balay for ( i=1; i<bs; i++ ) { 8453a40ed3dSBarry Smith if (row+i != idx[i]) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 846d9b7c43dSSatish Balay } 847d9b7c43dSSatish Balay *flg = PETSC_TRUE; 8483a40ed3dSBarry Smith PetscFunctionReturn(0); 849d9b7c43dSSatish Balay } 850d9b7c43dSSatish Balay 8515615d1e5SSatish Balay #undef __FUNC__ 8525615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ" 8538f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag) 854d9b7c43dSSatish Balay { 855d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 856d9b7c43dSSatish Balay IS is_local; 857d9b7c43dSSatish Balay int ierr,i,j,count,m=baij->m,is_n,*is_idx,*rows,bs=baij->bs,bs2=baij->bs2; 858d9b7c43dSSatish Balay PetscTruth flg; 859d9b7c43dSSatish Balay Scalar zero = 0.0,*aa; 860d9b7c43dSSatish Balay 8613a40ed3dSBarry Smith PetscFunctionBegin; 862d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 863d9b7c43dSSatish Balay ierr = ISGetSize(is,&is_n);CHKERRQ(ierr); 864d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 865537820f0SBarry Smith ierr = ISCreateGeneral(A->comm,is_n,is_idx,&is_local); CHKERRQ(ierr); 866d9b7c43dSSatish Balay ierr = ISSort(is_local); CHKERRQ(ierr); 867d9b7c43dSSatish Balay ierr = ISGetIndices(is_local,&rows); CHKERRQ(ierr); 868d9b7c43dSSatish Balay 869d9b7c43dSSatish Balay i = 0; 870d9b7c43dSSatish Balay while (i < is_n) { 871a8c6a408SBarry Smith if (rows[i]<0 || rows[i]>m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 872d9b7c43dSSatish Balay flg = PETSC_FALSE; 873d9b7c43dSSatish Balay if (i+bs <= is_n) {ierr = MatZeroRows_SeqBAIJ_Check_Block(rows+i,bs,&flg); CHKERRQ(ierr); } 874d9b7c43dSSatish Balay count = (baij->i[rows[i]/bs +1] - baij->i[rows[i]/bs])*bs; 875d9b7c43dSSatish Balay aa = baij->a + baij->i[rows[i]/bs]*bs2 + (rows[i]%bs); 8762d61bbb3SSatish Balay if (flg) { /* There exists a block of rows to be Zerowed */ 877a07cd24cSSatish Balay if (baij->ilen[rows[i]/bs] > 0) { 8782d61bbb3SSatish Balay PetscMemzero(aa,count*bs*sizeof(Scalar)); 8792d61bbb3SSatish Balay baij->ilen[rows[i]/bs] = 1; 8802d61bbb3SSatish Balay baij->j[baij->i[rows[i]/bs]] = rows[i]/bs; 881a07cd24cSSatish Balay } 8822d61bbb3SSatish Balay i += bs; 8832d61bbb3SSatish Balay } else { /* Zero out only the requested row */ 884d9b7c43dSSatish Balay for ( j=0; j<count; j++ ) { 885d9b7c43dSSatish Balay aa[0] = zero; 886d9b7c43dSSatish Balay aa+=bs; 887d9b7c43dSSatish Balay } 888d9b7c43dSSatish Balay i++; 889d9b7c43dSSatish Balay } 890d9b7c43dSSatish Balay } 891d9b7c43dSSatish Balay if (diag) { 892d9b7c43dSSatish Balay for ( j=0; j<is_n; j++ ) { 893f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 8942d61bbb3SSatish Balay /* ierr = MatSetValues(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); */ 895d9b7c43dSSatish Balay } 896d9b7c43dSSatish Balay } 897d9b7c43dSSatish Balay ierr = ISRestoreIndices(is,&is_idx); CHKERRQ(ierr); 898d9b7c43dSSatish Balay ierr = ISRestoreIndices(is_local,&rows); CHKERRQ(ierr); 899d9b7c43dSSatish Balay ierr = ISDestroy(is_local); CHKERRQ(ierr); 9009a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 9013a40ed3dSBarry Smith PetscFunctionReturn(0); 902d9b7c43dSSatish Balay } 9031c351548SSatish Balay 9045615d1e5SSatish Balay #undef __FUNC__ 9052d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ" 9062d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9072d61bbb3SSatish Balay { 9082d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 9092d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 9102d61bbb3SSatish Balay int *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 9112d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 9122d61bbb3SSatish Balay int ridx,cidx,bs2=a->bs2; 9132d61bbb3SSatish Balay Scalar *ap,value,*aa=a->a,*bap; 9142d61bbb3SSatish Balay 9152d61bbb3SSatish Balay PetscFunctionBegin; 9162d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over added rows */ 9172d61bbb3SSatish Balay row = im[k]; brow = row/bs; 9182d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9192d61bbb3SSatish Balay if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 9202d61bbb3SSatish Balay if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 9212d61bbb3SSatish Balay #endif 9222d61bbb3SSatish Balay rp = aj + ai[brow]; 9232d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 9242d61bbb3SSatish Balay rmax = imax[brow]; 9252d61bbb3SSatish Balay nrow = ailen[brow]; 9262d61bbb3SSatish Balay low = 0; 9272d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over added columns */ 9282d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9292d61bbb3SSatish Balay if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 9302d61bbb3SSatish Balay if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 9312d61bbb3SSatish Balay #endif 9322d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 9332d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 9342d61bbb3SSatish Balay if (roworiented) { 9352d61bbb3SSatish Balay value = *v++; 9362d61bbb3SSatish Balay } else { 9372d61bbb3SSatish Balay value = v[k + l*m]; 9382d61bbb3SSatish Balay } 9392d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 9402d61bbb3SSatish Balay while (high-low > 7) { 9412d61bbb3SSatish Balay t = (low+high)/2; 9422d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 9432d61bbb3SSatish Balay else low = t; 9442d61bbb3SSatish Balay } 9452d61bbb3SSatish Balay for ( i=low; i<high; i++ ) { 9462d61bbb3SSatish Balay if (rp[i] > bcol) break; 9472d61bbb3SSatish Balay if (rp[i] == bcol) { 9482d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 9492d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 9502d61bbb3SSatish Balay else *bap = value; 9512d61bbb3SSatish Balay goto noinsert1; 9522d61bbb3SSatish Balay } 9532d61bbb3SSatish Balay } 9542d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 9552d61bbb3SSatish Balay else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9562d61bbb3SSatish Balay if (nrow >= rmax) { 9572d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 9582d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 9592d61bbb3SSatish Balay Scalar *new_a; 9602d61bbb3SSatish Balay 9612d61bbb3SSatish Balay if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9622d61bbb3SSatish Balay 9632d61bbb3SSatish Balay /* Malloc new storage space */ 9642d61bbb3SSatish Balay len = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int); 9652d61bbb3SSatish Balay new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 9662d61bbb3SSatish Balay new_j = (int *) (new_a + bs2*new_nz); 9672d61bbb3SSatish Balay new_i = new_j + new_nz; 9682d61bbb3SSatish Balay 9692d61bbb3SSatish Balay /* copy over old data into new slots */ 9702d61bbb3SSatish Balay for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];} 9712d61bbb3SSatish Balay for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 9722d61bbb3SSatish Balay PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int)); 9732d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 9742d61bbb3SSatish Balay PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow, 9752d61bbb3SSatish Balay len*sizeof(int)); 9762d61bbb3SSatish Balay PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(Scalar)); 9772d61bbb3SSatish Balay PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(Scalar)); 9782d61bbb3SSatish Balay PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE), 9792d61bbb3SSatish Balay aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(Scalar)); 9802d61bbb3SSatish Balay /* free up old matrix storage */ 9812d61bbb3SSatish Balay PetscFree(a->a); 9822d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 9832d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 9842d61bbb3SSatish Balay a->singlemalloc = 1; 9852d61bbb3SSatish Balay 9862d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 9872d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 9882d61bbb3SSatish Balay PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar))); 9892d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 9902d61bbb3SSatish Balay a->reallocs++; 9912d61bbb3SSatish Balay a->nz++; 9922d61bbb3SSatish Balay } 9932d61bbb3SSatish Balay N = nrow++ - 1; 9942d61bbb3SSatish Balay /* shift up all the later entries in this row */ 9952d61bbb3SSatish Balay for ( ii=N; ii>=i; ii-- ) { 9962d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 9972d61bbb3SSatish Balay PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar)); 9982d61bbb3SSatish Balay } 9992d61bbb3SSatish Balay if (N>=i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar)); 10002d61bbb3SSatish Balay rp[i] = bcol; 10012d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10022d61bbb3SSatish Balay noinsert1:; 10032d61bbb3SSatish Balay low = i; 10042d61bbb3SSatish Balay } 10052d61bbb3SSatish Balay ailen[brow] = nrow; 10062d61bbb3SSatish Balay } 10072d61bbb3SSatish Balay PetscFunctionReturn(0); 10082d61bbb3SSatish Balay } 10092d61bbb3SSatish Balay 10102d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 10112d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 10122d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 1013d3825aa8SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatGetSubMatrixCall,Mat*); 10142d61bbb3SSatish Balay extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatGetSubMatrixCall,Mat**); 10152d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec); 10162d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 10172d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat); 10182d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *); 10192d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*); 10202d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec); 10212d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 10222d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 10232d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat); 10242d61bbb3SSatish Balay 10252d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 10262d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 10272d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 10282d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 10292d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 10302d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 10312d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 10322d61bbb3SSatish Balay 10332d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 10342d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 10352d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 10362d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 10372d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 10382d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 10392d61bbb3SSatish Balay 10402d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 10412d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 10422d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 10432d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 10442d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 10452d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 10462d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 10472d61bbb3SSatish Balay 10482d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 10492d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 10502d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 10512d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 10522d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 10532d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 10542d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 10552d61bbb3SSatish Balay 10562d61bbb3SSatish Balay #undef __FUNC__ 10572d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ" 10582d61bbb3SSatish Balay int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill) 10592d61bbb3SSatish Balay { 10602d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 10612d61bbb3SSatish Balay Mat outA; 10622d61bbb3SSatish Balay int ierr; 1063667159a5SBarry Smith PetscTruth row_identity, col_identity; 10642d61bbb3SSatish Balay 10652d61bbb3SSatish Balay PetscFunctionBegin; 10662d61bbb3SSatish Balay if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported"); 1067667159a5SBarry Smith ierr = ISIdentity(row,&row_identity); CHKERRQ(ierr); 1068667159a5SBarry Smith ierr = ISIdentity(col,&col_identity); CHKERRQ(ierr); 1069667159a5SBarry Smith if (!row_identity || !col_identity) { 1070667159a5SBarry Smith SETERRQ(1,1,"Row and column permutations must be identity"); 1071667159a5SBarry Smith } 10722d61bbb3SSatish Balay 10732d61bbb3SSatish Balay outA = inA; 10742d61bbb3SSatish Balay inA->factor = FACTOR_LU; 10752d61bbb3SSatish Balay a->row = row; 10762d61bbb3SSatish Balay a->col = col; 10772d61bbb3SSatish Balay 1078e51c0b9cSSatish Balay /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 1079e51c0b9cSSatish Balay ierr = ISInvertPermutation(col,&(a->icol)); CHKERRQ(ierr); 10801e4dd532SSatish Balay PLogObjectParent(inA,a->icol); 1081e51c0b9cSSatish Balay 10822d61bbb3SSatish Balay if (!a->solve_work) { 10832d61bbb3SSatish Balay a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work); 10842d61bbb3SSatish Balay PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar)); 10852d61bbb3SSatish Balay } 10862d61bbb3SSatish Balay 10872d61bbb3SSatish Balay if (!a->diag) { 10882d61bbb3SSatish Balay ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 10892d61bbb3SSatish Balay } 10902d61bbb3SSatish Balay /* 1091667159a5SBarry Smith Blocksize 4 and 5 have a special faster factorization/solver for ILU(0) factorization 10922d61bbb3SSatish Balay with natural ordering 10932d61bbb3SSatish Balay */ 10942d61bbb3SSatish Balay if (a->bs == 4) { 1095667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering; 1096f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 1097667159a5SBarry Smith PLogInfo(inA,"Using special in-place natural ordering factor and solve BS=4\n"); 1098667159a5SBarry Smith } else if (a->bs == 5) { 1099667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering; 1100667159a5SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_5_NaturalOrdering; 1101667159a5SBarry Smith PLogInfo(inA,"Using special in-place natural ordering factor and solve BS=5\n"); 11022d61bbb3SSatish Balay } 11032d61bbb3SSatish Balay 1104667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr); 1105667159a5SBarry Smith 1106667159a5SBarry Smith 11072d61bbb3SSatish Balay PetscFunctionReturn(0); 11082d61bbb3SSatish Balay } 11092d61bbb3SSatish Balay #undef __FUNC__ 1110d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ" 1111ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1112ba4ca20aSSatish Balay { 1113ba4ca20aSSatish Balay static int called = 0; 1114ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1115ba4ca20aSSatish Balay 11163a40ed3dSBarry Smith PetscFunctionBegin; 11173a40ed3dSBarry Smith if (called) {PetscFunctionReturn(0);} else called = 1; 111876be9ce4SBarry Smith (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n"); 111976be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n"); 11203a40ed3dSBarry Smith PetscFunctionReturn(0); 1121ba4ca20aSSatish Balay } 1122d9b7c43dSSatish Balay 1123fb2e594dSBarry Smith EXTERN_C_BEGIN 112427a8da17SBarry Smith #undef __FUNC__ 112527a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 112627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 112727a8da17SBarry Smith { 112827a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 112927a8da17SBarry Smith int i,nz,n; 113027a8da17SBarry Smith 113127a8da17SBarry Smith PetscFunctionBegin; 113227a8da17SBarry Smith nz = baij->maxnz; 113327a8da17SBarry Smith n = baij->n; 113427a8da17SBarry Smith for (i=0; i<nz; i++) { 113527a8da17SBarry Smith baij->j[i] = indices[i]; 113627a8da17SBarry Smith } 113727a8da17SBarry Smith baij->nz = nz; 113827a8da17SBarry Smith for ( i=0; i<n; i++ ) { 113927a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 114027a8da17SBarry Smith } 114127a8da17SBarry Smith 114227a8da17SBarry Smith PetscFunctionReturn(0); 114327a8da17SBarry Smith } 1144fb2e594dSBarry Smith EXTERN_C_END 114527a8da17SBarry Smith 114627a8da17SBarry Smith #undef __FUNC__ 114727a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices" 114827a8da17SBarry Smith /*@ 114927a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 115027a8da17SBarry Smith in the matrix. 115127a8da17SBarry Smith 115227a8da17SBarry Smith Input Parameters: 115327a8da17SBarry Smith + mat - the SeqBAIJ matrix 115427a8da17SBarry Smith - indices - the column indices 115527a8da17SBarry Smith 115627a8da17SBarry Smith Notes: 115727a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 115827a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 115927a8da17SBarry Smith of the MatSetValues() operation. 116027a8da17SBarry Smith 116127a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 116227a8da17SBarry Smith MatCreateSeqBAIJ(). 116327a8da17SBarry Smith 116427a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 116527a8da17SBarry Smith 116627a8da17SBarry Smith @*/ 116727a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 116827a8da17SBarry Smith { 116927a8da17SBarry Smith int ierr,(*f)(Mat,int *); 117027a8da17SBarry Smith 117127a8da17SBarry Smith PetscFunctionBegin; 117227a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 117327a8da17SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f); 117427a8da17SBarry Smith CHKERRQ(ierr); 117527a8da17SBarry Smith if (f) { 117627a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 117727a8da17SBarry Smith } else { 117827a8da17SBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 117927a8da17SBarry Smith } 118027a8da17SBarry Smith PetscFunctionReturn(0); 118127a8da17SBarry Smith } 118227a8da17SBarry Smith 11832593348eSBarry Smith /* -------------------------------------------------------------------*/ 1184cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1185cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1186cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1187cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1188cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 1189cc2dc46cSBarry Smith MatMultTrans_SeqBAIJ, 1190cc2dc46cSBarry Smith MatMultTransAdd_SeqBAIJ, 1191cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1192cc2dc46cSBarry Smith 0, 1193cc2dc46cSBarry Smith 0, 1194cc2dc46cSBarry Smith 0, 1195cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1196cc2dc46cSBarry Smith 0, 1197b6490206SBarry Smith 0, 1198f2501298SSatish Balay MatTranspose_SeqBAIJ, 1199cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1200cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1201cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1202cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1203cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1204b6490206SBarry Smith 0, 1205cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1206cc2dc46cSBarry Smith 0, 1207cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1208cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1209cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1210cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1211cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1212cc2dc46cSBarry Smith 0, 1213cc2dc46cSBarry Smith 0, 1214cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1215cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1216cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1217cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1218cc2dc46cSBarry Smith 0, 1219cc2dc46cSBarry Smith 0, 1220cc2dc46cSBarry Smith 0, 12212e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1222cc2dc46cSBarry Smith 0, 1223cc2dc46cSBarry Smith 0, 1224cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1225cc2dc46cSBarry Smith 0, 1226cc2dc46cSBarry Smith 0, 1227cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1228cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1229cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1230cc2dc46cSBarry Smith 0, 1231cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1232cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1233cc2dc46cSBarry Smith 0, 1234cc2dc46cSBarry Smith 0, 1235cc2dc46cSBarry Smith 0, 1236cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 12373b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 123892c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1239cc2dc46cSBarry Smith 0, 1240cc2dc46cSBarry Smith 0, 1241cc2dc46cSBarry Smith 0, 1242cc2dc46cSBarry Smith 0, 1243cc2dc46cSBarry Smith 0, 1244cc2dc46cSBarry Smith 0, 1245d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1246cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1247cc2dc46cSBarry Smith 0, 1248cc2dc46cSBarry Smith 0, 1249cc2dc46cSBarry Smith MatGetMaps_Petsc}; 12502593348eSBarry Smith 12515615d1e5SSatish Balay #undef __FUNC__ 12525615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ" 12532593348eSBarry Smith /*@C 125444cd7ae7SLois Curfman McInnes MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 125544cd7ae7SLois Curfman McInnes compressed row) format. For good matrix assembly performance the 125644cd7ae7SLois Curfman McInnes user should preallocate the matrix storage by setting the parameter nz 12572bd5e0b2SLois Curfman McInnes (or the array nzz). By setting these parameters accurately, performance 12582bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 12592593348eSBarry Smith 1260db81eaa0SLois Curfman McInnes Collective on MPI_Comm 1261db81eaa0SLois Curfman McInnes 12622593348eSBarry Smith Input Parameters: 1263db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 1264b6490206SBarry Smith . bs - size of block 12652593348eSBarry Smith . m - number of rows 12662593348eSBarry Smith . n - number of columns 1267b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1268db81eaa0SLois Curfman McInnes - nzz - array containing the number of block nonzeros in the various block rows 12692bd5e0b2SLois Curfman McInnes (possibly different for each block row) or PETSC_NULL 12702593348eSBarry Smith 12712593348eSBarry Smith Output Parameter: 12722593348eSBarry Smith . A - the matrix 12732593348eSBarry Smith 12740513a670SBarry Smith Options Database Keys: 1275db81eaa0SLois Curfman McInnes . -mat_no_unroll - uses code that does not unroll the loops in the 1276db81eaa0SLois Curfman McInnes block calculations (much slower) 1277db81eaa0SLois Curfman McInnes . -mat_block_size - size of the blocks to use 12780513a670SBarry Smith 12792593348eSBarry Smith Notes: 128044cd7ae7SLois Curfman McInnes The block AIJ format is fully compatible with standard Fortran 77 12812593348eSBarry Smith storage. That is, the stored row and column indices can begin at 128244cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 12832593348eSBarry Smith 12842593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 12852593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 12862593348eSBarry Smith allocation. For additional details, see the users manual chapter on 12876da5968aSLois Curfman McInnes matrices. 12882593348eSBarry Smith 1289db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 12902593348eSBarry Smith @*/ 1291b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 12922593348eSBarry Smith { 12932593348eSBarry Smith Mat B; 1294b6490206SBarry Smith Mat_SeqBAIJ *b; 12953b2fbd54SBarry Smith int i,len,ierr,flg,mbs=m/bs,nbs=n/bs,bs2=bs*bs,size; 12963b2fbd54SBarry Smith 12973a40ed3dSBarry Smith PetscFunctionBegin; 12983b2fbd54SBarry Smith MPI_Comm_size(comm,&size); 1299a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1"); 1300b6490206SBarry Smith 13010513a670SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 13020513a670SBarry Smith 13033a40ed3dSBarry Smith if (mbs*bs!=m || nbs*bs!=n) { 1304a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize"); 13053a40ed3dSBarry Smith } 13062593348eSBarry Smith 13072593348eSBarry Smith *A = 0; 1308f830108cSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,comm,MatDestroy,MatView); 13092593348eSBarry Smith PLogObjectCreate(B); 1310b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 131144cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_SeqBAIJ)); 1312cc2dc46cSBarry Smith PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); 13131a6a6d98SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg); CHKERRQ(ierr); 13141a6a6d98SBarry Smith if (!flg) { 13157fc0212eSBarry Smith switch (bs) { 13167fc0212eSBarry Smith case 1: 1317f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1318f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1319f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1320f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 13217fc0212eSBarry Smith break; 13224eeb42bcSBarry Smith case 2: 1323f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1324f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1325f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1326f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 13276d84be18SBarry Smith break; 1328f327dd97SBarry Smith case 3: 1329f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1330f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1331f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1332f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 13334eeb42bcSBarry Smith break; 13346d84be18SBarry Smith case 4: 1335f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1336f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1337f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1338f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 13396d84be18SBarry Smith break; 13406d84be18SBarry Smith case 5: 1341f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1342f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1343f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1344f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 13456d84be18SBarry Smith break; 134648e9ddb2SSatish Balay case 7: 1347f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1348f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1349f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 135048e9ddb2SSatish Balay break; 13517fc0212eSBarry Smith } 13521a6a6d98SBarry Smith } 1353e1311b90SBarry Smith B->ops->destroy = MatDestroy_SeqBAIJ; 1354e1311b90SBarry Smith B->ops->view = MatView_SeqBAIJ; 13552593348eSBarry Smith B->factor = 0; 13562593348eSBarry Smith B->lupivotthreshold = 1.0; 135790f02eecSBarry Smith B->mapping = 0; 13582593348eSBarry Smith b->row = 0; 13592593348eSBarry Smith b->col = 0; 1360e51c0b9cSSatish Balay b->icol = 0; 13612593348eSBarry Smith b->reallocs = 0; 13622593348eSBarry Smith 136344cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 136444cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 1365a5ae1ecdSBarry Smith 13667413bad6SBarry Smith ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 13677413bad6SBarry Smith ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 1368a5ae1ecdSBarry Smith 1369b6490206SBarry Smith b->mbs = mbs; 1370f2501298SSatish Balay b->nbs = nbs; 1371b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 13722593348eSBarry Smith if (nnz == PETSC_NULL) { 1373119a934aSSatish Balay if (nz == PETSC_DEFAULT) nz = 5; 13742593348eSBarry Smith else if (nz <= 0) nz = 1; 1375b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 1376b6490206SBarry Smith nz = nz*mbs; 13773a40ed3dSBarry Smith } else { 13782593348eSBarry Smith nz = 0; 1379b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 13802593348eSBarry Smith } 13812593348eSBarry Smith 13822593348eSBarry Smith /* allocate the matrix space */ 13837e67e3f9SSatish Balay len = nz*sizeof(int) + nz*bs2*sizeof(Scalar) + (b->m+1)*sizeof(int); 13842593348eSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 13857e67e3f9SSatish Balay PetscMemzero(b->a,nz*bs2*sizeof(Scalar)); 13867e67e3f9SSatish Balay b->j = (int *) (b->a + nz*bs2); 13872593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 13882593348eSBarry Smith b->i = b->j + nz; 13892593348eSBarry Smith b->singlemalloc = 1; 13902593348eSBarry Smith 1391de6a44a3SBarry Smith b->i[0] = 0; 1392b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 13932593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 13942593348eSBarry Smith } 13952593348eSBarry Smith 1396b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 1397b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 1398f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1399b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 14002593348eSBarry Smith 1401b6490206SBarry Smith b->bs = bs; 14029df24120SSatish Balay b->bs2 = bs2; 1403b6490206SBarry Smith b->mbs = mbs; 14042593348eSBarry Smith b->nz = 0; 140518e7b8e4SLois Curfman McInnes b->maxnz = nz*bs2; 14062593348eSBarry Smith b->sorted = 0; 14072593348eSBarry Smith b->roworiented = 1; 14082593348eSBarry Smith b->nonew = 0; 14092593348eSBarry Smith b->diag = 0; 14102593348eSBarry Smith b->solve_work = 0; 1411de6a44a3SBarry Smith b->mult_work = 0; 14122593348eSBarry Smith b->spptr = 0; 14134e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 14144e220ebcSLois Curfman McInnes 14152593348eSBarry Smith *A = B; 14162593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 14172593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 141827a8da17SBarry Smith 141927a8da17SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 142027a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 142127a8da17SBarry Smith (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 142227a8da17SBarry Smith 14233a40ed3dSBarry Smith PetscFunctionReturn(0); 14242593348eSBarry Smith } 14252593348eSBarry Smith 14265615d1e5SSatish Balay #undef __FUNC__ 14272e8a6d31SBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ" 14282e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 14292593348eSBarry Smith { 14302593348eSBarry Smith Mat C; 1431b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 143227a8da17SBarry Smith int i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1433de6a44a3SBarry Smith 14343a40ed3dSBarry Smith PetscFunctionBegin; 1435a8c6a408SBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix"); 14362593348eSBarry Smith 14372593348eSBarry Smith *B = 0; 1438f830108cSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,A->comm,MatDestroy,MatView); 14392593348eSBarry Smith PLogObjectCreate(C); 1440b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 1441c3c66ee5SSatish Balay PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps)); 1442e1311b90SBarry Smith C->ops->destroy = MatDestroy_SeqBAIJ; 1443e1311b90SBarry Smith C->ops->view = MatView_SeqBAIJ; 14442593348eSBarry Smith C->factor = A->factor; 14452593348eSBarry Smith c->row = 0; 14462593348eSBarry Smith c->col = 0; 14472593348eSBarry Smith C->assembled = PETSC_TRUE; 14482593348eSBarry Smith 144944cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 145044cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 145144cd7ae7SLois Curfman McInnes C->M = a->m; 145244cd7ae7SLois Curfman McInnes C->N = a->n; 145344cd7ae7SLois Curfman McInnes 1454b6490206SBarry Smith c->bs = a->bs; 14559df24120SSatish Balay c->bs2 = a->bs2; 1456b6490206SBarry Smith c->mbs = a->mbs; 1457b6490206SBarry Smith c->nbs = a->nbs; 14582593348eSBarry Smith 1459b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 1460b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 1461b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 14622593348eSBarry Smith c->imax[i] = a->imax[i]; 14632593348eSBarry Smith c->ilen[i] = a->ilen[i]; 14642593348eSBarry Smith } 14652593348eSBarry Smith 14662593348eSBarry Smith /* allocate the matrix space */ 14672593348eSBarry Smith c->singlemalloc = 1; 14687e67e3f9SSatish Balay len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(Scalar) + sizeof(int)); 14692593348eSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 14707e67e3f9SSatish Balay c->j = (int *) (c->a + nz*bs2); 1471de6a44a3SBarry Smith c->i = c->j + nz; 1472b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 1473b6490206SBarry Smith if (mbs > 0) { 1474de6a44a3SBarry Smith PetscMemcpy(c->j,a->j,nz*sizeof(int)); 14752e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 14767e67e3f9SSatish Balay PetscMemcpy(c->a,a->a,bs2*nz*sizeof(Scalar)); 14772e8a6d31SBarry Smith } else { 14782e8a6d31SBarry Smith PetscMemzero(c->a,bs2*nz*sizeof(Scalar)); 14792593348eSBarry Smith } 14802593348eSBarry Smith } 14812593348eSBarry Smith 1482f09e8eb9SSatish Balay PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 14832593348eSBarry Smith c->sorted = a->sorted; 14842593348eSBarry Smith c->roworiented = a->roworiented; 14852593348eSBarry Smith c->nonew = a->nonew; 14862593348eSBarry Smith 14872593348eSBarry Smith if (a->diag) { 1488b6490206SBarry Smith c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag); 1489b6490206SBarry Smith PLogObjectMemory(C,(mbs+1)*sizeof(int)); 1490b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 14912593348eSBarry Smith c->diag[i] = a->diag[i]; 14922593348eSBarry Smith } 14932593348eSBarry Smith } 14942593348eSBarry Smith else c->diag = 0; 14952593348eSBarry Smith c->nz = a->nz; 14962593348eSBarry Smith c->maxnz = a->maxnz; 14972593348eSBarry Smith c->solve_work = 0; 14982593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 14997fc0212eSBarry Smith c->mult_work = 0; 15002593348eSBarry Smith *B = C; 150127a8da17SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)C,"MatSeqBAIJSetColumnIndices_C", 150227a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 150327a8da17SBarry Smith (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 15043a40ed3dSBarry Smith PetscFunctionReturn(0); 15052593348eSBarry Smith } 15062593348eSBarry Smith 15075615d1e5SSatish Balay #undef __FUNC__ 15085615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ" 150919bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A) 15102593348eSBarry Smith { 1511b6490206SBarry Smith Mat_SeqBAIJ *a; 15122593348eSBarry Smith Mat B; 1513de6a44a3SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg; 1514b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 151535aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1516a7c10996SSatish Balay int *masked, nmask,tmp,bs2,ishift; 1517b6490206SBarry Smith Scalar *aa; 151819bcc07fSBarry Smith MPI_Comm comm = ((PetscObject) viewer)->comm; 15192593348eSBarry Smith 15203a40ed3dSBarry Smith PetscFunctionBegin; 15211a6a6d98SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,&flg);CHKERRQ(ierr); 1522de6a44a3SBarry Smith bs2 = bs*bs; 1523b6490206SBarry Smith 15242593348eSBarry Smith MPI_Comm_size(comm,&size); 1525cc0fae11SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor"); 152690ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 15270752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr); 1528a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object"); 15292593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 15302593348eSBarry Smith 1531d64ed03dSBarry Smith if (header[3] < 0) { 1532a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ"); 1533d64ed03dSBarry Smith } 1534d64ed03dSBarry Smith 1535a8c6a408SBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices"); 153635aab85fSBarry Smith 153735aab85fSBarry Smith /* 153835aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 153935aab85fSBarry Smith divisible by the blocksize 154035aab85fSBarry Smith */ 1541b6490206SBarry Smith mbs = M/bs; 154235aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 154335aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 154435aab85fSBarry Smith else mbs++; 154535aab85fSBarry Smith if (extra_rows) { 1546537820f0SBarry Smith PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 154735aab85fSBarry Smith } 1548b6490206SBarry Smith 15492593348eSBarry Smith /* read in row lengths */ 155035aab85fSBarry Smith rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths); 15510752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr); 155235aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1; 15532593348eSBarry Smith 1554b6490206SBarry Smith /* read in column indices */ 155535aab85fSBarry Smith jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj); 15560752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT); CHKERRQ(ierr); 155735aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i; 1558b6490206SBarry Smith 1559b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1560b6490206SBarry Smith browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths); 1561b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 156235aab85fSBarry Smith mask = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask); 156335aab85fSBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 156435aab85fSBarry Smith masked = mask + mbs; 1565b6490206SBarry Smith rowcount = 0; nzcount = 0; 1566b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 156735aab85fSBarry Smith nmask = 0; 1568b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1569b6490206SBarry Smith kmax = rowlengths[rowcount]; 1570b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 157135aab85fSBarry Smith tmp = jj[nzcount++]/bs; 157235aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1573b6490206SBarry Smith } 1574b6490206SBarry Smith rowcount++; 1575b6490206SBarry Smith } 157635aab85fSBarry Smith browlengths[i] += nmask; 157735aab85fSBarry Smith /* zero out the mask elements we set */ 157835aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1579b6490206SBarry Smith } 1580b6490206SBarry Smith 15812593348eSBarry Smith /* create our matrix */ 15823eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 15832593348eSBarry Smith B = *A; 1584b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 15852593348eSBarry Smith 15862593348eSBarry Smith /* set matrix "i" values */ 1587de6a44a3SBarry Smith a->i[0] = 0; 1588b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 1589b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1590b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 15912593348eSBarry Smith } 1592b6490206SBarry Smith a->nz = 0; 1593b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 15942593348eSBarry Smith 1595b6490206SBarry Smith /* read in nonzero values */ 159635aab85fSBarry Smith aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa); 15970752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR); CHKERRQ(ierr); 159835aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0; 1599b6490206SBarry Smith 1600b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1601b6490206SBarry Smith nzcount = 0; jcount = 0; 1602b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 1603b6490206SBarry Smith nzcountb = nzcount; 160435aab85fSBarry Smith nmask = 0; 1605b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1606b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1607b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 160835aab85fSBarry Smith tmp = jj[nzcount++]/bs; 160935aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1610b6490206SBarry Smith } 1611b6490206SBarry Smith rowcount++; 1612b6490206SBarry Smith } 1613de6a44a3SBarry Smith /* sort the masked values */ 161477c4ece6SBarry Smith PetscSortInt(nmask,masked); 1615de6a44a3SBarry Smith 1616b6490206SBarry Smith /* set "j" values into matrix */ 1617b6490206SBarry Smith maskcount = 1; 161835aab85fSBarry Smith for ( j=0; j<nmask; j++ ) { 161935aab85fSBarry Smith a->j[jcount++] = masked[j]; 1620de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1621b6490206SBarry Smith } 1622b6490206SBarry Smith /* set "a" values into matrix */ 1623de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1624b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1625b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1626b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 1627de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1628de6a44a3SBarry Smith block = mask[tmp] - 1; 1629de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1630de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1631b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 1632b6490206SBarry Smith } 1633b6490206SBarry Smith } 163435aab85fSBarry Smith /* zero out the mask elements we set */ 163535aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1636b6490206SBarry Smith } 1637a8c6a408SBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix"); 1638b6490206SBarry Smith 1639b6490206SBarry Smith PetscFree(rowlengths); 1640b6490206SBarry Smith PetscFree(browlengths); 1641b6490206SBarry Smith PetscFree(aa); 1642b6490206SBarry Smith PetscFree(jj); 1643b6490206SBarry Smith PetscFree(mask); 1644b6490206SBarry Smith 1645b6490206SBarry Smith B->assembled = PETSC_TRUE; 1646de6a44a3SBarry Smith 16479c01be13SBarry Smith ierr = MatView_Private(B); CHKERRQ(ierr); 16483a40ed3dSBarry Smith PetscFunctionReturn(0); 16492593348eSBarry Smith } 16502593348eSBarry Smith 16512593348eSBarry Smith 16522593348eSBarry Smith 1653