1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*d3825aa8SBarry Smith static char vcid[] = "$Id: baij.c,v 1.123 1998/01/14 02:41:43 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 103369ce9aSBarry Smith #include "pinclude/pviewer.h" 113369ce9aSBarry Smith #include "sys.h" 1270f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h" 131a6a6d98SBarry Smith #include "src/vec/vecimpl.h" 141a6a6d98SBarry Smith #include "src/inline/spops.h" 152593348eSBarry Smith #include "petsc.h" 163b547af2SSatish Balay 172d61bbb3SSatish Balay #define CHUNKSIZE 10 18de6a44a3SBarry Smith 195615d1e5SSatish Balay #undef __FUNC__ 205615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqBAIJ" 21de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A) 22de6a44a3SBarry Smith { 23de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 247fc0212eSBarry Smith int i,j, *diag, m = a->mbs; 25de6a44a3SBarry Smith 263a40ed3dSBarry Smith PetscFunctionBegin; 27de6a44a3SBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 28de6a44a3SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 297fc0212eSBarry Smith for ( i=0; i<m; i++ ) { 30de6a44a3SBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 31de6a44a3SBarry Smith if (a->j[j] == i) { 32de6a44a3SBarry Smith diag[i] = j; 33de6a44a3SBarry Smith break; 34de6a44a3SBarry Smith } 35de6a44a3SBarry Smith } 36de6a44a3SBarry Smith } 37de6a44a3SBarry Smith a->diag = diag; 383a40ed3dSBarry Smith PetscFunctionReturn(0); 39de6a44a3SBarry Smith } 402593348eSBarry Smith 412593348eSBarry Smith 423b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 433b2fbd54SBarry Smith 445615d1e5SSatish Balay #undef __FUNC__ 455615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqBAIJ" 463b2fbd54SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 473b2fbd54SBarry Smith PetscTruth *done) 483b2fbd54SBarry Smith { 493b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 503b2fbd54SBarry Smith int ierr, n = a->mbs,i; 513b2fbd54SBarry Smith 523a40ed3dSBarry Smith PetscFunctionBegin; 533b2fbd54SBarry Smith *nn = n; 543a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 553b2fbd54SBarry Smith if (symmetric) { 563b2fbd54SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 573b2fbd54SBarry Smith } else if (oshift == 1) { 583b2fbd54SBarry Smith /* temporarily add 1 to i and j indices */ 593b2fbd54SBarry Smith int nz = a->i[n] + 1; 603b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]++; 613b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]++; 623b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 633b2fbd54SBarry Smith } else { 643b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 653b2fbd54SBarry Smith } 663b2fbd54SBarry Smith 673a40ed3dSBarry Smith PetscFunctionReturn(0); 683b2fbd54SBarry Smith } 693b2fbd54SBarry Smith 705615d1e5SSatish Balay #undef __FUNC__ 71d4bb536fSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ" 723b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 733b2fbd54SBarry Smith PetscTruth *done) 743b2fbd54SBarry Smith { 753b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 763b2fbd54SBarry Smith int i,n = a->mbs; 773b2fbd54SBarry Smith 783a40ed3dSBarry Smith PetscFunctionBegin; 793a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 803b2fbd54SBarry Smith if (symmetric) { 813b2fbd54SBarry Smith PetscFree(*ia); 823b2fbd54SBarry Smith PetscFree(*ja); 83af5da2bfSBarry Smith } else if (oshift == 1) { 843b2fbd54SBarry Smith int nz = a->i[n]; 853b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) a->j[i]--; 863b2fbd54SBarry Smith for ( i=0; i<n+1; i++ ) a->i[i]--; 873b2fbd54SBarry Smith } 883a40ed3dSBarry Smith PetscFunctionReturn(0); 893b2fbd54SBarry Smith } 903b2fbd54SBarry Smith 912d61bbb3SSatish Balay #undef __FUNC__ 922d61bbb3SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqBAIJ" 932d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat, int *bs) 942d61bbb3SSatish Balay { 952d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *) mat->data; 962d61bbb3SSatish Balay 972d61bbb3SSatish Balay PetscFunctionBegin; 982d61bbb3SSatish Balay *bs = baij->bs; 992d61bbb3SSatish Balay PetscFunctionReturn(0); 1002d61bbb3SSatish Balay } 1012d61bbb3SSatish Balay 1022d61bbb3SSatish Balay 1032d61bbb3SSatish Balay #undef __FUNC__ 1042d61bbb3SSatish Balay #define __FUNC__ "MatDestroy_SeqBAIJ" 1052d61bbb3SSatish Balay int MatDestroy_SeqBAIJ(PetscObject obj) 1062d61bbb3SSatish Balay { 1072d61bbb3SSatish Balay Mat A = (Mat) obj; 1082d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1092d61bbb3SSatish Balay 1102d61bbb3SSatish Balay #if defined(USE_PETSC_LOG) 1112d61bbb3SSatish Balay PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 1122d61bbb3SSatish Balay #endif 1132d61bbb3SSatish Balay PetscFree(a->a); 1142d61bbb3SSatish Balay if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 1152d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 1162d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 1172d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 1182d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 1192d61bbb3SSatish Balay if (a->mult_work) PetscFree(a->mult_work); 1202d61bbb3SSatish Balay PetscFree(a); 1212d61bbb3SSatish Balay PLogObjectDestroy(A); 1222d61bbb3SSatish Balay PetscHeaderDestroy(A); 1232d61bbb3SSatish Balay PetscFunctionReturn(0); 1242d61bbb3SSatish Balay } 1252d61bbb3SSatish Balay 1262d61bbb3SSatish Balay #undef __FUNC__ 1272d61bbb3SSatish Balay #define __FUNC__ "MatSetOption_SeqBAIJ" 1282d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1292d61bbb3SSatish Balay { 1302d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1312d61bbb3SSatish Balay 1322d61bbb3SSatish Balay PetscFunctionBegin; 1332d61bbb3SSatish Balay if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 1342d61bbb3SSatish Balay else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 1352d61bbb3SSatish Balay else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 1362d61bbb3SSatish Balay else if (op == MAT_COLUMNS_UNSORTED) a->sorted = 0; 1372d61bbb3SSatish Balay else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 1382d61bbb3SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERROR) a->nonew = -1; 1392d61bbb3SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERROR) a->nonew = -2; 1402d61bbb3SSatish Balay else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 1412d61bbb3SSatish Balay else if (op == MAT_ROWS_SORTED || 1422d61bbb3SSatish Balay op == MAT_ROWS_UNSORTED || 1432d61bbb3SSatish Balay op == MAT_SYMMETRIC || 1442d61bbb3SSatish Balay op == MAT_STRUCTURALLY_SYMMETRIC || 1452d61bbb3SSatish Balay op == MAT_YES_NEW_DIAGONALS || 1462d61bbb3SSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES) { 147981c4779SBarry Smith PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 1482d61bbb3SSatish Balay } else if (op == MAT_NO_NEW_DIAGONALS) { 1492d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 1502d61bbb3SSatish Balay } else { 1512d61bbb3SSatish Balay SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 1522d61bbb3SSatish Balay } 1532d61bbb3SSatish Balay PetscFunctionReturn(0); 1542d61bbb3SSatish Balay } 1552d61bbb3SSatish Balay 1562d61bbb3SSatish Balay 1572d61bbb3SSatish Balay #undef __FUNC__ 1582d61bbb3SSatish Balay #define __FUNC__ "MatGetSize_SeqBAIJ" 1592d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n) 1602d61bbb3SSatish Balay { 1612d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1622d61bbb3SSatish Balay 1632d61bbb3SSatish Balay PetscFunctionBegin; 1642d61bbb3SSatish Balay if (m) *m = a->m; 1652d61bbb3SSatish Balay if (n) *n = a->n; 1662d61bbb3SSatish Balay PetscFunctionReturn(0); 1672d61bbb3SSatish Balay } 1682d61bbb3SSatish Balay 1692d61bbb3SSatish Balay #undef __FUNC__ 1702d61bbb3SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ" 1712d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 1722d61bbb3SSatish Balay { 1732d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1742d61bbb3SSatish Balay 1752d61bbb3SSatish Balay PetscFunctionBegin; 1762d61bbb3SSatish Balay *m = 0; *n = a->m; 1772d61bbb3SSatish Balay PetscFunctionReturn(0); 1782d61bbb3SSatish Balay } 1792d61bbb3SSatish Balay 1802d61bbb3SSatish Balay #undef __FUNC__ 1812d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ" 1822d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 1832d61bbb3SSatish Balay { 1842d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 1852d61bbb3SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2; 1862d61bbb3SSatish Balay Scalar *aa,*v_i,*aa_i; 1872d61bbb3SSatish Balay 1882d61bbb3SSatish Balay PetscFunctionBegin; 1892d61bbb3SSatish Balay bs = a->bs; 1902d61bbb3SSatish Balay ai = a->i; 1912d61bbb3SSatish Balay aj = a->j; 1922d61bbb3SSatish Balay aa = a->a; 1932d61bbb3SSatish Balay bs2 = a->bs2; 1942d61bbb3SSatish Balay 1952d61bbb3SSatish Balay if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 1962d61bbb3SSatish Balay 1972d61bbb3SSatish Balay bn = row/bs; /* Block number */ 1982d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 1992d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2002d61bbb3SSatish Balay *nz = bs*M; 2012d61bbb3SSatish Balay 2022d61bbb3SSatish Balay if (v) { 2032d61bbb3SSatish Balay *v = 0; 2042d61bbb3SSatish Balay if (*nz) { 2052d61bbb3SSatish Balay *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v); 2062d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2072d61bbb3SSatish Balay v_i = *v + i*bs; 2082d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2092d61bbb3SSatish Balay for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];} 2102d61bbb3SSatish Balay } 2112d61bbb3SSatish Balay } 2122d61bbb3SSatish Balay } 2132d61bbb3SSatish Balay 2142d61bbb3SSatish Balay if (idx) { 2152d61bbb3SSatish Balay *idx = 0; 2162d61bbb3SSatish Balay if (*nz) { 2172d61bbb3SSatish Balay *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 2182d61bbb3SSatish Balay for ( i=0; i<M; i++ ) { /* for each block in the block row */ 2192d61bbb3SSatish Balay idx_i = *idx + i*bs; 2202d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2212d61bbb3SSatish Balay for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;} 2222d61bbb3SSatish Balay } 2232d61bbb3SSatish Balay } 2242d61bbb3SSatish Balay } 2252d61bbb3SSatish Balay PetscFunctionReturn(0); 2262d61bbb3SSatish Balay } 2272d61bbb3SSatish Balay 2282d61bbb3SSatish Balay #undef __FUNC__ 2292d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ" 2302d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2312d61bbb3SSatish Balay { 2322d61bbb3SSatish Balay PetscFunctionBegin; 2332d61bbb3SSatish Balay if (idx) {if (*idx) PetscFree(*idx);} 2342d61bbb3SSatish Balay if (v) {if (*v) PetscFree(*v);} 2352d61bbb3SSatish Balay PetscFunctionReturn(0); 2362d61bbb3SSatish Balay } 2372d61bbb3SSatish Balay 2382d61bbb3SSatish Balay #undef __FUNC__ 2392d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ" 2402d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2412d61bbb3SSatish Balay { 2422d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2432d61bbb3SSatish Balay Mat C; 2442d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 2452d61bbb3SSatish Balay int *rows,*cols,bs2=a->bs2; 2462d61bbb3SSatish Balay Scalar *array=a->a; 2472d61bbb3SSatish Balay 2482d61bbb3SSatish Balay PetscFunctionBegin; 2492d61bbb3SSatish Balay if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place"); 2502d61bbb3SSatish Balay col = (int *) PetscMalloc((1+nbs)*sizeof(int)); CHKPTRQ(col); 2512d61bbb3SSatish Balay PetscMemzero(col,(1+nbs)*sizeof(int)); 2522d61bbb3SSatish Balay 2532d61bbb3SSatish Balay for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1; 2542d61bbb3SSatish Balay ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C); CHKERRQ(ierr); 2552d61bbb3SSatish Balay PetscFree(col); 2562d61bbb3SSatish Balay rows = (int *) PetscMalloc(2*bs*sizeof(int)); CHKPTRQ(rows); 2572d61bbb3SSatish Balay cols = rows + bs; 2582d61bbb3SSatish Balay for ( i=0; i<mbs; i++ ) { 2592d61bbb3SSatish Balay cols[0] = i*bs; 2602d61bbb3SSatish Balay for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1; 2612d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 2622d61bbb3SSatish Balay for ( j=0; j<len; j++ ) { 2632d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 2642d61bbb3SSatish Balay for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1; 2652d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES); CHKERRQ(ierr); 2662d61bbb3SSatish Balay array += bs2; 2672d61bbb3SSatish Balay } 2682d61bbb3SSatish Balay } 2692d61bbb3SSatish Balay PetscFree(rows); 2702d61bbb3SSatish Balay 2712d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2722d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2732d61bbb3SSatish Balay 2742d61bbb3SSatish Balay if (B != PETSC_NULL) { 2752d61bbb3SSatish Balay *B = C; 2762d61bbb3SSatish Balay } else { 2772d61bbb3SSatish Balay /* This isn't really an in-place transpose */ 2782d61bbb3SSatish Balay PetscFree(a->a); 2792d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);} 2802d61bbb3SSatish Balay if (a->diag) PetscFree(a->diag); 2812d61bbb3SSatish Balay if (a->ilen) PetscFree(a->ilen); 2822d61bbb3SSatish Balay if (a->imax) PetscFree(a->imax); 2832d61bbb3SSatish Balay if (a->solve_work) PetscFree(a->solve_work); 2842d61bbb3SSatish Balay PetscFree(a); 2852d61bbb3SSatish Balay PetscMemcpy(A,C,sizeof(struct _p_Mat)); 2862d61bbb3SSatish Balay PetscHeaderDestroy(C); 2872d61bbb3SSatish Balay } 2882d61bbb3SSatish Balay PetscFunctionReturn(0); 2892d61bbb3SSatish Balay } 2902d61bbb3SSatish Balay 2912d61bbb3SSatish Balay 2922d61bbb3SSatish Balay 2933b2fbd54SBarry Smith 2945615d1e5SSatish Balay #undef __FUNC__ 295d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary" 296b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer) 2972593348eSBarry Smith { 298b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 2999df24120SSatish Balay int i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 300b6490206SBarry Smith Scalar *aa; 3012593348eSBarry Smith 3023a40ed3dSBarry Smith PetscFunctionBegin; 30390ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 3042593348eSBarry Smith col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 3052593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3063b2fbd54SBarry Smith 3072593348eSBarry Smith col_lens[1] = a->m; 3082593348eSBarry Smith col_lens[2] = a->n; 3097e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3102593348eSBarry Smith 3112593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 312b6490206SBarry Smith count = 0; 313b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 314b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 315b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 316b6490206SBarry Smith } 3172593348eSBarry Smith } 3180752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr); 3192593348eSBarry Smith PetscFree(col_lens); 3202593348eSBarry Smith 3212593348eSBarry Smith /* store column indices (zero start index) */ 32266963ce1SSatish Balay jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) ); CHKPTRQ(jj); 323b6490206SBarry Smith count = 0; 324b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 325b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 326b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 327b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 328b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3292593348eSBarry Smith } 3302593348eSBarry Smith } 331b6490206SBarry Smith } 332b6490206SBarry Smith } 3330752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0); CHKERRQ(ierr); 334b6490206SBarry Smith PetscFree(jj); 3352593348eSBarry Smith 3362593348eSBarry Smith /* store nonzero values */ 33766963ce1SSatish Balay aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar)); CHKPTRQ(aa); 338b6490206SBarry Smith count = 0; 339b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 340b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 341b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 342b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 3437e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 344b6490206SBarry Smith } 345b6490206SBarry Smith } 346b6490206SBarry Smith } 347b6490206SBarry Smith } 3480752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0); CHKERRQ(ierr); 349b6490206SBarry Smith PetscFree(aa); 3503a40ed3dSBarry Smith PetscFunctionReturn(0); 3512593348eSBarry Smith } 3522593348eSBarry Smith 3535615d1e5SSatish Balay #undef __FUNC__ 354d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII" 355b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer) 3562593348eSBarry Smith { 357b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 3589df24120SSatish Balay int ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2; 3592593348eSBarry Smith FILE *fd; 3602593348eSBarry Smith char *outputname; 3612593348eSBarry Smith 3623a40ed3dSBarry Smith PetscFunctionBegin; 36390ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 3642593348eSBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname);CHKERRQ(ierr); 36590ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 366639f9d9dSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) { 3677ddc982cSLois Curfman McInnes fprintf(fd," block size is %d\n",bs); 3682593348eSBarry Smith } 369639f9d9dSBarry Smith else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 370a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported"); 3712593348eSBarry Smith } 372639f9d9dSBarry Smith else if (format == VIEWER_FORMAT_ASCII_COMMON) { 37344cd7ae7SLois Curfman McInnes for ( i=0; i<a->mbs; i++ ) { 37444cd7ae7SLois Curfman McInnes for ( j=0; j<bs; j++ ) { 37544cd7ae7SLois Curfman McInnes fprintf(fd,"row %d:",i*bs+j); 37644cd7ae7SLois Curfman McInnes for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 37744cd7ae7SLois Curfman McInnes for ( l=0; l<bs; l++ ) { 3783a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 379766eeae4SLois Curfman McInnes if (imag(a->a[bs2*k + l*bs + j]) > 0.0 && real(a->a[bs2*k + l*bs + j]) != 0.0) 38044cd7ae7SLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 38144cd7ae7SLois Curfman McInnes real(a->a[bs2*k + l*bs + j]),imag(a->a[bs2*k + l*bs + j])); 382766eeae4SLois Curfman McInnes else if (imag(a->a[bs2*k + l*bs + j]) < 0.0 && real(a->a[bs2*k + l*bs + j]) != 0.0) 383766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 384766eeae4SLois Curfman McInnes real(a->a[bs2*k + l*bs + j]),-imag(a->a[bs2*k + l*bs + j])); 38544cd7ae7SLois Curfman McInnes else if (real(a->a[bs2*k + l*bs + j]) != 0.0) 38644cd7ae7SLois Curfman McInnes fprintf(fd," %d %g ",bs*a->j[k]+l,real(a->a[bs2*k + l*bs + j])); 38744cd7ae7SLois Curfman McInnes #else 38844cd7ae7SLois Curfman McInnes if (a->a[bs2*k + l*bs + j] != 0.0) 38944cd7ae7SLois Curfman McInnes fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 39044cd7ae7SLois Curfman McInnes #endif 39144cd7ae7SLois Curfman McInnes } 39244cd7ae7SLois Curfman McInnes } 39344cd7ae7SLois Curfman McInnes fprintf(fd,"\n"); 39444cd7ae7SLois Curfman McInnes } 39544cd7ae7SLois Curfman McInnes } 39644cd7ae7SLois Curfman McInnes } 3972593348eSBarry Smith else { 398b6490206SBarry Smith for ( i=0; i<a->mbs; i++ ) { 399b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 400b6490206SBarry Smith fprintf(fd,"row %d:",i*bs+j); 401b6490206SBarry Smith for ( k=a->i[i]; k<a->i[i+1]; k++ ) { 402b6490206SBarry Smith for ( l=0; l<bs; l++ ) { 4033a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 404766eeae4SLois Curfman McInnes if (imag(a->a[bs2*k + l*bs + j]) > 0.0) { 40588685aaeSLois Curfman McInnes fprintf(fd," %d %g + %g i",bs*a->j[k]+l, 4067e67e3f9SSatish Balay real(a->a[bs2*k + l*bs + j]),imag(a->a[bs2*k + l*bs + j])); 40788685aaeSLois Curfman McInnes } 408766eeae4SLois Curfman McInnes else if (imag(a->a[bs2*k + l*bs + j]) < 0.0) { 409766eeae4SLois Curfman McInnes fprintf(fd," %d %g - %g i",bs*a->j[k]+l, 410766eeae4SLois Curfman McInnes real(a->a[bs2*k + l*bs + j]),-imag(a->a[bs2*k + l*bs + j])); 411766eeae4SLois Curfman McInnes } 41288685aaeSLois Curfman McInnes else { 4137e67e3f9SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,real(a->a[bs2*k + l*bs + j])); 41488685aaeSLois Curfman McInnes } 41588685aaeSLois Curfman McInnes #else 4167e67e3f9SSatish Balay fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]); 41788685aaeSLois Curfman McInnes #endif 4182593348eSBarry Smith } 4192593348eSBarry Smith } 4202593348eSBarry Smith fprintf(fd,"\n"); 4212593348eSBarry Smith } 4222593348eSBarry Smith } 423b6490206SBarry Smith } 4242593348eSBarry Smith fflush(fd); 4253a40ed3dSBarry Smith PetscFunctionReturn(0); 4262593348eSBarry Smith } 4272593348eSBarry Smith 4285615d1e5SSatish Balay #undef __FUNC__ 429d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw" 4303270192aSSatish Balay static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer) 4313270192aSSatish Balay { 4323270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *) A->data; 4333270192aSSatish Balay int row,ierr,i,j,k,l,mbs=a->mbs,pause,color,bs=a->bs,bs2=a->bs2; 4343270192aSSatish Balay double xl,yl,xr,yr,w,h,xc,yc,scale = 1.0,x_l,x_r,y_l,y_r; 4353270192aSSatish Balay Scalar *aa; 4363270192aSSatish Balay Draw draw; 4373270192aSSatish Balay DrawButton button; 4383270192aSSatish Balay PetscTruth isnull; 4393270192aSSatish Balay 4403a40ed3dSBarry Smith PetscFunctionBegin; 4413a40ed3dSBarry Smith ierr = ViewerDrawGetDraw(viewer,&draw);CHKERRQ(ierr); 4423a40ed3dSBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 4433270192aSSatish Balay 4443270192aSSatish Balay xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 4453270192aSSatish Balay xr += w; yr += h; xl = -w; yl = -h; 4463270192aSSatish Balay ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 4473270192aSSatish Balay /* loop over matrix elements drawing boxes */ 4483270192aSSatish Balay color = DRAW_BLUE; 4493270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 4503270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 4513270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 4523270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4533270192aSSatish Balay aa = a->a + j*bs2; 4543270192aSSatish Balay for ( k=0; k<bs; k++ ) { 4553270192aSSatish Balay for ( l=0; l<bs; l++ ) { 4563270192aSSatish Balay if (PetscReal(*aa++) >= 0.) continue; 457b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 4583270192aSSatish Balay } 4593270192aSSatish Balay } 4603270192aSSatish Balay } 4613270192aSSatish Balay } 4623270192aSSatish Balay color = DRAW_CYAN; 4633270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 4643270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 4653270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 4663270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4673270192aSSatish Balay aa = a->a + j*bs2; 4683270192aSSatish Balay for ( k=0; k<bs; k++ ) { 4693270192aSSatish Balay for ( l=0; l<bs; l++ ) { 4703270192aSSatish Balay if (PetscReal(*aa++) != 0.) continue; 471b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 4723270192aSSatish Balay } 4733270192aSSatish Balay } 4743270192aSSatish Balay } 4753270192aSSatish Balay } 4763270192aSSatish Balay 4773270192aSSatish Balay color = DRAW_RED; 4783270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 4793270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 4803270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 4813270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4823270192aSSatish Balay aa = a->a + j*bs2; 4833270192aSSatish Balay for ( k=0; k<bs; k++ ) { 4843270192aSSatish Balay for ( l=0; l<bs; l++ ) { 4853270192aSSatish Balay if (PetscReal(*aa++) <= 0.) continue; 486b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 4873270192aSSatish Balay } 4883270192aSSatish Balay } 4893270192aSSatish Balay } 4903270192aSSatish Balay } 4913270192aSSatish Balay 49255843e3eSBarry Smith DrawSynchronizedFlush(draw); 4933270192aSSatish Balay DrawGetPause(draw,&pause); 4943a40ed3dSBarry Smith if (pause >= 0) { PetscSleep(pause); PetscFunctionReturn(0);} 4953270192aSSatish Balay 4963270192aSSatish Balay /* allow the matrix to zoom or shrink */ 49755843e3eSBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0); 4983270192aSSatish Balay while (button != BUTTON_RIGHT) { 49955843e3eSBarry Smith DrawSynchronizedClear(draw); 5003270192aSSatish Balay if (button == BUTTON_LEFT) scale = .5; 5013270192aSSatish Balay else if (button == BUTTON_CENTER) scale = 2.; 5023270192aSSatish Balay xl = scale*(xl + w - xc) + xc - w*scale; 5033270192aSSatish Balay xr = scale*(xr - w - xc) + xc + w*scale; 5043270192aSSatish Balay yl = scale*(yl + h - yc) + yc - h*scale; 5053270192aSSatish Balay yr = scale*(yr - h - yc) + yc + h*scale; 5063270192aSSatish Balay w *= scale; h *= scale; 5073270192aSSatish Balay ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 5083270192aSSatish Balay color = DRAW_BLUE; 5093270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5103270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5113270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5123270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5133270192aSSatish Balay aa = a->a + j*bs2; 5143270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5153270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5163270192aSSatish Balay if (PetscReal(*aa++) >= 0.) continue; 517b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5183270192aSSatish Balay } 5193270192aSSatish Balay } 5203270192aSSatish Balay } 5213270192aSSatish Balay } 5223270192aSSatish Balay color = DRAW_CYAN; 5233270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5243270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5253270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5263270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5273270192aSSatish Balay aa = a->a + j*bs2; 5283270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5293270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5303270192aSSatish Balay if (PetscReal(*aa++) != 0.) continue; 531b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5323270192aSSatish Balay } 5333270192aSSatish Balay } 5343270192aSSatish Balay } 5353270192aSSatish Balay } 5363270192aSSatish Balay 5373270192aSSatish Balay color = DRAW_RED; 5383270192aSSatish Balay for ( i=0,row=0; i<mbs; i++,row+=bs ) { 5393270192aSSatish Balay for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 5403270192aSSatish Balay y_l = a->m - row - 1.0; y_r = y_l + 1.0; 5413270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5423270192aSSatish Balay aa = a->a + j*bs2; 5433270192aSSatish Balay for ( k=0; k<bs; k++ ) { 5443270192aSSatish Balay for ( l=0; l<bs; l++ ) { 5453270192aSSatish Balay if (PetscReal(*aa++) <= 0.) continue; 546b34f160eSSatish Balay DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color); 5473270192aSSatish Balay } 5483270192aSSatish Balay } 5493270192aSSatish Balay } 5503270192aSSatish Balay } 55155843e3eSBarry Smith ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0); 5523270192aSSatish Balay } 5533a40ed3dSBarry Smith PetscFunctionReturn(0); 5543270192aSSatish Balay } 5553270192aSSatish Balay 5565615d1e5SSatish Balay #undef __FUNC__ 557d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ" 5588f6be9afSLois Curfman McInnes int MatView_SeqBAIJ(PetscObject obj,Viewer viewer) 5592593348eSBarry Smith { 5602593348eSBarry Smith Mat A = (Mat) obj; 56119bcc07fSBarry Smith ViewerType vtype; 56219bcc07fSBarry Smith int ierr; 5632593348eSBarry Smith 5643a40ed3dSBarry Smith PetscFunctionBegin; 56519bcc07fSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 56619bcc07fSBarry Smith if (vtype == MATLAB_VIEWER) { 567a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Matlab viewer not supported"); 5683a40ed3dSBarry Smith } else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){ 5693a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5703a40ed3dSBarry Smith } else if (vtype == BINARY_FILE_VIEWER) { 5713a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 5723a40ed3dSBarry Smith } else if (vtype == DRAW_VIEWER) { 5733a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 5742593348eSBarry Smith } 5753a40ed3dSBarry Smith PetscFunctionReturn(0); 5762593348eSBarry Smith } 577b6490206SBarry Smith 578cd0e1443SSatish Balay 5795615d1e5SSatish Balay #undef __FUNC__ 5802d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ" 5812d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 582cd0e1443SSatish Balay { 583cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 5842d61bbb3SSatish Balay int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 5852d61bbb3SSatish Balay int *ai = a->i, *ailen = a->ilen; 5862d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 5872d61bbb3SSatish Balay Scalar *ap, *aa = a->a, zero = 0.0; 588cd0e1443SSatish Balay 5893a40ed3dSBarry Smith PetscFunctionBegin; 5902d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over rows */ 591cd0e1443SSatish Balay row = im[k]; brow = row/bs; 592a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 593a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 5942d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 5952c3acbe9SBarry Smith nrow = ailen[brow]; 5962d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over columns */ 597a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 598a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 5992d61bbb3SSatish Balay col = in[l] ; 6002d61bbb3SSatish Balay bcol = col/bs; 6012d61bbb3SSatish Balay cidx = col%bs; 6022d61bbb3SSatish Balay ridx = row%bs; 6032d61bbb3SSatish Balay high = nrow; 6042d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6052d61bbb3SSatish Balay while (high-low > 5) { 606cd0e1443SSatish Balay t = (low+high)/2; 607cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 608cd0e1443SSatish Balay else low = t; 609cd0e1443SSatish Balay } 610cd0e1443SSatish Balay for ( i=low; i<high; i++ ) { 611cd0e1443SSatish Balay if (rp[i] > bcol) break; 612cd0e1443SSatish Balay if (rp[i] == bcol) { 6132d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6142d61bbb3SSatish Balay goto finished; 615cd0e1443SSatish Balay } 616cd0e1443SSatish Balay } 6172d61bbb3SSatish Balay *v++ = zero; 6182d61bbb3SSatish Balay finished:; 619cd0e1443SSatish Balay } 620cd0e1443SSatish Balay } 6213a40ed3dSBarry Smith PetscFunctionReturn(0); 622cd0e1443SSatish Balay } 623cd0e1443SSatish Balay 6242d61bbb3SSatish Balay 6255615d1e5SSatish Balay #undef __FUNC__ 62605a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 62792c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 62892c4ed94SBarry Smith { 62992c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 6308a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 631dd9472c6SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented; 632dd9472c6SBarry Smith int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval; 6330e324ae4SSatish Balay Scalar *ap,*value=v,*aa=a->a,*bap; 63492c4ed94SBarry Smith 6353a40ed3dSBarry Smith PetscFunctionBegin; 6360e324ae4SSatish Balay if (roworiented) { 6370e324ae4SSatish Balay stepval = (n-1)*bs; 6380e324ae4SSatish Balay } else { 6390e324ae4SSatish Balay stepval = (m-1)*bs; 6400e324ae4SSatish Balay } 64192c4ed94SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 64292c4ed94SBarry Smith row = im[k]; 6433a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 644a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 645a8c6a408SBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 64692c4ed94SBarry Smith #endif 64792c4ed94SBarry Smith rp = aj + ai[row]; 64892c4ed94SBarry Smith ap = aa + bs2*ai[row]; 64992c4ed94SBarry Smith rmax = imax[row]; 65092c4ed94SBarry Smith nrow = ailen[row]; 65192c4ed94SBarry Smith low = 0; 65292c4ed94SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 6533a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 654a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 655a8c6a408SBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 65692c4ed94SBarry Smith #endif 65792c4ed94SBarry Smith col = in[l]; 65892c4ed94SBarry Smith if (roworiented) { 6590e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 6600e324ae4SSatish Balay } else { 6610e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 66292c4ed94SBarry Smith } 66392c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 66492c4ed94SBarry Smith while (high-low > 7) { 66592c4ed94SBarry Smith t = (low+high)/2; 66692c4ed94SBarry Smith if (rp[t] > col) high = t; 66792c4ed94SBarry Smith else low = t; 66892c4ed94SBarry Smith } 66992c4ed94SBarry Smith for ( i=low; i<high; i++ ) { 67092c4ed94SBarry Smith if (rp[i] > col) break; 67192c4ed94SBarry Smith if (rp[i] == col) { 6728a84c255SSatish Balay bap = ap + bs2*i; 6730e324ae4SSatish Balay if (roworiented) { 6748a84c255SSatish Balay if (is == ADD_VALUES) { 675dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 676dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 6778a84c255SSatish Balay bap[jj] += *value++; 678dd9472c6SBarry Smith } 679dd9472c6SBarry Smith } 6800e324ae4SSatish Balay } else { 681dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 682dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 6830e324ae4SSatish Balay bap[jj] = *value++; 6848a84c255SSatish Balay } 685dd9472c6SBarry Smith } 686dd9472c6SBarry Smith } 6870e324ae4SSatish Balay } else { 6880e324ae4SSatish Balay if (is == ADD_VALUES) { 689dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 690dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 6910e324ae4SSatish Balay *bap++ += *value++; 692dd9472c6SBarry Smith } 693dd9472c6SBarry Smith } 6940e324ae4SSatish Balay } else { 695dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 696dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 6970e324ae4SSatish Balay *bap++ = *value++; 6980e324ae4SSatish Balay } 6998a84c255SSatish Balay } 700dd9472c6SBarry Smith } 701dd9472c6SBarry Smith } 702f1241b54SBarry Smith goto noinsert2; 70392c4ed94SBarry Smith } 70492c4ed94SBarry Smith } 70589280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 706a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 70792c4ed94SBarry Smith if (nrow >= rmax) { 70892c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 70992c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 71092c4ed94SBarry Smith Scalar *new_a; 71192c4ed94SBarry Smith 712a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 71389280ab3SLois Curfman McInnes 71492c4ed94SBarry Smith /* malloc new storage space */ 71592c4ed94SBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int); 71692c4ed94SBarry Smith new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 71792c4ed94SBarry Smith new_j = (int *) (new_a + bs2*new_nz); 71892c4ed94SBarry Smith new_i = new_j + new_nz; 71992c4ed94SBarry Smith 72092c4ed94SBarry Smith /* copy over old data into new slots */ 72192c4ed94SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 72292c4ed94SBarry Smith for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 72392c4ed94SBarry Smith PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int)); 72492c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 725dd9472c6SBarry Smith PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int)); 72692c4ed94SBarry Smith PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(Scalar)); 72792c4ed94SBarry Smith PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(Scalar)); 728dd9472c6SBarry Smith PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(Scalar)); 72992c4ed94SBarry Smith /* free up old matrix storage */ 73092c4ed94SBarry Smith PetscFree(a->a); 73192c4ed94SBarry Smith if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 73292c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 73392c4ed94SBarry Smith a->singlemalloc = 1; 73492c4ed94SBarry Smith 73592c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 73692c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 73792c4ed94SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar))); 73892c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 73992c4ed94SBarry Smith a->reallocs++; 74092c4ed94SBarry Smith a->nz++; 74192c4ed94SBarry Smith } 74292c4ed94SBarry Smith N = nrow++ - 1; 74392c4ed94SBarry Smith /* shift up all the later entries in this row */ 74492c4ed94SBarry Smith for ( ii=N; ii>=i; ii-- ) { 74592c4ed94SBarry Smith rp[ii+1] = rp[ii]; 74692c4ed94SBarry Smith PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar)); 74792c4ed94SBarry Smith } 74892c4ed94SBarry Smith if (N >= i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar)); 74992c4ed94SBarry Smith rp[i] = col; 7508a84c255SSatish Balay bap = ap + bs2*i; 7510e324ae4SSatish Balay if (roworiented) { 752dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval) { 753dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs ) { 7540e324ae4SSatish Balay bap[jj] = *value++; 755dd9472c6SBarry Smith } 756dd9472c6SBarry Smith } 7570e324ae4SSatish Balay } else { 758dd9472c6SBarry Smith for ( ii=0; ii<bs; ii++,value+=stepval ) { 759dd9472c6SBarry Smith for (jj=0; jj<bs; jj++ ) { 7600e324ae4SSatish Balay *bap++ = *value++; 7610e324ae4SSatish Balay } 762dd9472c6SBarry Smith } 763dd9472c6SBarry Smith } 764f1241b54SBarry Smith noinsert2:; 76592c4ed94SBarry Smith low = i; 76692c4ed94SBarry Smith } 76792c4ed94SBarry Smith ailen[row] = nrow; 76892c4ed94SBarry Smith } 7693a40ed3dSBarry Smith PetscFunctionReturn(0); 77092c4ed94SBarry Smith } 77192c4ed94SBarry Smith 772f2501298SSatish Balay 7735615d1e5SSatish Balay #undef __FUNC__ 7745615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ" 7758f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 776584200bdSSatish Balay { 777584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 778584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax; 779a7c10996SSatish Balay int m = a->m,*ip, N, *ailen = a->ilen; 78043ee02c3SBarry Smith int mbs = a->mbs, bs2 = a->bs2,rmax = 0; 781584200bdSSatish Balay Scalar *aa = a->a, *ap; 782584200bdSSatish Balay 7833a40ed3dSBarry Smith PetscFunctionBegin; 7843a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 785584200bdSSatish Balay 78643ee02c3SBarry Smith if (m) rmax = ailen[0]; 787584200bdSSatish Balay for ( i=1; i<mbs; i++ ) { 788584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 789584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 790d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 791584200bdSSatish Balay if (fshift) { 792a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 793584200bdSSatish Balay N = ailen[i]; 794584200bdSSatish Balay for ( j=0; j<N; j++ ) { 795584200bdSSatish Balay ip[j-fshift] = ip[j]; 7967e67e3f9SSatish Balay PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(Scalar)); 797584200bdSSatish Balay } 798584200bdSSatish Balay } 799584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 800584200bdSSatish Balay } 801584200bdSSatish Balay if (mbs) { 802584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 803584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 804584200bdSSatish Balay } 805584200bdSSatish Balay /* reset ilen and imax for each row */ 806584200bdSSatish Balay for ( i=0; i<mbs; i++ ) { 807584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 808584200bdSSatish Balay } 809a7c10996SSatish Balay a->nz = ai[mbs]; 810584200bdSSatish Balay 811584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 812584200bdSSatish Balay if (fshift && a->diag) { 813584200bdSSatish Balay PetscFree(a->diag); 814584200bdSSatish Balay PLogObjectMemory(A,-(m+1)*sizeof(int)); 815584200bdSSatish Balay a->diag = 0; 816584200bdSSatish Balay } 8173d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 818219d9a1aSLois Curfman McInnes m,a->n,a->bs,fshift*bs2,a->nz*bs2); 8193d2013a6SLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 820584200bdSSatish Balay a->reallocs); 821d402145bSBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 822e2f3b5e9SSatish Balay a->reallocs = 0; 8234e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift*bs2; 8244e220ebcSLois Curfman McInnes 8253a40ed3dSBarry Smith PetscFunctionReturn(0); 826584200bdSSatish Balay } 827584200bdSSatish Balay 8285a838052SSatish Balay 829d9b7c43dSSatish Balay /* idx should be of length atlease bs */ 8305615d1e5SSatish Balay #undef __FUNC__ 8315615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Block" 832d9b7c43dSSatish Balay static int MatZeroRows_SeqBAIJ_Check_Block(int *idx, int bs, PetscTruth *flg) 833d9b7c43dSSatish Balay { 834d9b7c43dSSatish Balay int i,row; 8353a40ed3dSBarry Smith 8363a40ed3dSBarry Smith PetscFunctionBegin; 837d9b7c43dSSatish Balay row = idx[0]; 8383a40ed3dSBarry Smith if (row%bs!=0) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 839d9b7c43dSSatish Balay 840d9b7c43dSSatish Balay for ( i=1; i<bs; i++ ) { 8413a40ed3dSBarry Smith if (row+i != idx[i]) { *flg = PETSC_FALSE; PetscFunctionReturn(0); } 842d9b7c43dSSatish Balay } 843d9b7c43dSSatish Balay *flg = PETSC_TRUE; 8443a40ed3dSBarry Smith PetscFunctionReturn(0); 845d9b7c43dSSatish Balay } 846d9b7c43dSSatish Balay 8475615d1e5SSatish Balay #undef __FUNC__ 8485615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ" 8498f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag) 850d9b7c43dSSatish Balay { 851d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 852d9b7c43dSSatish Balay IS is_local; 853d9b7c43dSSatish Balay int ierr,i,j,count,m=baij->m,is_n,*is_idx,*rows,bs=baij->bs,bs2=baij->bs2; 854d9b7c43dSSatish Balay PetscTruth flg; 855d9b7c43dSSatish Balay Scalar zero = 0.0,*aa; 856d9b7c43dSSatish Balay 8573a40ed3dSBarry Smith PetscFunctionBegin; 858d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 859d9b7c43dSSatish Balay ierr = ISGetSize(is,&is_n);CHKERRQ(ierr); 860d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 861537820f0SBarry Smith ierr = ISCreateGeneral(A->comm,is_n,is_idx,&is_local); CHKERRQ(ierr); 862d9b7c43dSSatish Balay ierr = ISSort(is_local); CHKERRQ(ierr); 863d9b7c43dSSatish Balay ierr = ISGetIndices(is_local,&rows); CHKERRQ(ierr); 864d9b7c43dSSatish Balay 865d9b7c43dSSatish Balay i = 0; 866d9b7c43dSSatish Balay while (i < is_n) { 867a8c6a408SBarry Smith if (rows[i]<0 || rows[i]>m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 868d9b7c43dSSatish Balay flg = PETSC_FALSE; 869d9b7c43dSSatish Balay if (i+bs <= is_n) {ierr = MatZeroRows_SeqBAIJ_Check_Block(rows+i,bs,&flg); CHKERRQ(ierr); } 870d9b7c43dSSatish Balay count = (baij->i[rows[i]/bs +1] - baij->i[rows[i]/bs])*bs; 871d9b7c43dSSatish Balay aa = baij->a + baij->i[rows[i]/bs]*bs2 + (rows[i]%bs); 8722d61bbb3SSatish Balay if (flg) { /* There exists a block of rows to be Zerowed */ 873a07cd24cSSatish Balay if (baij->ilen[rows[i]/bs] > 0) { 8742d61bbb3SSatish Balay PetscMemzero(aa,count*bs*sizeof(Scalar)); 8752d61bbb3SSatish Balay baij->ilen[rows[i]/bs] = 1; 8762d61bbb3SSatish Balay baij->j[baij->i[rows[i]/bs]] = rows[i]/bs; 877a07cd24cSSatish Balay } 8782d61bbb3SSatish Balay i += bs; 8792d61bbb3SSatish Balay } else { /* Zero out only the requested row */ 880d9b7c43dSSatish Balay for ( j=0; j<count; j++ ) { 881d9b7c43dSSatish Balay aa[0] = zero; 882d9b7c43dSSatish Balay aa+=bs; 883d9b7c43dSSatish Balay } 884d9b7c43dSSatish Balay i++; 885d9b7c43dSSatish Balay } 886d9b7c43dSSatish Balay } 887d9b7c43dSSatish Balay if (diag) { 888d9b7c43dSSatish Balay for ( j=0; j<is_n; j++ ) { 889d9b7c43dSSatish Balay ierr = (*A->ops.setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 8902d61bbb3SSatish Balay /* ierr = MatSetValues(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); */ 891d9b7c43dSSatish Balay } 892d9b7c43dSSatish Balay } 893d9b7c43dSSatish Balay ierr = ISRestoreIndices(is,&is_idx); CHKERRQ(ierr); 894d9b7c43dSSatish Balay ierr = ISRestoreIndices(is_local,&rows); CHKERRQ(ierr); 895d9b7c43dSSatish Balay ierr = ISDestroy(is_local); CHKERRQ(ierr); 8969a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 8973a40ed3dSBarry Smith PetscFunctionReturn(0); 898d9b7c43dSSatish Balay } 8991c351548SSatish Balay 9005615d1e5SSatish Balay #undef __FUNC__ 9012d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ" 9022d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9032d61bbb3SSatish Balay { 9042d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 9052d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 9062d61bbb3SSatish Balay int *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 9072d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 9082d61bbb3SSatish Balay int ridx,cidx,bs2=a->bs2; 9092d61bbb3SSatish Balay Scalar *ap,value,*aa=a->a,*bap; 9102d61bbb3SSatish Balay 9112d61bbb3SSatish Balay PetscFunctionBegin; 9122d61bbb3SSatish Balay for ( k=0; k<m; k++ ) { /* loop over added rows */ 9132d61bbb3SSatish Balay row = im[k]; brow = row/bs; 9142d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9152d61bbb3SSatish Balay if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 9162d61bbb3SSatish Balay if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 9172d61bbb3SSatish Balay #endif 9182d61bbb3SSatish Balay rp = aj + ai[brow]; 9192d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 9202d61bbb3SSatish Balay rmax = imax[brow]; 9212d61bbb3SSatish Balay nrow = ailen[brow]; 9222d61bbb3SSatish Balay low = 0; 9232d61bbb3SSatish Balay for ( l=0; l<n; l++ ) { /* loop over added columns */ 9242d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g) 9252d61bbb3SSatish Balay if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 9262d61bbb3SSatish Balay if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 9272d61bbb3SSatish Balay #endif 9282d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 9292d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 9302d61bbb3SSatish Balay if (roworiented) { 9312d61bbb3SSatish Balay value = *v++; 9322d61bbb3SSatish Balay } else { 9332d61bbb3SSatish Balay value = v[k + l*m]; 9342d61bbb3SSatish Balay } 9352d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 9362d61bbb3SSatish Balay while (high-low > 7) { 9372d61bbb3SSatish Balay t = (low+high)/2; 9382d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 9392d61bbb3SSatish Balay else low = t; 9402d61bbb3SSatish Balay } 9412d61bbb3SSatish Balay for ( i=low; i<high; i++ ) { 9422d61bbb3SSatish Balay if (rp[i] > bcol) break; 9432d61bbb3SSatish Balay if (rp[i] == bcol) { 9442d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 9452d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 9462d61bbb3SSatish Balay else *bap = value; 9472d61bbb3SSatish Balay goto noinsert1; 9482d61bbb3SSatish Balay } 9492d61bbb3SSatish Balay } 9502d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 9512d61bbb3SSatish Balay else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9522d61bbb3SSatish Balay if (nrow >= rmax) { 9532d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 9542d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 9552d61bbb3SSatish Balay Scalar *new_a; 9562d61bbb3SSatish Balay 9572d61bbb3SSatish Balay if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 9582d61bbb3SSatish Balay 9592d61bbb3SSatish Balay /* Malloc new storage space */ 9602d61bbb3SSatish Balay len = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int); 9612d61bbb3SSatish Balay new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 9622d61bbb3SSatish Balay new_j = (int *) (new_a + bs2*new_nz); 9632d61bbb3SSatish Balay new_i = new_j + new_nz; 9642d61bbb3SSatish Balay 9652d61bbb3SSatish Balay /* copy over old data into new slots */ 9662d61bbb3SSatish Balay for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];} 9672d61bbb3SSatish Balay for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 9682d61bbb3SSatish Balay PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int)); 9692d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 9702d61bbb3SSatish Balay PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow, 9712d61bbb3SSatish Balay len*sizeof(int)); 9722d61bbb3SSatish Balay PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(Scalar)); 9732d61bbb3SSatish Balay PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(Scalar)); 9742d61bbb3SSatish Balay PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE), 9752d61bbb3SSatish Balay aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(Scalar)); 9762d61bbb3SSatish Balay /* free up old matrix storage */ 9772d61bbb3SSatish Balay PetscFree(a->a); 9782d61bbb3SSatish Balay if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 9792d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 9802d61bbb3SSatish Balay a->singlemalloc = 1; 9812d61bbb3SSatish Balay 9822d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 9832d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 9842d61bbb3SSatish Balay PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar))); 9852d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 9862d61bbb3SSatish Balay a->reallocs++; 9872d61bbb3SSatish Balay a->nz++; 9882d61bbb3SSatish Balay } 9892d61bbb3SSatish Balay N = nrow++ - 1; 9902d61bbb3SSatish Balay /* shift up all the later entries in this row */ 9912d61bbb3SSatish Balay for ( ii=N; ii>=i; ii-- ) { 9922d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 9932d61bbb3SSatish Balay PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar)); 9942d61bbb3SSatish Balay } 9952d61bbb3SSatish Balay if (N>=i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar)); 9962d61bbb3SSatish Balay rp[i] = bcol; 9972d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 9982d61bbb3SSatish Balay noinsert1:; 9992d61bbb3SSatish Balay low = i; 10002d61bbb3SSatish Balay } 10012d61bbb3SSatish Balay ailen[brow] = nrow; 10022d61bbb3SSatish Balay } 10032d61bbb3SSatish Balay PetscFunctionReturn(0); 10042d61bbb3SSatish Balay } 10052d61bbb3SSatish Balay 10062d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*); 10072d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double); 10082d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 1009*d3825aa8SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatGetSubMatrixCall,Mat*); 10102d61bbb3SSatish Balay extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatGetSubMatrixCall,Mat**); 10112d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec); 10122d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 10132d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat); 10142d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *); 10152d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*); 10162d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec); 10172d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 10182d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 10192d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat); 10202d61bbb3SSatish Balay 10212d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 10222d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 10232d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 10242d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 10252d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 10262d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 10272d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 10282d61bbb3SSatish Balay 10292d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 10302d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 10312d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 10322d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 10332d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 10342d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 10352d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4_NaturalOrdering(Mat,Vec,Vec); 10362d61bbb3SSatish Balay 10372d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 10382d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 10392d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 10402d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 10412d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 10422d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 10432d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 10442d61bbb3SSatish Balay 10452d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 10462d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 10472d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 10482d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 10492d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 10502d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 10512d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 10522d61bbb3SSatish Balay 10532d61bbb3SSatish Balay /* 10542d61bbb3SSatish Balay note: This can only work for identity for row and col. It would 10552d61bbb3SSatish Balay be good to check this and otherwise generate an error. 10562d61bbb3SSatish Balay */ 10572d61bbb3SSatish Balay #undef __FUNC__ 10582d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ" 10592d61bbb3SSatish Balay int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill) 10602d61bbb3SSatish Balay { 10612d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data; 10622d61bbb3SSatish Balay Mat outA; 10632d61bbb3SSatish Balay int ierr; 10642d61bbb3SSatish Balay 10652d61bbb3SSatish Balay PetscFunctionBegin; 10662d61bbb3SSatish Balay if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported"); 10672d61bbb3SSatish Balay 10682d61bbb3SSatish Balay outA = inA; 10692d61bbb3SSatish Balay inA->factor = FACTOR_LU; 10702d61bbb3SSatish Balay a->row = row; 10712d61bbb3SSatish Balay a->col = col; 10722d61bbb3SSatish Balay 10732d61bbb3SSatish Balay if (!a->solve_work) { 10742d61bbb3SSatish Balay a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work); 10752d61bbb3SSatish Balay PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar)); 10762d61bbb3SSatish Balay } 10772d61bbb3SSatish Balay 10782d61bbb3SSatish Balay if (!a->diag) { 10792d61bbb3SSatish Balay ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr); 10802d61bbb3SSatish Balay } 10812d61bbb3SSatish Balay ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr); 10822d61bbb3SSatish Balay 10832d61bbb3SSatish Balay /* 10842d61bbb3SSatish Balay Blocksize 4 has a special faster solver for ILU(0) factorization 10852d61bbb3SSatish Balay with natural ordering 10862d61bbb3SSatish Balay */ 10872d61bbb3SSatish Balay if (a->bs == 4) { 10882d61bbb3SSatish Balay inA->ops.solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 10892d61bbb3SSatish Balay } 10902d61bbb3SSatish Balay 10912d61bbb3SSatish Balay PetscFunctionReturn(0); 10922d61bbb3SSatish Balay } 10932d61bbb3SSatish Balay #undef __FUNC__ 1094d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ" 1095ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1096ba4ca20aSSatish Balay { 1097ba4ca20aSSatish Balay static int called = 0; 1098ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1099ba4ca20aSSatish Balay 11003a40ed3dSBarry Smith PetscFunctionBegin; 11013a40ed3dSBarry Smith if (called) {PetscFunctionReturn(0);} else called = 1; 110276be9ce4SBarry Smith (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n"); 110376be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n"); 11043a40ed3dSBarry Smith PetscFunctionReturn(0); 1105ba4ca20aSSatish Balay } 1106d9b7c43dSSatish Balay 11072593348eSBarry Smith /* -------------------------------------------------------------------*/ 1108cd0e1443SSatish Balay static struct _MatOps MatOps = {MatSetValues_SeqBAIJ, 11099867e207SSatish Balay MatGetRow_SeqBAIJ,MatRestoreRow_SeqBAIJ, 1110f44d3a6dSSatish Balay MatMult_SeqBAIJ_N,MatMultAdd_SeqBAIJ_N, 1111faf6580fSSatish Balay MatMultTrans_SeqBAIJ,MatMultTransAdd_SeqBAIJ, 11121a6a6d98SBarry Smith MatSolve_SeqBAIJ_N,0, 1113b6490206SBarry Smith 0,0, 1114de6a44a3SBarry Smith MatLUFactor_SeqBAIJ,0, 1115b6490206SBarry Smith 0, 1116f2501298SSatish Balay MatTranspose_SeqBAIJ, 111717e48fc4SSatish Balay MatGetInfo_SeqBAIJ,MatEqual_SeqBAIJ, 11189867e207SSatish Balay MatGetDiagonal_SeqBAIJ,MatDiagonalScale_SeqBAIJ,MatNorm_SeqBAIJ, 1119584200bdSSatish Balay 0,MatAssemblyEnd_SeqBAIJ, 1120b6490206SBarry Smith 0, 1121d9b7c43dSSatish Balay MatSetOption_SeqBAIJ,MatZeroEntries_SeqBAIJ,MatZeroRows_SeqBAIJ, 11227fc0212eSBarry Smith MatLUFactorSymbolic_SeqBAIJ,MatLUFactorNumeric_SeqBAIJ_N,0,0, 1123b6490206SBarry Smith MatGetSize_SeqBAIJ,MatGetSize_SeqBAIJ,MatGetOwnershipRange_SeqBAIJ, 1124de6a44a3SBarry Smith MatILUFactorSymbolic_SeqBAIJ,0, 1125d402145bSBarry Smith 0,0, 1126b6490206SBarry Smith MatConvertSameType_SeqBAIJ,0,0, 1127b6490206SBarry Smith MatILUFactor_SeqBAIJ,0,0, 1128af015674SSatish Balay MatGetSubMatrices_SeqBAIJ,MatIncreaseOverlap_SeqBAIJ, 11297e67e3f9SSatish Balay MatGetValues_SeqBAIJ,0, 1130ba4ca20aSSatish Balay MatPrintHelp_SeqBAIJ,MatScale_SeqBAIJ, 11313b2fbd54SBarry Smith 0,0,0,MatGetBlockSize_SeqBAIJ, 11323b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 113392c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 113492c4ed94SBarry Smith 0,0,0,0,0,0, 1135*d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1136*d3825aa8SBarry Smith MatGetSubMatrix_SeqBAIJ}; 11372593348eSBarry Smith 11385615d1e5SSatish Balay #undef __FUNC__ 11395615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ" 11402593348eSBarry Smith /*@C 114144cd7ae7SLois Curfman McInnes MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 114244cd7ae7SLois Curfman McInnes compressed row) format. For good matrix assembly performance the 114344cd7ae7SLois Curfman McInnes user should preallocate the matrix storage by setting the parameter nz 11442bd5e0b2SLois Curfman McInnes (or the array nzz). By setting these parameters accurately, performance 11452bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 11462593348eSBarry Smith 11472593348eSBarry Smith Input Parameters: 1148029af93fSBarry Smith . comm - MPI communicator, set to PETSC_COMM_SELF 1149b6490206SBarry Smith . bs - size of block 11502593348eSBarry Smith . m - number of rows 11512593348eSBarry Smith . n - number of columns 1152b6490206SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 11532bd5e0b2SLois Curfman McInnes . nzz - array containing the number of block nonzeros in the various block rows 11542bd5e0b2SLois Curfman McInnes (possibly different for each block row) or PETSC_NULL 11552593348eSBarry Smith 11562593348eSBarry Smith Output Parameter: 11572593348eSBarry Smith . A - the matrix 11582593348eSBarry Smith 11590513a670SBarry Smith Options Database Keys: 11600513a670SBarry Smith $ -mat_no_unroll - uses code that does not unroll the loops in the 11610effe34fSLois Curfman McInnes $ block calculations (much slower) 11620513a670SBarry Smith $ -mat_block_size - size of the blocks to use 11630513a670SBarry Smith 11642593348eSBarry Smith Notes: 116544cd7ae7SLois Curfman McInnes The block AIJ format is fully compatible with standard Fortran 77 11662593348eSBarry Smith storage. That is, the stored row and column indices can begin at 116744cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 11682593348eSBarry Smith 11692593348eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 11702593348eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 11712593348eSBarry Smith allocation. For additional details, see the users manual chapter on 11726da5968aSLois Curfman McInnes matrices. 11732593348eSBarry Smith 117444cd7ae7SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues() 11752593348eSBarry Smith @*/ 1176b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A) 11772593348eSBarry Smith { 11782593348eSBarry Smith Mat B; 1179b6490206SBarry Smith Mat_SeqBAIJ *b; 11803b2fbd54SBarry Smith int i,len,ierr,flg,mbs=m/bs,nbs=n/bs,bs2=bs*bs,size; 11813b2fbd54SBarry Smith 11823a40ed3dSBarry Smith PetscFunctionBegin; 11833b2fbd54SBarry Smith MPI_Comm_size(comm,&size); 1184a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1"); 1185b6490206SBarry Smith 11860513a670SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 11870513a670SBarry Smith 11883a40ed3dSBarry Smith if (mbs*bs!=m || nbs*bs!=n) { 1189a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize"); 11903a40ed3dSBarry Smith } 11912593348eSBarry Smith 11922593348eSBarry Smith *A = 0; 1193d4bb536fSBarry Smith PetscHeaderCreate(B,_p_Mat,MAT_COOKIE,MATSEQBAIJ,comm,MatDestroy,MatView); 11942593348eSBarry Smith PLogObjectCreate(B); 1195b6490206SBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b); 119644cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_SeqBAIJ)); 11972593348eSBarry Smith PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps)); 11981a6a6d98SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg); CHKERRQ(ierr); 11991a6a6d98SBarry Smith if (!flg) { 12007fc0212eSBarry Smith switch (bs) { 12017fc0212eSBarry Smith case 1: 12027fc0212eSBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 12031a6a6d98SBarry Smith B->ops.solve = MatSolve_SeqBAIJ_1; 120439b95ed1SBarry Smith B->ops.mult = MatMult_SeqBAIJ_1; 1205f44d3a6dSSatish Balay B->ops.multadd = MatMultAdd_SeqBAIJ_1; 12067fc0212eSBarry Smith break; 12074eeb42bcSBarry Smith case 2: 12084eeb42bcSBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 12091a6a6d98SBarry Smith B->ops.solve = MatSolve_SeqBAIJ_2; 121039b95ed1SBarry Smith B->ops.mult = MatMult_SeqBAIJ_2; 1211f44d3a6dSSatish Balay B->ops.multadd = MatMultAdd_SeqBAIJ_2; 12126d84be18SBarry Smith break; 1213f327dd97SBarry Smith case 3: 1214f327dd97SBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 12151a6a6d98SBarry Smith B->ops.solve = MatSolve_SeqBAIJ_3; 121639b95ed1SBarry Smith B->ops.mult = MatMult_SeqBAIJ_3; 1217f44d3a6dSSatish Balay B->ops.multadd = MatMultAdd_SeqBAIJ_3; 12184eeb42bcSBarry Smith break; 12196d84be18SBarry Smith case 4: 12206d84be18SBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 12211a6a6d98SBarry Smith B->ops.solve = MatSolve_SeqBAIJ_4; 122239b95ed1SBarry Smith B->ops.mult = MatMult_SeqBAIJ_4; 1223f44d3a6dSSatish Balay B->ops.multadd = MatMultAdd_SeqBAIJ_4; 12246d84be18SBarry Smith break; 12256d84be18SBarry Smith case 5: 12266d84be18SBarry Smith B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 12271a6a6d98SBarry Smith B->ops.solve = MatSolve_SeqBAIJ_5; 122839b95ed1SBarry Smith B->ops.mult = MatMult_SeqBAIJ_5; 1229f44d3a6dSSatish Balay B->ops.multadd = MatMultAdd_SeqBAIJ_5; 12306d84be18SBarry Smith break; 123148e9ddb2SSatish Balay case 7: 123248e9ddb2SSatish Balay B->ops.mult = MatMult_SeqBAIJ_7; 123348e9ddb2SSatish Balay B->ops.solve = MatSolve_SeqBAIJ_7; 123448e9ddb2SSatish Balay B->ops.multadd = MatMultAdd_SeqBAIJ_7; 123548e9ddb2SSatish Balay break; 12367fc0212eSBarry Smith } 12371a6a6d98SBarry Smith } 1238b6490206SBarry Smith B->destroy = MatDestroy_SeqBAIJ; 1239b6490206SBarry Smith B->view = MatView_SeqBAIJ; 12402593348eSBarry Smith B->factor = 0; 12412593348eSBarry Smith B->lupivotthreshold = 1.0; 124290f02eecSBarry Smith B->mapping = 0; 12432593348eSBarry Smith b->row = 0; 12442593348eSBarry Smith b->col = 0; 12452593348eSBarry Smith b->reallocs = 0; 12462593348eSBarry Smith 124744cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 124844cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 1249b6490206SBarry Smith b->mbs = mbs; 1250f2501298SSatish Balay b->nbs = nbs; 1251b6490206SBarry Smith b->imax = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax); 12522593348eSBarry Smith if (nnz == PETSC_NULL) { 1253119a934aSSatish Balay if (nz == PETSC_DEFAULT) nz = 5; 12542593348eSBarry Smith else if (nz <= 0) nz = 1; 1255b6490206SBarry Smith for ( i=0; i<mbs; i++ ) b->imax[i] = nz; 1256b6490206SBarry Smith nz = nz*mbs; 12573a40ed3dSBarry Smith } else { 12582593348eSBarry Smith nz = 0; 1259b6490206SBarry Smith for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 12602593348eSBarry Smith } 12612593348eSBarry Smith 12622593348eSBarry Smith /* allocate the matrix space */ 12637e67e3f9SSatish Balay len = nz*sizeof(int) + nz*bs2*sizeof(Scalar) + (b->m+1)*sizeof(int); 12642593348eSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 12657e67e3f9SSatish Balay PetscMemzero(b->a,nz*bs2*sizeof(Scalar)); 12667e67e3f9SSatish Balay b->j = (int *) (b->a + nz*bs2); 12672593348eSBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 12682593348eSBarry Smith b->i = b->j + nz; 12692593348eSBarry Smith b->singlemalloc = 1; 12702593348eSBarry Smith 1271de6a44a3SBarry Smith b->i[0] = 0; 1272b6490206SBarry Smith for (i=1; i<mbs+1; i++) { 12732593348eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 12742593348eSBarry Smith } 12752593348eSBarry Smith 1276b6490206SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 1277b6490206SBarry Smith b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); 1278f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1279b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;} 12802593348eSBarry Smith 1281b6490206SBarry Smith b->bs = bs; 12829df24120SSatish Balay b->bs2 = bs2; 1283b6490206SBarry Smith b->mbs = mbs; 12842593348eSBarry Smith b->nz = 0; 128518e7b8e4SLois Curfman McInnes b->maxnz = nz*bs2; 12862593348eSBarry Smith b->sorted = 0; 12872593348eSBarry Smith b->roworiented = 1; 12882593348eSBarry Smith b->nonew = 0; 12892593348eSBarry Smith b->diag = 0; 12902593348eSBarry Smith b->solve_work = 0; 1291de6a44a3SBarry Smith b->mult_work = 0; 12922593348eSBarry Smith b->spptr = 0; 12934e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 12944e220ebcSLois Curfman McInnes 12952593348eSBarry Smith *A = B; 12962593348eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 12972593348eSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 12983a40ed3dSBarry Smith PetscFunctionReturn(0); 12992593348eSBarry Smith } 13002593348eSBarry Smith 13015615d1e5SSatish Balay #undef __FUNC__ 13025615d1e5SSatish Balay #define __FUNC__ "MatConvertSameType_SeqBAIJ" 1303b6490206SBarry Smith int MatConvertSameType_SeqBAIJ(Mat A,Mat *B,int cpvalues) 13042593348eSBarry Smith { 13052593348eSBarry Smith Mat C; 1306b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data; 13079df24120SSatish Balay int i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2; 1308de6a44a3SBarry Smith 13093a40ed3dSBarry Smith PetscFunctionBegin; 1310a8c6a408SBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix"); 13112593348eSBarry Smith 13122593348eSBarry Smith *B = 0; 1313d4bb536fSBarry Smith PetscHeaderCreate(C,_p_Mat,MAT_COOKIE,MATSEQBAIJ,A->comm,MatDestroy,MatView); 13142593348eSBarry Smith PLogObjectCreate(C); 1315b6490206SBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c); 13162593348eSBarry Smith PetscMemcpy(&C->ops,&A->ops,sizeof(struct _MatOps)); 1317b6490206SBarry Smith C->destroy = MatDestroy_SeqBAIJ; 1318b6490206SBarry Smith C->view = MatView_SeqBAIJ; 13192593348eSBarry Smith C->factor = A->factor; 13202593348eSBarry Smith c->row = 0; 13212593348eSBarry Smith c->col = 0; 13222593348eSBarry Smith C->assembled = PETSC_TRUE; 13232593348eSBarry Smith 132444cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 132544cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 132644cd7ae7SLois Curfman McInnes C->M = a->m; 132744cd7ae7SLois Curfman McInnes C->N = a->n; 132844cd7ae7SLois Curfman McInnes 1329b6490206SBarry Smith c->bs = a->bs; 13309df24120SSatish Balay c->bs2 = a->bs2; 1331b6490206SBarry Smith c->mbs = a->mbs; 1332b6490206SBarry Smith c->nbs = a->nbs; 13332593348eSBarry Smith 1334b6490206SBarry Smith c->imax = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax); 1335b6490206SBarry Smith c->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen); 1336b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 13372593348eSBarry Smith c->imax[i] = a->imax[i]; 13382593348eSBarry Smith c->ilen[i] = a->ilen[i]; 13392593348eSBarry Smith } 13402593348eSBarry Smith 13412593348eSBarry Smith /* allocate the matrix space */ 13422593348eSBarry Smith c->singlemalloc = 1; 13437e67e3f9SSatish Balay len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(Scalar) + sizeof(int)); 13442593348eSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 13457e67e3f9SSatish Balay c->j = (int *) (c->a + nz*bs2); 1346de6a44a3SBarry Smith c->i = c->j + nz; 1347b6490206SBarry Smith PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int)); 1348b6490206SBarry Smith if (mbs > 0) { 1349de6a44a3SBarry Smith PetscMemcpy(c->j,a->j,nz*sizeof(int)); 13502593348eSBarry Smith if (cpvalues == COPY_VALUES) { 13517e67e3f9SSatish Balay PetscMemcpy(c->a,a->a,bs2*nz*sizeof(Scalar)); 13522593348eSBarry Smith } 13532593348eSBarry Smith } 13542593348eSBarry Smith 1355f09e8eb9SSatish Balay PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 13562593348eSBarry Smith c->sorted = a->sorted; 13572593348eSBarry Smith c->roworiented = a->roworiented; 13582593348eSBarry Smith c->nonew = a->nonew; 13592593348eSBarry Smith 13602593348eSBarry Smith if (a->diag) { 1361b6490206SBarry Smith c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag); 1362b6490206SBarry Smith PLogObjectMemory(C,(mbs+1)*sizeof(int)); 1363b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 13642593348eSBarry Smith c->diag[i] = a->diag[i]; 13652593348eSBarry Smith } 13662593348eSBarry Smith } 13672593348eSBarry Smith else c->diag = 0; 13682593348eSBarry Smith c->nz = a->nz; 13692593348eSBarry Smith c->maxnz = a->maxnz; 13702593348eSBarry Smith c->solve_work = 0; 13712593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 13727fc0212eSBarry Smith c->mult_work = 0; 13732593348eSBarry Smith *B = C; 13743a40ed3dSBarry Smith PetscFunctionReturn(0); 13752593348eSBarry Smith } 13762593348eSBarry Smith 13775615d1e5SSatish Balay #undef __FUNC__ 13785615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ" 137919bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A) 13802593348eSBarry Smith { 1381b6490206SBarry Smith Mat_SeqBAIJ *a; 13822593348eSBarry Smith Mat B; 1383de6a44a3SBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg; 1384b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 138535aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1386a7c10996SSatish Balay int *masked, nmask,tmp,bs2,ishift; 1387b6490206SBarry Smith Scalar *aa; 138819bcc07fSBarry Smith MPI_Comm comm = ((PetscObject) viewer)->comm; 13892593348eSBarry Smith 13903a40ed3dSBarry Smith PetscFunctionBegin; 13911a6a6d98SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,&flg);CHKERRQ(ierr); 1392de6a44a3SBarry Smith bs2 = bs*bs; 1393b6490206SBarry Smith 13942593348eSBarry Smith MPI_Comm_size(comm,&size); 1395cc0fae11SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor"); 139690ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 13970752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr); 1398a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object"); 13992593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 14002593348eSBarry Smith 1401d64ed03dSBarry Smith if (header[3] < 0) { 1402a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ"); 1403d64ed03dSBarry Smith } 1404d64ed03dSBarry Smith 1405a8c6a408SBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices"); 140635aab85fSBarry Smith 140735aab85fSBarry Smith /* 140835aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 140935aab85fSBarry Smith divisible by the blocksize 141035aab85fSBarry Smith */ 1411b6490206SBarry Smith mbs = M/bs; 141235aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 141335aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 141435aab85fSBarry Smith else mbs++; 141535aab85fSBarry Smith if (extra_rows) { 1416537820f0SBarry Smith PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 141735aab85fSBarry Smith } 1418b6490206SBarry Smith 14192593348eSBarry Smith /* read in row lengths */ 142035aab85fSBarry Smith rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths); 14210752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr); 142235aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1; 14232593348eSBarry Smith 1424b6490206SBarry Smith /* read in column indices */ 142535aab85fSBarry Smith jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj); 14260752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT); CHKERRQ(ierr); 142735aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i; 1428b6490206SBarry Smith 1429b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1430b6490206SBarry Smith browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths); 1431b6490206SBarry Smith PetscMemzero(browlengths,mbs*sizeof(int)); 143235aab85fSBarry Smith mask = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask); 143335aab85fSBarry Smith PetscMemzero(mask,mbs*sizeof(int)); 143435aab85fSBarry Smith masked = mask + mbs; 1435b6490206SBarry Smith rowcount = 0; nzcount = 0; 1436b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 143735aab85fSBarry Smith nmask = 0; 1438b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1439b6490206SBarry Smith kmax = rowlengths[rowcount]; 1440b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 144135aab85fSBarry Smith tmp = jj[nzcount++]/bs; 144235aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1443b6490206SBarry Smith } 1444b6490206SBarry Smith rowcount++; 1445b6490206SBarry Smith } 144635aab85fSBarry Smith browlengths[i] += nmask; 144735aab85fSBarry Smith /* zero out the mask elements we set */ 144835aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1449b6490206SBarry Smith } 1450b6490206SBarry Smith 14512593348eSBarry Smith /* create our matrix */ 14523eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 14532593348eSBarry Smith B = *A; 1454b6490206SBarry Smith a = (Mat_SeqBAIJ *) B->data; 14552593348eSBarry Smith 14562593348eSBarry Smith /* set matrix "i" values */ 1457de6a44a3SBarry Smith a->i[0] = 0; 1458b6490206SBarry Smith for ( i=1; i<= mbs; i++ ) { 1459b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1460b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 14612593348eSBarry Smith } 1462b6490206SBarry Smith a->nz = 0; 1463b6490206SBarry Smith for ( i=0; i<mbs; i++ ) a->nz += browlengths[i]; 14642593348eSBarry Smith 1465b6490206SBarry Smith /* read in nonzero values */ 146635aab85fSBarry Smith aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa); 14670752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR); CHKERRQ(ierr); 146835aab85fSBarry Smith for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0; 1469b6490206SBarry Smith 1470b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1471b6490206SBarry Smith nzcount = 0; jcount = 0; 1472b6490206SBarry Smith for ( i=0; i<mbs; i++ ) { 1473b6490206SBarry Smith nzcountb = nzcount; 147435aab85fSBarry Smith nmask = 0; 1475b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1476b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1477b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 147835aab85fSBarry Smith tmp = jj[nzcount++]/bs; 147935aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1480b6490206SBarry Smith } 1481b6490206SBarry Smith rowcount++; 1482b6490206SBarry Smith } 1483de6a44a3SBarry Smith /* sort the masked values */ 148477c4ece6SBarry Smith PetscSortInt(nmask,masked); 1485de6a44a3SBarry Smith 1486b6490206SBarry Smith /* set "j" values into matrix */ 1487b6490206SBarry Smith maskcount = 1; 148835aab85fSBarry Smith for ( j=0; j<nmask; j++ ) { 148935aab85fSBarry Smith a->j[jcount++] = masked[j]; 1490de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1491b6490206SBarry Smith } 1492b6490206SBarry Smith /* set "a" values into matrix */ 1493de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1494b6490206SBarry Smith for ( j=0; j<bs; j++ ) { 1495b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1496b6490206SBarry Smith for ( k=0; k<kmax; k++ ) { 1497de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1498de6a44a3SBarry Smith block = mask[tmp] - 1; 1499de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1500de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1501b6490206SBarry Smith a->a[idx] = aa[nzcountb++]; 1502b6490206SBarry Smith } 1503b6490206SBarry Smith } 150435aab85fSBarry Smith /* zero out the mask elements we set */ 150535aab85fSBarry Smith for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0; 1506b6490206SBarry Smith } 1507a8c6a408SBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix"); 1508b6490206SBarry Smith 1509b6490206SBarry Smith PetscFree(rowlengths); 1510b6490206SBarry Smith PetscFree(browlengths); 1511b6490206SBarry Smith PetscFree(aa); 1512b6490206SBarry Smith PetscFree(jj); 1513b6490206SBarry Smith PetscFree(mask); 1514b6490206SBarry Smith 1515b6490206SBarry Smith B->assembled = PETSC_TRUE; 1516de6a44a3SBarry Smith 15179c01be13SBarry Smith ierr = MatView_Private(B); CHKERRQ(ierr); 15183a40ed3dSBarry Smith PetscFunctionReturn(0); 15192593348eSBarry Smith } 15202593348eSBarry Smith 15212593348eSBarry Smith 15222593348eSBarry Smith 1523