1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*7b2a1423SBarry Smith static char vcid[] = "$Id: baij.c,v 1.152 1998/12/21 01:00:55 bsmith 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 #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; 2003f1db9ecSBarry Smith MatScalar *aa,*aa_i; 2013f1db9ecSBarry Smith Scalar *v_i; 2022d61bbb3SSatish Balay 2032d61bbb3SSatish Balay PetscFunctionBegin; 2042d61bbb3SSatish Balay bs = a->bs; 2052d61bbb3SSatish Balay ai = a->i; 2062d61bbb3SSatish Balay aj = a->j; 2072d61bbb3SSatish Balay aa = a->a; 2082d61bbb3SSatish Balay bs2 = a->bs2; 2092d61bbb3SSatish Balay 2102d61bbb3SSatish Balay if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 2112d61bbb3SSatish Balay 2122d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2132d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2142d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2152d61bbb3SSatish Balay *nz = bs*M; 2162d61bbb3SSatish Balay 2172d61bbb3SSatish Balay if (v) { 2182d61bbb3SSatish Balay *v = 0; 2192d61bbb3SSatish Balay if (*nz) { 2202d61bbb3SSatish Balay *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v); 2212d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2222d61bbb3SSatish Balay v_i = *v + i*bs; 2232d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2242d61bbb3SSatish Balay for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];} 2252d61bbb3SSatish Balay } 2262d61bbb3SSatish Balay } 2272d61bbb3SSatish Balay } 2282d61bbb3SSatish Balay 2292d61bbb3SSatish Balay if (idx) { 2302d61bbb3SSatish Balay *idx = 0; 2312d61bbb3SSatish Balay if (*nz) { 2322d61bbb3SSatish Balay *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 2332d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2342d61bbb3SSatish Balay idx_i = *idx + i*bs; 2352d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2362d61bbb3SSatish Balay for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;} 2372d61bbb3SSatish Balay } 2382d61bbb3SSatish Balay } 2392d61bbb3SSatish Balay } 2402d61bbb3SSatish Balay PetscFunctionReturn(0); 2412d61bbb3SSatish Balay } 2422d61bbb3SSatish Balay 2432d61bbb3SSatish Balay #undef __FUNC__ 2442d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ" 2452d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2462d61bbb3SSatish Balay { 2472d61bbb3SSatish Balay PetscFunctionBegin; 2482d61bbb3SSatish Balay if (idx) {if (*idx) PetscFree(*idx);} 2492d61bbb3SSatish Balay if (v) {if (*v) PetscFree(*v);} 2502d61bbb3SSatish Balay PetscFunctionReturn(0); 2512d61bbb3SSatish Balay } 2522d61bbb3SSatish Balay 2532d61bbb3SSatish Balay #undef __FUNC__ 2542d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ" 2552d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2562d61bbb3SSatish Balay { 2572d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2582d61bbb3SSatish Balay Mat C; 2592d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 2602d61bbb3SSatish Balay int *rows,*cols,bs2=a->bs2; 2613f1db9ecSBarry Smith MatScalar *array = a->a; 2622d61bbb3SSatish Balay 2632d61bbb3SSatish Balay PetscFunctionBegin; 2642d61bbb3SSatish Balay if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place"); 2652d61bbb3SSatish Balay col = (int *) PetscMalloc((1+nbs)*sizeof(int)); CHKPTRQ(col); 2662d61bbb3SSatish Balay PetscMemzero(col,(1+nbs)*sizeof(int)); 2672d61bbb3SSatish Balay 2682d61bbb3SSatish Balay for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1; 2692d61bbb3SSatish Balay ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C); CHKERRQ(ierr); 2702d61bbb3SSatish Balay PetscFree(col); 2712d61bbb3SSatish Balay rows = (int *) PetscMalloc(2*bs*sizeof(int)); CHKPTRQ(rows); 2722d61bbb3SSatish Balay cols = rows + bs; 2732d61bbb3SSatish Balay for ( i=0; i<mbs; i++ ) { 2742d61bbb3SSatish Balay cols[0] = i*bs; 2752d61bbb3SSatish Balay for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1; 2762d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 2772d61bbb3SSatish Balay for ( j=0; j<len; j++ ) { 2782d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 2792d61bbb3SSatish Balay for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1; 2802d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES); CHKERRQ(ierr); 2812d61bbb3SSatish Balay array += bs2; 2822d61bbb3SSatish Balay } 2832d61bbb3SSatish Balay } 2842d61bbb3SSatish Balay PetscFree(rows); 2852d61bbb3SSatish Balay 2862d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2872d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2882d61bbb3SSatish Balay 2892d61bbb3SSatish Balay if (B != PETSC_NULL) { 2902d61bbb3SSatish Balay *B = C; 2912d61bbb3SSatish Balay } else { 292f830108cSBarry Smith PetscOps *Abops; 293cc2dc46cSBarry Smith MatOps Aops; 294f830108cSBarry Smith 2952d61bbb3SSatish Balay /* This isn't really an in-place transpose */ 2962d61bbb3SSatish Balay PetscFree(a->a); 2972d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);} 2982d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 2992d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 3002d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 3012d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 3022d61bbb3SSatish Balay PetscFree(a); 303f830108cSBarry Smith 3047413bad6SBarry Smith 3057413bad6SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 3067413bad6SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 3077413bad6SBarry Smith 308f830108cSBarry Smith /* 309f830108cSBarry Smith This is horrible, horrible code. We need to keep the 310f830108cSBarry Smith A pointers for the bops and ops but copy everything 311f830108cSBarry Smith else from C. 312f830108cSBarry Smith */ 313f830108cSBarry Smith Abops = A->bops; 314f830108cSBarry Smith Aops = A->ops; 3152d61bbb3SSatish Balay PetscMemcpy(A,C,sizeof(struct _p_Mat)); 316f830108cSBarry Smith A->bops = Abops; 317f830108cSBarry Smith A->ops = Aops; 31827a8da17SBarry Smith A->qlist = 0; 319f830108cSBarry Smith 3202d61bbb3SSatish Balay PetscHeaderDestroy(C); 3212d61bbb3SSatish Balay } 3222d61bbb3SSatish Balay PetscFunctionReturn(0); 3232d61bbb3SSatish Balay } 3242d61bbb3SSatish Balay 3252d61bbb3SSatish Balay 3262d61bbb3SSatish Balay 3273b2fbd54SBarry Smith 3285615d1e5SSatish Balay #undef __FUNC__ 329d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary" 330b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer) 3312593348eSBarry Smith { 332b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3339df24120SSatish Balay int i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 334b6490206SBarry Smith Scalar *aa; 3352593348eSBarry Smith 3363a40ed3dSBarry Smith PetscFunctionBegin; 33790ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 3382593348eSBarry Smith col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 3392593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3403b2fbd54SBarry Smith 3412593348eSBarry Smith col_lens[1] = a->m; 3422593348eSBarry Smith col_lens[2] = a->n; 3437e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3442593348eSBarry Smith 3452593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 346b6490206SBarry Smith count = 0; 347b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 348b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 349b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 350b6490206SBarry Smith } 3512593348eSBarry Smith } 3520752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr); 3532593348eSBarry Smith PetscFree(col_lens); 3542593348eSBarry Smith 3552593348eSBarry Smith /* store column indices (zero start index) */ 35666963ce1SSatish Balay jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) ); CHKPTRQ(jj); 357b6490206SBarry Smith count = 0; 358b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 359b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 360b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 361b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 362b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3632593348eSBarry Smith } 3642593348eSBarry Smith } 365b6490206SBarry Smith } 366b6490206SBarry Smith } 3670752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0); CHKERRQ(ierr); 368b6490206SBarry Smith PetscFree(jj); 3692593348eSBarry Smith 3702593348eSBarry Smith /* store nonzero values */ 37166963ce1SSatish Balay aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar)); CHKPTRQ(aa); 372b6490206SBarry Smith count = 0; 373b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 374b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 375b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 376b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 3777e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 378b6490206SBarry Smith } 379b6490206SBarry Smith } 380b6490206SBarry Smith } 381b6490206SBarry Smith } 3820752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0); CHKERRQ(ierr); 383b6490206SBarry Smith PetscFree(aa); 3843a40ed3dSBarry Smith PetscFunctionReturn(0); 3852593348eSBarry Smith } 3862593348eSBarry Smith 3875615d1e5SSatish Balay #undef __FUNC__ 388d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII" 389b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer) 3902593348eSBarry Smith { 391b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3929df24120SSatish Balay int ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2; 3932593348eSBarry Smith FILE *fd; 3942593348eSBarry Smith char *outputname; 3952593348eSBarry Smith 3963a40ed3dSBarry Smith PetscFunctionBegin; 39790ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 39877ed5343SBarry Smith ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr); 39990ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 400639f9d9dSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) { 4010ef38995SBarry Smith ViewerASCIIPrintf(viewer," block size is %d\n",bs); 4020ef38995SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 403*7b2a1423SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Socket format not supported"); 4040ef38995SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_COMMON) { 40544cd7ae7SLois Curfman McInnes for ( i=0; i<a->mbs; i++ ) { 40644cd7ae7SLois Curfman McInnes for ( j=0; j<bs; j++ ) { 40744cd7ae7SLois Curfman McInnes fprintf(fd,"row %d:",i*bs+j); 40844cd7ae7SLois Curfman McInnes for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 40944cd7ae7SLois Curfman McInnes for ( l=0; l<bs; l++ ) { 4103a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 4110ef38995SBarry Smith if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) { 41244cd7ae7SLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 413e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j])); 4140ef38995SBarry Smith } else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) { 415766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 416e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 4170ef38995SBarry Smith } else if (PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) { 418e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 4190ef38995SBarry Smith } 42044cd7ae7SLois Curfman McInnes #else 4210ef38995SBarry Smith 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]); 4230ef38995SBarry Smith } 42444cd7ae7SLois Curfman McInnes #endif 42544cd7ae7SLois Curfman McInnes } 42644cd7ae7SLois Curfman McInnes } 42744cd7ae7SLois Curfman McInnes fprintf(fd,"\n"); 42844cd7ae7SLois Curfman McInnes } 42944cd7ae7SLois Curfman McInnes } 4300ef38995SBarry 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])); 4400ef38995SBarry Smith } else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0) { 441766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 442e20fef11SSatish Balay PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j])); 4430ef38995SBarry Smith } else { 444e20fef11SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j])); 44588685aaeSLois Curfman McInnes } 44688685aaeSLois Curfman McInnes #else 4477e67e3f9SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 44888685aaeSLois Curfman McInnes #endif 4492593348eSBarry Smith } 4502593348eSBarry Smith } 4512593348eSBarry Smith fprintf(fd,"\n"); 4522593348eSBarry Smith } 4532593348eSBarry Smith } 454b6490206SBarry Smith } 4552593348eSBarry Smith fflush(fd); 4563a40ed3dSBarry Smith PetscFunctionReturn(0); 4572593348eSBarry Smith } 4582593348eSBarry Smith 4595615d1e5SSatish Balay #undef __FUNC__ 46077ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom" 46177ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa) 4623270192aSSatish Balay { 46377ed5343SBarry Smith Mat A = (Mat) Aa; 4643270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *) A->data; 4657dce120fSSatish Balay int row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2,rank; 466fae8c767SSatish Balay double xl,yl,xr,yr,x_l,x_r,y_l,y_r; 4673f1db9ecSBarry Smith MatScalar *aa; 46877ed5343SBarry Smith MPI_Comm comm; 46977ed5343SBarry Smith Viewer viewer; 4703270192aSSatish Balay 4713a40ed3dSBarry Smith PetscFunctionBegin; 47277ed5343SBarry Smith /* 47377ed5343SBarry Smith This is nasty. If this is called from an originally parallel matrix 47477ed5343SBarry Smith then all processes call this, but only the first has the matrix so the 47577ed5343SBarry Smith rest should return immediately. 47677ed5343SBarry Smith */ 47777ed5343SBarry Smith ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 47877ed5343SBarry Smith MPI_Comm_rank(comm,&rank); 47977ed5343SBarry Smith if (rank) PetscFunctionReturn(0); 4803270192aSSatish Balay 48177ed5343SBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr); 48277ed5343SBarry Smith 48377ed5343SBarry Smith ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr); CHKERRQ(ierr); 48477ed5343SBarry Smith 4853270192aSSatish Balay /* loop over matrix elements drawing boxes */ 4863270192aSSatish Balay color = DRAW_BLUE; 4873270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 4883270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 4893270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 4903270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4913270192aSSatish Balay aa = a->a + j*bs2; 4923270192aSSatish Balay for ( k=0; k<bs; k++ ) { 4933270192aSSatish Balay for ( l=0; l<bs; l++ ) { 4943270192aSSatish Balay if (PetscReal(*aa++) >= 0.) continue; 495b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 4963270192aSSatish Balay } 4973270192aSSatish Balay } 4983270192aSSatish Balay } 4993270192aSSatish Balay } 5003270192aSSatish Balay color = DRAW_CYAN; 5013270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5023270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5033270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5043270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5053270192aSSatish Balay aa = a->a + j*bs2; 5063270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5073270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5083270192aSSatish Balay if (PetscReal(*aa++) != 0.) continue; 509b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5103270192aSSatish Balay } 5113270192aSSatish Balay } 5123270192aSSatish Balay } 5133270192aSSatish Balay } 5143270192aSSatish Balay 5153270192aSSatish Balay color = DRAW_RED; 5163270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5173270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5183270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5193270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5203270192aSSatish Balay aa = a->a + j*bs2; 5213270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5223270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5233270192aSSatish Balay if (PetscReal(*aa++) <= 0.) continue; 524b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5253270192aSSatish Balay } 5263270192aSSatish Balay } 5273270192aSSatish Balay } 5283270192aSSatish Balay } 52977ed5343SBarry Smith PetscFunctionReturn(0); 53077ed5343SBarry Smith } 5313270192aSSatish Balay 53277ed5343SBarry Smith #undef __FUNC__ 53377ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw" 53477ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer) 53577ed5343SBarry Smith { 53677ed5343SBarry Smith Mat_SeqBAIJ *a=(Mat_SeqBAIJ *) A->data; 5377dce120fSSatish Balay int ierr; 5387dce120fSSatish Balay double xl,yl,xr,yr,w,h; 53977ed5343SBarry Smith Draw draw; 54077ed5343SBarry Smith PetscTruth isnull; 5413270192aSSatish Balay 54277ed5343SBarry Smith PetscFunctionBegin; 54377ed5343SBarry Smith 54477ed5343SBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 54577ed5343SBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 54677ed5343SBarry Smith 54777ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 54877ed5343SBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 54977ed5343SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 5503270192aSSatish Balay ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 55177ed5343SBarry Smith ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A); CHKERRQ(ierr); 55277ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5533a40ed3dSBarry Smith PetscFunctionReturn(0); 5543270192aSSatish Balay } 5553270192aSSatish Balay 5565615d1e5SSatish Balay #undef __FUNC__ 557d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ" 558e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer) 5592593348eSBarry Smith { 56019bcc07fSBarry Smith ViewerType vtype; 56119bcc07fSBarry Smith int ierr; 5622593348eSBarry Smith 5633a40ed3dSBarry Smith PetscFunctionBegin; 56419bcc07fSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 565*7b2a1423SBarry Smith if (PetscTypeCompare(vtype,SOCKET_VIEWER)) { 566*7b2a1423SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Socket viewer not supported"); 5673f1db9ecSBarry Smith } else if (PetscTypeCompare(vtype,ASCII_VIEWER)){ 5683a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5693f1db9ecSBarry Smith } else if (PetscTypeCompare(vtype,BINARY_VIEWER)) { 5703a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 5713f1db9ecSBarry Smith } else if (PetscTypeCompare(vtype,DRAW_VIEWER)) { 5723a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 5735cd90555SBarry Smith } else { 5745cd90555SBarry Smith SETERRQ(1,1,"Viewer type not supported by PETSc object"); 5752593348eSBarry Smith } 5763a40ed3dSBarry Smith PetscFunctionReturn(0); 5772593348eSBarry Smith } 578b6490206SBarry Smith 579cd0e1443SSatish Balay 5805615d1e5SSatish Balay #undef __FUNC__ 5812d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ" 5822d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 583cd0e1443SSatish Balay { 584cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 5852d61bbb3SSatish Balay int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 5862d61bbb3SSatish Balay int *ai = a->i, *ailen = a->ilen; 5872d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 5883f1db9ecSBarry Smith MatScalar *ap, *aa = a->a, zero = 0.0; 589cd0e1443SSatish Balay 5903a40ed3dSBarry Smith PetscFunctionBegin; 5912d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over rows */ 592cd0e1443SSatish Balay row = im[k]; brow = row/bs; 593a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 594a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 5952d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 5962c3acbe9SBarry Smith nrow = ailen[brow]; 5972d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over columns */ 598a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 599a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 6002d61bbb3SSatish Balay col = in[l] ; 6012d61bbb3SSatish Balay bcol = col/bs; 6022d61bbb3SSatish Balay cidx = col%bs; 6032d61bbb3SSatish Balay ridx = row%bs; 6042d61bbb3SSatish Balay high = nrow; 6052d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6062d61bbb3SSatish Balay while (high-low > 5) { 607cd0e1443SSatish Balay t = (low+high)/2; 608cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 609cd0e1443SSatish Balay else low = t; 610cd0e1443SSatish Balay } 611cd0e1443SSatish Balay for ( i=low; i<high; i++ ) { 612cd0e1443SSatish Balay if (rp[i] > bcol) break; 613cd0e1443SSatish Balay if (rp[i] == bcol) { 6142d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6152d61bbb3SSatish Balay goto finished; 616cd0e1443SSatish Balay } 617cd0e1443SSatish Balay } 6182d61bbb3SSatish Balay *v++ = zero; 6192d61bbb3SSatish Balay finished:; 620cd0e1443SSatish Balay } 621cd0e1443SSatish Balay } 6223a40ed3dSBarry Smith PetscFunctionReturn(0); 623cd0e1443SSatish Balay } 624cd0e1443SSatish Balay 6252d61bbb3SSatish Balay 6265615d1e5SSatish Balay #undef __FUNC__ 62705a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 62892c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 62992c4ed94SBarry Smith { 63092c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6318a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 632dd9472c6SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented; 633dd9472c6SBarry Smith int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval; 6343f1db9ecSBarry Smith Scalar *value = v; 6353f1db9ecSBarry Smith MatScalar *ap,*aa=a->a,*bap; 63692c4ed94SBarry Smith 6373a40ed3dSBarry Smith PetscFunctionBegin; 6380e324ae4SSatish Balay if (roworiented) { 6390e324ae4SSatish Balay stepval = (n-1)*bs; 6400e324ae4SSatish Balay } else { 6410e324ae4SSatish Balay stepval = (m-1)*bs; 6420e324ae4SSatish Balay } 64392c4ed94SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 64492c4ed94SBarry Smith row = im[k]; 6453a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 646a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 647a8c6a408SBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 64892c4ed94SBarry Smith #endif 64992c4ed94SBarry Smith rp = aj + ai[row]; 65092c4ed94SBarry Smith ap = aa + bs2*ai[row]; 65192c4ed94SBarry Smith rmax = imax[row]; 65292c4ed94SBarry Smith nrow = ailen[row]; 65392c4ed94SBarry Smith low = 0; 65492c4ed94SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 6553a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 656a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 657a8c6a408SBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 65892c4ed94SBarry Smith #endif 65992c4ed94SBarry Smith col = in[l]; 66092c4ed94SBarry Smith if (roworiented) { 6610e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 6620e324ae4SSatish Balay } else { 6630e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 66492c4ed94SBarry Smith } 66592c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 66692c4ed94SBarry Smith while (high-low > 7) { 66792c4ed94SBarry Smith t = (low+high)/2; 66892c4ed94SBarry Smith if (rp[t] > col) high = t; 66992c4ed94SBarry Smith else low = t; 67092c4ed94SBarry Smith } 67192c4ed94SBarry Smith for ( i=low; i<high; i++ ) { 67292c4ed94SBarry Smith if (rp[i] > col) break; 67392c4ed94SBarry Smith if (rp[i] == col) { 6748a84c255SSatish Balay bap = ap + bs2*i; 6750e324ae4SSatish Balay if (roworiented) { 6768a84c255SSatish Balay if (is == ADD_VALUES) { 677dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 678dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 6798a84c255SSatish Balay bap[jj] += *value++; 680dd9472c6SBarry Smith } 681dd9472c6SBarry Smith } 6820e324ae4SSatish Balay } else { 683dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 684dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 6850e324ae4SSatish Balay bap[jj] = *value++; 6868a84c255SSatish Balay } 687dd9472c6SBarry Smith } 688dd9472c6SBarry Smith } 6890e324ae4SSatish Balay } else { 6900e324ae4SSatish Balay if (is == ADD_VALUES) { 691dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 692dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 6930e324ae4SSatish Balay *bap++ += *value++; 694dd9472c6SBarry Smith } 695dd9472c6SBarry Smith } 6960e324ae4SSatish Balay } else { 697dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 698dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 6990e324ae4SSatish Balay *bap++ = *value++; 7000e324ae4SSatish Balay } 7018a84c255SSatish Balay } 702dd9472c6SBarry Smith } 703dd9472c6SBarry Smith } 704f1241b54SBarry Smith goto noinsert2; 70592c4ed94SBarry Smith } 70692c4ed94SBarry Smith } 70789280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 708a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 70992c4ed94SBarry Smith if (nrow >= rmax) { 71092c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 71192c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 7123f1db9ecSBarry Smith MatScalar *new_a; 71392c4ed94SBarry Smith 714a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 71589280ab3SLois Curfman McInnes 71692c4ed94SBarry Smith /* malloc new storage space */ 7173f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 7183f1db9ecSBarry Smith new_a = (MatScalar *) PetscMalloc( len ); CHKPTRQ(new_a); 71992c4ed94SBarry Smith new_j = (int *) (new_a + bs2*new_nz); 72092c4ed94SBarry Smith new_i = new_j + new_nz; 72192c4ed94SBarry Smith 72292c4ed94SBarry Smith /* copy over old data into new slots */ 72392c4ed94SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 72492c4ed94SBarry Smith for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 72592c4ed94SBarry Smith PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int)); 72692c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 727dd9472c6SBarry Smith PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int)); 7283f1db9ecSBarry Smith PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar)); 7293f1db9ecSBarry Smith PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar)); 7303f1db9ecSBarry Smith PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar)); 73192c4ed94SBarry Smith /* free up old matrix storage */ 73292c4ed94SBarry Smith PetscFree(a->a); 73392c4ed94SBarry Smith if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 73492c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 73592c4ed94SBarry Smith a->singlemalloc = 1; 73692c4ed94SBarry Smith 73792c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 73892c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 7393f1db9ecSBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 74092c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 74192c4ed94SBarry Smith a->reallocs++; 74292c4ed94SBarry Smith a->nz++; 74392c4ed94SBarry Smith } 74492c4ed94SBarry Smith N = nrow++ - 1; 74592c4ed94SBarry Smith /* shift up all the later entries in this row */ 74692c4ed94SBarry Smith for ( ii=N; ii>=i; ii-- ) { 74792c4ed94SBarry Smith rp[ii+1] = rp[ii]; 7483f1db9ecSBarry Smith PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar)); 74992c4ed94SBarry Smith } 7503f1db9ecSBarry Smith if (N >= i) PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar)); 75192c4ed94SBarry Smith rp[i] = col; 7528a84c255SSatish Balay bap = ap + bs2*i; 7530e324ae4SSatish Balay if (roworiented) { 754dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval) { 755dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7560e324ae4SSatish Balay bap[jj] = *value++; 757dd9472c6SBarry Smith } 758dd9472c6SBarry Smith } 7590e324ae4SSatish Balay } else { 760dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 761dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7620e324ae4SSatish Balay *bap++ = *value++; 7630e324ae4SSatish Balay } 764dd9472c6SBarry Smith } 765dd9472c6SBarry Smith } 766f1241b54SBarry Smith noinsert2:; 76792c4ed94SBarry Smith low = i; 76892c4ed94SBarry Smith } 76992c4ed94SBarry Smith ailen[row] = nrow; 77092c4ed94SBarry Smith } 7713a40ed3dSBarry Smith PetscFunctionReturn(0); 77292c4ed94SBarry Smith } 77392c4ed94SBarry Smith 774f2501298SSatish Balay 7755615d1e5SSatish Balay #undef __FUNC__ 7765615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ" 7778f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 778584200bdSSatish Balay { 779584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 780584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax; 781a7c10996SSatish Balay int m = a->m,*ip, N, *ailen = a->ilen; 78243ee02c3SBarry Smith int mbs = a->mbs, bs2 = a->bs2,rmax = 0; 7833f1db9ecSBarry Smith MatScalar *aa = a->a, *ap; 784584200bdSSatish Balay 7853a40ed3dSBarry Smith PetscFunctionBegin; 7863a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 787584200bdSSatish Balay 78843ee02c3SBarry Smith if (m) rmax = ailen[0]; 789584200bdSSatish Balay for ( i=1; i<mbs; i++ ) { 790584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 791584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 792d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 793584200bdSSatish Balay if (fshift) { 794a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 795584200bdSSatish Balay N = ailen[i]; 796584200bdSSatish Balay for ( j=0; j<N; j++ ) { 797584200bdSSatish Balay ip[j-fshift] = ip[j]; 7983f1db9ecSBarry Smith PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar)); 799584200bdSSatish Balay } 800584200bdSSatish Balay } 801584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 802584200bdSSatish Balay } 803584200bdSSatish Balay if (mbs) { 804584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 805584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 806584200bdSSatish Balay } 807584200bdSSatish Balay /* reset ilen and imax for each row */ 808584200bdSSatish Balay for ( i=0; i<mbs; i++ ) { 809584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 810584200bdSSatish Balay } 811a7c10996SSatish Balay a->nz = ai[mbs]; 812584200bdSSatish Balay 813584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 814584200bdSSatish Balay if (fshift && a->diag) { 815584200bdSSatish Balay PetscFree(a->diag); 816584200bdSSatish Balay PLogObjectMemory(A,-(m+1)*sizeof(int)); 817584200bdSSatish Balay a->diag = 0; 818584200bdSSatish Balay } 8193d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 820219d9a1aSLois Curfman McInnes m,a->n,a->bs,fshift*bs2,a->nz*bs2); 8213d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 822584200bdSSatish Balay a->reallocs); 823d402145bSBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 824e2f3b5e9SSatish Balay a->reallocs = 0; 8254e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift*bs2; 8264e220ebcSLois Curfman McInnes 8273a40ed3dSBarry Smith PetscFunctionReturn(0); 828584200bdSSatish Balay } 829584200bdSSatish Balay 8305a838052SSatish Balay 831d9b7c43dSSatish Balay /* idx should be of length atlease bs */ 8325615d1e5SSatish Balay #undef __FUNC__ 8335615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Block" 834d9b7c43dSSatish Balay static int MatZeroRows_SeqBAIJ_Check_Block(int *idx, int bs, PetscTruth *flg) 835d9b7c43dSSatish Balay { 836d9b7c43dSSatish Balay int i,row; 8373a40ed3dSBarry Smith 8383a40ed3dSBarry Smith PetscFunctionBegin; 839d9b7c43dSSatish Balay row = idx[0]; 8403a40ed3dSBarry Smith if (row%bs!=0) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 841d9b7c43dSSatish Balay 842d9b7c43dSSatish Balay for ( i=1; i<bs; i++ ) { 8433a40ed3dSBarry Smith if (row+i != idx[i]) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 844d9b7c43dSSatish Balay } 845d9b7c43dSSatish Balay *flg = PETSC_TRUE; 8463a40ed3dSBarry Smith PetscFunctionReturn(0); 847d9b7c43dSSatish Balay } 848d9b7c43dSSatish Balay 8495615d1e5SSatish Balay #undef __FUNC__ 8505615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ" 8518f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag) 852d9b7c43dSSatish Balay { 853d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 854d9b7c43dSSatish Balay IS is_local; 855d9b7c43dSSatish Balay int ierr,i,j,count,m=baij->m,is_n,*is_idx,*rows,bs=baij->bs,bs2=baij->bs2; 856d9b7c43dSSatish Balay PetscTruth flg; 8573f1db9ecSBarry Smith Scalar zero = 0.0; 8583f1db9ecSBarry Smith MatScalar *aa; 859d9b7c43dSSatish Balay 8603a40ed3dSBarry Smith PetscFunctionBegin; 861d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 862d9b7c43dSSatish Balay ierr = ISGetSize(is,&is_n);CHKERRQ(ierr); 863d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 864537820f0SBarry Smith ierr = ISCreateGeneral(A->comm,is_n,is_idx,&is_local); CHKERRQ(ierr); 865d9b7c43dSSatish Balay ierr = ISSort(is_local); CHKERRQ(ierr); 866d9b7c43dSSatish Balay ierr = ISGetIndices(is_local,&rows); CHKERRQ(ierr); 867d9b7c43dSSatish Balay 868d9b7c43dSSatish Balay i = 0; 869d9b7c43dSSatish Balay while (i < is_n) { 870a8c6a408SBarry Smith if (rows[i]<0 || rows[i]>m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 871d9b7c43dSSatish Balay flg = PETSC_FALSE; 872d9b7c43dSSatish Balay if (i+bs <= is_n) {ierr = MatZeroRows_SeqBAIJ_Check_Block(rows+i,bs,&flg); CHKERRQ(ierr); } 873d9b7c43dSSatish Balay count = (baij->i[rows[i]/bs +1] - baij->i[rows[i]/bs])*bs; 874d9b7c43dSSatish Balay aa = baij->a + baij->i[rows[i]/bs]*bs2 + (rows[i]%bs); 8752d61bbb3SSatish Balay if (flg) { /* There exists a block of rows to be Zerowed */ 876a07cd24cSSatish Balay if (baij->ilen[rows[i]/bs] > 0) { 8773f1db9ecSBarry Smith PetscMemzero(aa,count*bs*sizeof(MatScalar)); 8782d61bbb3SSatish Balay baij->ilen[rows[i]/bs] = 1; 8792d61bbb3SSatish Balay baij->j[baij->i[rows[i]/bs]] = rows[i]/bs; 880a07cd24cSSatish Balay } 8812d61bbb3SSatish Balay i += bs; 8822d61bbb3SSatish Balay } else { /* Zero out only the requested row */ 883d9b7c43dSSatish Balay for ( j=0; j<count; j++ ) { 884d9b7c43dSSatish Balay aa[0] = zero; 885d9b7c43dSSatish Balay aa+=bs; 886d9b7c43dSSatish Balay } 887d9b7c43dSSatish Balay i++; 888d9b7c43dSSatish Balay } 889d9b7c43dSSatish Balay } 890d9b7c43dSSatish Balay if (diag) { 891d9b7c43dSSatish Balay for ( j=0; j<is_n; j++ ) { 892f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 893d9b7c43dSSatish Balay } 894d9b7c43dSSatish Balay } 895d9b7c43dSSatish Balay ierr = ISRestoreIndices(is,&is_idx); CHKERRQ(ierr); 896d9b7c43dSSatish Balay ierr = ISRestoreIndices(is_local,&rows); CHKERRQ(ierr); 897d9b7c43dSSatish Balay ierr = ISDestroy(is_local); CHKERRQ(ierr); 8989a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 8993a40ed3dSBarry Smith PetscFunctionReturn(0); 900d9b7c43dSSatish Balay } 9011c351548SSatish Balay 9025615d1e5SSatish Balay #undef __FUNC__ 9032d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ" 9042d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9052d61bbb3SSatish Balay { 9062d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 9072d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 9082d61bbb3SSatish Balay int *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 9092d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 9102d61bbb3SSatish Balay int ridx,cidx,bs2=a->bs2; 9113f1db9ecSBarry Smith MatScalar *ap,value,*aa=a->a,*bap; 9122d61bbb3SSatish Balay 9132d61bbb3SSatish Balay PetscFunctionBegin; 9142d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over added rows */ 9152d61bbb3SSatish Balay row = im[k]; brow = row/bs; 9162d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9172d61bbb3SSatish Balay if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 9182d61bbb3SSatish Balay if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 9192d61bbb3SSatish Balay #endif 9202d61bbb3SSatish Balay rp = aj + ai[brow]; 9212d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 9222d61bbb3SSatish Balay rmax = imax[brow]; 9232d61bbb3SSatish Balay nrow = ailen[brow]; 9242d61bbb3SSatish Balay low = 0; 9252d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over added columns */ 9262d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9272d61bbb3SSatish Balay if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 9282d61bbb3SSatish Balay if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 9292d61bbb3SSatish Balay #endif 9302d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 9312d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 9322d61bbb3SSatish Balay if (roworiented) { 9332d61bbb3SSatish Balay value = *v++; 9342d61bbb3SSatish Balay } else { 9352d61bbb3SSatish Balay value = v[k + l*m]; 9362d61bbb3SSatish Balay } 9372d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 9382d61bbb3SSatish Balay while (high-low > 7) { 9392d61bbb3SSatish Balay t = (low+high)/2; 9402d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 9412d61bbb3SSatish Balay else low = t; 9422d61bbb3SSatish Balay } 9432d61bbb3SSatish Balay for ( i=low; i<high; i++ ) { 9442d61bbb3SSatish Balay if (rp[i] > bcol) break; 9452d61bbb3SSatish Balay if (rp[i] == bcol) { 9462d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 9472d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 9482d61bbb3SSatish Balay else *bap = value; 9492d61bbb3SSatish Balay goto noinsert1; 9502d61bbb3SSatish Balay } 9512d61bbb3SSatish Balay } 9522d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 9532d61bbb3SSatish Balay else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9542d61bbb3SSatish Balay if (nrow >= rmax) { 9552d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 9562d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 9573f1db9ecSBarry Smith MatScalar *new_a; 9582d61bbb3SSatish Balay 9592d61bbb3SSatish Balay if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9602d61bbb3SSatish Balay 9612d61bbb3SSatish Balay /* Malloc new storage space */ 9623f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 9633f1db9ecSBarry Smith new_a = (MatScalar *) PetscMalloc( len ); CHKPTRQ(new_a); 9642d61bbb3SSatish Balay new_j = (int *) (new_a + bs2*new_nz); 9652d61bbb3SSatish Balay new_i = new_j + new_nz; 9662d61bbb3SSatish Balay 9672d61bbb3SSatish Balay /* copy over old data into new slots */ 9682d61bbb3SSatish Balay for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];} 9692d61bbb3SSatish Balay for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 9702d61bbb3SSatish Balay PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int)); 9712d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 9722d61bbb3SSatish Balay PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow, 9732d61bbb3SSatish Balay len*sizeof(int)); 9743f1db9ecSBarry Smith PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar)); 9753f1db9ecSBarry Smith PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar)); 9762d61bbb3SSatish Balay PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE), 9773f1db9ecSBarry Smith aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar)); 9782d61bbb3SSatish Balay /* free up old matrix storage */ 9792d61bbb3SSatish Balay PetscFree(a->a); 9802d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 9812d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 9822d61bbb3SSatish Balay a->singlemalloc = 1; 9832d61bbb3SSatish Balay 9842d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 9852d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 9863f1db9ecSBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 9872d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 9882d61bbb3SSatish Balay a->reallocs++; 9892d61bbb3SSatish Balay a->nz++; 9902d61bbb3SSatish Balay } 9912d61bbb3SSatish Balay N = nrow++ - 1; 9922d61bbb3SSatish Balay /* shift up all the later entries in this row */ 9932d61bbb3SSatish Balay for ( ii=N; ii>=i; ii-- ) { 9942d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 9953f1db9ecSBarry Smith PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar)); 9962d61bbb3SSatish Balay } 9973f1db9ecSBarry Smith if (N>=i) PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar)); 9982d61bbb3SSatish Balay rp[i] = bcol; 9992d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10002d61bbb3SSatish Balay noinsert1:; 10012d61bbb3SSatish Balay low = i; 10022d61bbb3SSatish Balay } 10032d61bbb3SSatish Balay ailen[brow] = nrow; 10042d61bbb3SSatish Balay } 10052d61bbb3SSatish Balay PetscFunctionReturn(0); 10062d61bbb3SSatish Balay } 10072d61bbb3SSatish Balay 10082d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 10092d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 10102d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 1011*7b2a1423SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*); 1012*7b2a1423SBarry Smith extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**); 10132d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec); 10142d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 10152d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat); 10162d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *); 10172d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*); 10182d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec); 10192d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 10202d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 10212d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat); 10222d61bbb3SSatish Balay 10232d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 10242d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 10252d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 10262d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 10272d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 10282d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 10292d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 10302d61bbb3SSatish Balay 10312d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 10322d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 10332d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 10342d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 10352d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 10362d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 10372d61bbb3SSatish Balay 10382d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 10392d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 10402d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 10412d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 10422d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 10432d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 10442d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 10452d61bbb3SSatish Balay 10462d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 10472d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 10482d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 10492d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 10502d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 10512d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 10522d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 10532d61bbb3SSatish Balay 10542d61bbb3SSatish Balay #undef __FUNC__ 10552d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ" 10562d61bbb3SSatish Balay int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill) 10572d61bbb3SSatish Balay { 10582d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 10592d61bbb3SSatish Balay Mat outA; 10602d61bbb3SSatish Balay int ierr; 1061667159a5SBarry Smith PetscTruth row_identity, col_identity; 10622d61bbb3SSatish Balay 10632d61bbb3SSatish Balay PetscFunctionBegin; 10642d61bbb3SSatish Balay if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported"); 1065667159a5SBarry Smith ierr = ISIdentity(row,&row_identity); CHKERRQ(ierr); 1066667159a5SBarry Smith ierr = ISIdentity(col,&col_identity); CHKERRQ(ierr); 1067667159a5SBarry Smith if (!row_identity || !col_identity) { 1068667159a5SBarry Smith SETERRQ(1,1,"Row and column permutations must be identity"); 1069667159a5SBarry Smith } 10702d61bbb3SSatish Balay 10712d61bbb3SSatish Balay outA = inA; 10722d61bbb3SSatish Balay inA->factor = FACTOR_LU; 10732d61bbb3SSatish Balay a->row = row; 10742d61bbb3SSatish Balay a->col = col; 10752d61bbb3SSatish Balay 1076e51c0b9cSSatish Balay /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 1077e51c0b9cSSatish Balay ierr = ISInvertPermutation(col,&(a->icol)); CHKERRQ(ierr); 10781e4dd532SSatish Balay PLogObjectParent(inA,a->icol); 1079e51c0b9cSSatish Balay 10802d61bbb3SSatish Balay if (!a->solve_work) { 10812d61bbb3SSatish Balay a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work); 10822d61bbb3SSatish Balay PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar)); 10832d61bbb3SSatish Balay } 10842d61bbb3SSatish Balay 10852d61bbb3SSatish Balay if (!a->diag) { 10862d61bbb3SSatish Balay ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 10872d61bbb3SSatish Balay } 10882d61bbb3SSatish Balay /* 1089667159a5SBarry Smith Blocksize 4 and 5 have a special faster factorization/solver for ILU(0) factorization 10902d61bbb3SSatish Balay with natural ordering 10912d61bbb3SSatish Balay */ 10922d61bbb3SSatish Balay if (a->bs == 4) { 1093667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering; 1094f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 1095667159a5SBarry Smith PLogInfo(inA,"Using special in-place natural ordering factor and solve BS=4\n"); 1096667159a5SBarry Smith } else if (a->bs == 5) { 1097667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering; 1098667159a5SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_5_NaturalOrdering; 1099667159a5SBarry Smith PLogInfo(inA,"Using special in-place natural ordering factor and solve BS=5\n"); 11002d61bbb3SSatish Balay } 11012d61bbb3SSatish Balay 1102667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr); 1103667159a5SBarry Smith 1104667159a5SBarry Smith 11052d61bbb3SSatish Balay PetscFunctionReturn(0); 11062d61bbb3SSatish Balay } 11072d61bbb3SSatish Balay #undef __FUNC__ 1108d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ" 1109ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1110ba4ca20aSSatish Balay { 1111ba4ca20aSSatish Balay static int called = 0; 1112ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1113ba4ca20aSSatish Balay 11143a40ed3dSBarry Smith PetscFunctionBegin; 11153a40ed3dSBarry Smith if (called) {PetscFunctionReturn(0);} else called = 1; 111676be9ce4SBarry Smith (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n"); 111776be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n"); 11183a40ed3dSBarry Smith PetscFunctionReturn(0); 1119ba4ca20aSSatish Balay } 1120d9b7c43dSSatish Balay 1121fb2e594dSBarry Smith EXTERN_C_BEGIN 112227a8da17SBarry Smith #undef __FUNC__ 112327a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 112427a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 112527a8da17SBarry Smith { 112627a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 112727a8da17SBarry Smith int i,nz,n; 112827a8da17SBarry Smith 112927a8da17SBarry Smith PetscFunctionBegin; 113027a8da17SBarry Smith nz = baij->maxnz; 113127a8da17SBarry Smith n = baij->n; 113227a8da17SBarry Smith for (i=0; i<nz; i++) { 113327a8da17SBarry Smith baij->j[i] = indices[i]; 113427a8da17SBarry Smith } 113527a8da17SBarry Smith baij->nz = nz; 113627a8da17SBarry Smith for ( i=0; i<n; i++ ) { 113727a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 113827a8da17SBarry Smith } 113927a8da17SBarry Smith 114027a8da17SBarry Smith PetscFunctionReturn(0); 114127a8da17SBarry Smith } 1142fb2e594dSBarry Smith EXTERN_C_END 114327a8da17SBarry Smith 114427a8da17SBarry Smith #undef __FUNC__ 114527a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices" 114627a8da17SBarry Smith /*@ 114727a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 114827a8da17SBarry Smith in the matrix. 114927a8da17SBarry Smith 115027a8da17SBarry Smith Input Parameters: 115127a8da17SBarry Smith + mat - the SeqBAIJ matrix 115227a8da17SBarry Smith - indices - the column indices 115327a8da17SBarry Smith 115427a8da17SBarry Smith Notes: 115527a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 115627a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 115727a8da17SBarry Smith of the MatSetValues() operation. 115827a8da17SBarry Smith 115927a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 116027a8da17SBarry Smith MatCreateSeqBAIJ(). 116127a8da17SBarry Smith 116227a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 116327a8da17SBarry Smith 116427a8da17SBarry Smith @*/ 116527a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 116627a8da17SBarry Smith { 116727a8da17SBarry Smith int ierr,(*f)(Mat,int *); 116827a8da17SBarry Smith 116927a8da17SBarry Smith PetscFunctionBegin; 117027a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 117127a8da17SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f); 117227a8da17SBarry Smith CHKERRQ(ierr); 117327a8da17SBarry Smith if (f) { 117427a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 117527a8da17SBarry Smith } else { 117627a8da17SBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 117727a8da17SBarry Smith } 117827a8da17SBarry Smith PetscFunctionReturn(0); 117927a8da17SBarry Smith } 118027a8da17SBarry Smith 11812593348eSBarry Smith /* -------------------------------------------------------------------*/ 1182cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1183cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1184cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1185cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1186cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 1187cc2dc46cSBarry Smith MatMultTrans_SeqBAIJ, 1188cc2dc46cSBarry Smith MatMultTransAdd_SeqBAIJ, 1189cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1190cc2dc46cSBarry Smith 0, 1191cc2dc46cSBarry Smith 0, 1192cc2dc46cSBarry Smith 0, 1193cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1194cc2dc46cSBarry Smith 0, 1195b6490206SBarry Smith 0, 1196f2501298SSatish Balay MatTranspose_SeqBAIJ, 1197cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1198cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1199cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1200cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1201cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1202b6490206SBarry Smith 0, 1203cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1204cc2dc46cSBarry Smith 0, 1205cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1206cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1207cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1208cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1209cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1210cc2dc46cSBarry Smith 0, 1211cc2dc46cSBarry Smith 0, 1212cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1213cc2dc46cSBarry Smith MatGetSize_SeqBAIJ, 1214cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1215cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1216cc2dc46cSBarry Smith 0, 1217cc2dc46cSBarry Smith 0, 1218cc2dc46cSBarry Smith 0, 12192e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1220cc2dc46cSBarry Smith 0, 1221cc2dc46cSBarry Smith 0, 1222cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1223cc2dc46cSBarry Smith 0, 1224cc2dc46cSBarry Smith 0, 1225cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1226cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1227cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1228cc2dc46cSBarry Smith 0, 1229cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1230cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1231cc2dc46cSBarry Smith 0, 1232cc2dc46cSBarry Smith 0, 1233cc2dc46cSBarry Smith 0, 1234cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 12353b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 123692c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1237cc2dc46cSBarry Smith 0, 1238cc2dc46cSBarry Smith 0, 1239cc2dc46cSBarry Smith 0, 1240cc2dc46cSBarry Smith 0, 1241cc2dc46cSBarry Smith 0, 1242cc2dc46cSBarry Smith 0, 1243d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1244cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1245cc2dc46cSBarry Smith 0, 1246cc2dc46cSBarry Smith 0, 1247cc2dc46cSBarry Smith MatGetMaps_Petsc}; 12482593348eSBarry Smith 1249*7b2a1423SBarry Smith #include "pc.h" 1250*7b2a1423SBarry Smith EXTERN_C_BEGIN 1251*7b2a1423SBarry Smith extern int PCSetUp_BJacobi_BAIJ(PC); 1252*7b2a1423SBarry Smith EXTERN_C_END 1253*7b2a1423SBarry Smith 12545615d1e5SSatish Balay #undef __FUNC__ 12555615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ" 12562593348eSBarry Smith /*@C 125744cd7ae7SLois Curfman McInnes MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 125844cd7ae7SLois Curfman McInnes compressed row) format. For good matrix assembly performance the 125944cd7ae7SLois Curfman McInnes user should preallocate the matrix storage by setting the parameter nz 12602bd5e0b2SLois Curfman McInnes (or the array nzz). By setting these parameters accurately, performance 12612bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 12622593348eSBarry Smith 1263db81eaa0SLois Curfman McInnes Collective on MPI_Comm 1264db81eaa0SLois Curfman McInnes 12652593348eSBarry Smith Input Parameters: 1266db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 1267b6490206SBarry Smith . bs - size of block 12682593348eSBarry Smith . m - number of rows 12692593348eSBarry Smith . n - number of columns 1270b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1271db81eaa0SLois Curfman McInnes - nzz - array containing the number of block nonzeros in the various block rows 12722bd5e0b2SLois Curfman McInnes (possibly different for each block row) or PETSC_NULL 12732593348eSBarry Smith 12742593348eSBarry Smith Output Parameter: 12752593348eSBarry Smith . A - the matrix 12762593348eSBarry Smith 12770513a670SBarry Smith Options Database Keys: 1278db81eaa0SLois Curfman McInnes . -mat_no_unroll - uses code that does not unroll the loops in the 1279db81eaa0SLois Curfman McInnes block calculations (much slower) 1280db81eaa0SLois Curfman McInnes . -mat_block_size - size of the blocks to use 12810513a670SBarry Smith 12822593348eSBarry Smith Notes: 128344cd7ae7SLois Curfman McInnes The block AIJ format is fully compatible with standard Fortran 77 12842593348eSBarry Smith storage. That is, the stored row and column indices can begin at 128544cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 12862593348eSBarry Smith 12872593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 12882593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 12892593348eSBarry Smith allocation. For additional details, see the users manual chapter on 12906da5968aSLois Curfman McInnes matrices. 12912593348eSBarry Smith 1292db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 12932593348eSBarry Smith @*/ 1294b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 12952593348eSBarry Smith { 12962593348eSBarry Smith Mat B; 1297b6490206SBarry Smith Mat_SeqBAIJ *b; 12983b2fbd54SBarry Smith int i,len,ierr,flg,mbs=m/bs,nbs=n/bs,bs2=bs*bs,size; 12993b2fbd54SBarry Smith 13003a40ed3dSBarry Smith PetscFunctionBegin; 13013b2fbd54SBarry Smith MPI_Comm_size(comm,&size); 1302a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1"); 1303b6490206SBarry Smith 13040513a670SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 13050513a670SBarry Smith 13063a40ed3dSBarry Smith if (mbs*bs!=m || nbs*bs!=n) { 1307a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize"); 13083a40ed3dSBarry Smith } 13092593348eSBarry Smith 13102593348eSBarry Smith *A = 0; 13113f1db9ecSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",comm,MatDestroy,MatView); 13122593348eSBarry Smith PLogObjectCreate(B); 1313b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 131444cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_SeqBAIJ)); 1315cc2dc46cSBarry Smith PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); 13161a6a6d98SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg); CHKERRQ(ierr); 13171a6a6d98SBarry Smith if (!flg) { 13187fc0212eSBarry Smith switch (bs) { 13197fc0212eSBarry Smith case 1: 1320f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1321f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1322f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1323f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 13247fc0212eSBarry Smith break; 13254eeb42bcSBarry Smith case 2: 1326f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1327f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1328f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1329f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 13306d84be18SBarry Smith break; 1331f327dd97SBarry Smith case 3: 1332f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1333f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1334f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1335f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 13364eeb42bcSBarry Smith break; 13376d84be18SBarry Smith case 4: 1338f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1339f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1340f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1341f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 13426d84be18SBarry Smith break; 13436d84be18SBarry Smith case 5: 1344f830108cSBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1345f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1346f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1347f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 13486d84be18SBarry Smith break; 134948e9ddb2SSatish Balay case 7: 1350f830108cSBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1351f830108cSBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1352f830108cSBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 135348e9ddb2SSatish Balay break; 13547fc0212eSBarry Smith } 13551a6a6d98SBarry Smith } 1356e1311b90SBarry Smith B->ops->destroy = MatDestroy_SeqBAIJ; 1357e1311b90SBarry Smith B->ops->view = MatView_SeqBAIJ; 13582593348eSBarry Smith B->factor = 0; 13592593348eSBarry Smith B->lupivotthreshold = 1.0; 136090f02eecSBarry Smith B->mapping = 0; 13612593348eSBarry Smith b->row = 0; 13622593348eSBarry Smith b->col = 0; 1363e51c0b9cSSatish Balay b->icol = 0; 13642593348eSBarry Smith b->reallocs = 0; 13652593348eSBarry Smith 136644cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 136744cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 1368a5ae1ecdSBarry Smith 13697413bad6SBarry Smith ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 13707413bad6SBarry Smith ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 1371a5ae1ecdSBarry Smith 1372b6490206SBarry Smith b->mbs = mbs; 1373f2501298SSatish Balay b->nbs = nbs; 1374b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 13752593348eSBarry Smith if (nnz == PETSC_NULL) { 1376119a934aSSatish Balay if (nz == PETSC_DEFAULT) nz = 5; 13772593348eSBarry Smith else if (nz <= 0) nz = 1; 1378b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 1379b6490206SBarry Smith nz = nz*mbs; 13803a40ed3dSBarry Smith } else { 13812593348eSBarry Smith nz = 0; 1382b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 13832593348eSBarry Smith } 13842593348eSBarry Smith 13852593348eSBarry Smith /* allocate the matrix space */ 13863f1db9ecSBarry Smith len = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (b->m+1)*sizeof(int); 13873f1db9ecSBarry Smith b->a = (MatScalar *) PetscMalloc( len ); CHKPTRQ(b->a); 13883f1db9ecSBarry Smith PetscMemzero(b->a,nz*bs2*sizeof(MatScalar)); 13897e67e3f9SSatish Balay b->j = (int *) (b->a + nz*bs2); 13902593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 13912593348eSBarry Smith b->i = b->j + nz; 13922593348eSBarry Smith b->singlemalloc = 1; 13932593348eSBarry Smith 1394de6a44a3SBarry Smith b->i[0] = 0; 1395b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 13962593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 13972593348eSBarry Smith } 13982593348eSBarry Smith 1399b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 1400b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 1401f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1402b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 14032593348eSBarry Smith 1404b6490206SBarry Smith b->bs = bs; 14059df24120SSatish Balay b->bs2 = bs2; 1406b6490206SBarry Smith b->mbs = mbs; 14072593348eSBarry Smith b->nz = 0; 140818e7b8e4SLois Curfman McInnes b->maxnz = nz*bs2; 14092593348eSBarry Smith b->sorted = 0; 14102593348eSBarry Smith b->roworiented = 1; 14112593348eSBarry Smith b->nonew = 0; 14122593348eSBarry Smith b->diag = 0; 14132593348eSBarry Smith b->solve_work = 0; 1414de6a44a3SBarry Smith b->mult_work = 0; 14152593348eSBarry Smith b->spptr = 0; 14164e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 14174e220ebcSLois Curfman McInnes 14182593348eSBarry Smith *A = B; 14192593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 14202593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 142127a8da17SBarry Smith 142227a8da17SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 142327a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 142427a8da17SBarry Smith (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 1425*7b2a1423SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PCSetUp_BJacobi_C", 1426*7b2a1423SBarry Smith "PCSetUp_BJacobi_BAIJ", 1427*7b2a1423SBarry Smith (void*)PCSetUp_BJacobi_BAIJ);CHKERRQ(ierr); 142827a8da17SBarry Smith 14293a40ed3dSBarry Smith PetscFunctionReturn(0); 14302593348eSBarry Smith } 14312593348eSBarry Smith 14325615d1e5SSatish Balay #undef __FUNC__ 14332e8a6d31SBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ" 14342e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 14352593348eSBarry Smith { 14362593348eSBarry Smith Mat C; 1437b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 143827a8da17SBarry Smith int i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1439de6a44a3SBarry Smith 14403a40ed3dSBarry Smith PetscFunctionBegin; 1441a8c6a408SBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix"); 14422593348eSBarry Smith 14432593348eSBarry Smith *B = 0; 14443f1db9ecSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",A->comm,MatDestroy,MatView); 14452593348eSBarry Smith PLogObjectCreate(C); 1446b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 1447c3c66ee5SSatish Balay PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps)); 1448e1311b90SBarry Smith C->ops->destroy = MatDestroy_SeqBAIJ; 1449e1311b90SBarry Smith C->ops->view = MatView_SeqBAIJ; 14502593348eSBarry Smith C->factor = A->factor; 14512593348eSBarry Smith c->row = 0; 14522593348eSBarry Smith c->col = 0; 14532593348eSBarry Smith C->assembled = PETSC_TRUE; 14542593348eSBarry Smith 145544cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 145644cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 145744cd7ae7SLois Curfman McInnes C->M = a->m; 145844cd7ae7SLois Curfman McInnes C->N = a->n; 145944cd7ae7SLois Curfman McInnes 1460b6490206SBarry Smith c->bs = a->bs; 14619df24120SSatish Balay c->bs2 = a->bs2; 1462b6490206SBarry Smith c->mbs = a->mbs; 1463b6490206SBarry Smith c->nbs = a->nbs; 14642593348eSBarry Smith 1465b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 1466b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 1467b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 14682593348eSBarry Smith c->imax[i] = a->imax[i]; 14692593348eSBarry Smith c->ilen[i] = a->ilen[i]; 14702593348eSBarry Smith } 14712593348eSBarry Smith 14722593348eSBarry Smith /* allocate the matrix space */ 14732593348eSBarry Smith c->singlemalloc = 1; 14743f1db9ecSBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int)); 14753f1db9ecSBarry Smith c->a = (MatScalar *) PetscMalloc( len ); CHKPTRQ(c->a); 14767e67e3f9SSatish Balay c->j = (int *) (c->a + nz*bs2); 1477de6a44a3SBarry Smith c->i = c->j + nz; 1478b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 1479b6490206SBarry Smith if (mbs > 0) { 1480de6a44a3SBarry Smith PetscMemcpy(c->j,a->j,nz*sizeof(int)); 14812e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 14823f1db9ecSBarry Smith PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar)); 14832e8a6d31SBarry Smith } else { 14843f1db9ecSBarry Smith PetscMemzero(c->a,bs2*nz*sizeof(MatScalar)); 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; 1507*7b2a1423SBarry Smith ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 15083a40ed3dSBarry Smith PetscFunctionReturn(0); 15092593348eSBarry Smith } 15102593348eSBarry Smith 15115615d1e5SSatish Balay #undef __FUNC__ 15125615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ" 151319bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A) 15142593348eSBarry Smith { 1515b6490206SBarry Smith Mat_SeqBAIJ *a; 15162593348eSBarry Smith Mat B; 1517de6a44a3SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg; 1518b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 151935aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1520a7c10996SSatish Balay int *masked, nmask,tmp,bs2,ishift; 1521b6490206SBarry Smith Scalar *aa; 152219bcc07fSBarry Smith MPI_Comm comm = ((PetscObject) viewer)->comm; 15232593348eSBarry Smith 15243a40ed3dSBarry Smith PetscFunctionBegin; 15251a6a6d98SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,&flg);CHKERRQ(ierr); 1526de6a44a3SBarry Smith bs2 = bs*bs; 1527b6490206SBarry Smith 15282593348eSBarry Smith MPI_Comm_size(comm,&size); 1529cc0fae11SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor"); 153090ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 15310752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr); 1532a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object"); 15332593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 15342593348eSBarry Smith 1535d64ed03dSBarry Smith if (header[3] < 0) { 1536a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ"); 1537d64ed03dSBarry Smith } 1538d64ed03dSBarry Smith 1539a8c6a408SBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices"); 154035aab85fSBarry Smith 154135aab85fSBarry Smith /* 154235aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 154335aab85fSBarry Smith divisible by the blocksize 154435aab85fSBarry Smith */ 1545b6490206SBarry Smith mbs = M/bs; 154635aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 154735aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 154835aab85fSBarry Smith else mbs++; 154935aab85fSBarry Smith if (extra_rows) { 1550537820f0SBarry Smith PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 155135aab85fSBarry Smith } 1552b6490206SBarry Smith 15532593348eSBarry Smith /* read in row lengths */ 155435aab85fSBarry Smith rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths); 15550752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr); 155635aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1; 15572593348eSBarry Smith 1558b6490206SBarry Smith /* read in column indices */ 155935aab85fSBarry Smith jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj); 15600752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT); CHKERRQ(ierr); 156135aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i; 1562b6490206SBarry Smith 1563b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1564b6490206SBarry Smith browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths); 1565b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 156635aab85fSBarry Smith mask = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask); 156735aab85fSBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 156835aab85fSBarry Smith masked = mask + mbs; 1569b6490206SBarry Smith rowcount = 0; nzcount = 0; 1570b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 157135aab85fSBarry Smith nmask = 0; 1572b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1573b6490206SBarry Smith kmax = rowlengths[rowcount]; 1574b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 157535aab85fSBarry Smith tmp = jj[nzcount++]/bs; 157635aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1577b6490206SBarry Smith } 1578b6490206SBarry Smith rowcount++; 1579b6490206SBarry Smith } 158035aab85fSBarry Smith browlengths[i] += nmask; 158135aab85fSBarry Smith /* zero out the mask elements we set */ 158235aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1583b6490206SBarry Smith } 1584b6490206SBarry Smith 15852593348eSBarry Smith /* create our matrix */ 15863eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 15872593348eSBarry Smith B = *A; 1588b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 15892593348eSBarry Smith 15902593348eSBarry Smith /* set matrix "i" values */ 1591de6a44a3SBarry Smith a->i[0] = 0; 1592b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 1593b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1594b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 15952593348eSBarry Smith } 1596b6490206SBarry Smith a->nz = 0; 1597b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 15982593348eSBarry Smith 1599b6490206SBarry Smith /* read in nonzero values */ 160035aab85fSBarry Smith aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa); 16010752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR); CHKERRQ(ierr); 160235aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0; 1603b6490206SBarry Smith 1604b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1605b6490206SBarry Smith nzcount = 0; jcount = 0; 1606b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 1607b6490206SBarry Smith nzcountb = nzcount; 160835aab85fSBarry Smith nmask = 0; 1609b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1610b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1611b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 161235aab85fSBarry Smith tmp = jj[nzcount++]/bs; 161335aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1614b6490206SBarry Smith } 1615b6490206SBarry Smith rowcount++; 1616b6490206SBarry Smith } 1617de6a44a3SBarry Smith /* sort the masked values */ 161877c4ece6SBarry Smith PetscSortInt(nmask,masked); 1619de6a44a3SBarry Smith 1620b6490206SBarry Smith /* set "j" values into matrix */ 1621b6490206SBarry Smith maskcount = 1; 162235aab85fSBarry Smith for ( j=0; j<nmask; j++ ) { 162335aab85fSBarry Smith a->j[jcount++] = masked[j]; 1624de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1625b6490206SBarry Smith } 1626b6490206SBarry Smith /* set "a" values into matrix */ 1627de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1628b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1629b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1630b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 1631de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1632de6a44a3SBarry Smith block = mask[tmp] - 1; 1633de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1634de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1635b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 1636b6490206SBarry Smith } 1637b6490206SBarry Smith } 163835aab85fSBarry Smith /* zero out the mask elements we set */ 163935aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1640b6490206SBarry Smith } 1641a8c6a408SBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix"); 1642b6490206SBarry Smith 1643b6490206SBarry Smith PetscFree(rowlengths); 1644b6490206SBarry Smith PetscFree(browlengths); 1645b6490206SBarry Smith PetscFree(aa); 1646b6490206SBarry Smith PetscFree(jj); 1647b6490206SBarry Smith PetscFree(mask); 1648b6490206SBarry Smith 1649b6490206SBarry Smith B->assembled = PETSC_TRUE; 1650de6a44a3SBarry Smith 16519c01be13SBarry Smith ierr = MatView_Private(B); CHKERRQ(ierr); 16523a40ed3dSBarry Smith PetscFunctionReturn(0); 16532593348eSBarry Smith } 16542593348eSBarry Smith 16552593348eSBarry Smith 16562593348eSBarry Smith 1657