1*435da068SBarry Smith /*$Id: baij.c,v 1.221 2001/03/09 21:49:34 balay Exp bsmith $*/ 22593348eSBarry Smith 32593348eSBarry Smith /* 4b6490206SBarry Smith Defines the basic matrix operations for the BAIJ (compressed row) 52593348eSBarry Smith matrix storage format. 62593348eSBarry Smith */ 7e090d566SSatish Balay #include "petscsys.h" 870f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h" 91a6a6d98SBarry Smith #include "src/vec/vecimpl.h" 101a6a6d98SBarry Smith #include "src/inline/spops.h" 113b547af2SSatish Balay 1295d5f7c2SBarry Smith /* UGLY, ugly, ugly 1395d5f7c2SBarry Smith When MatScalar == Scalar the function MatSetValuesBlocked_SeqBAIJ_MatScalar() does 1495d5f7c2SBarry Smith not exist. Otherwise ..._MatScalar() takes matrix elements in single precision and 1595d5f7c2SBarry Smith inserts them into the single precision data structure. The function MatSetValuesBlocked_SeqBAIJ() 1695d5f7c2SBarry Smith converts the entries into single precision and then calls ..._MatScalar() to put them 1795d5f7c2SBarry Smith into the single precision data structures. 1895d5f7c2SBarry Smith */ 1995d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 20ca44d042SBarry Smith EXTERN int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat,int,int*,int,int*,MatScalar*,InsertMode); 2195d5f7c2SBarry Smith #else 2295d5f7c2SBarry Smith #define MatSetValuesBlocked_SeqBAIJ_MatScalar MatSetValuesBlocked_SeqBAIJ 2395d5f7c2SBarry Smith #endif 2495d5f7c2SBarry Smith 252d61bbb3SSatish Balay #define CHUNKSIZE 10 26de6a44a3SBarry Smith 27be5855fcSBarry Smith /* 28be5855fcSBarry Smith Checks for missing diagonals 29be5855fcSBarry Smith */ 30be5855fcSBarry Smith #undef __FUNC__ 31b0a32e0cSBarry Smith #define __FUNC__ "MatMissingDiagonal_SeqBAIJ" 32c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A) 33be5855fcSBarry Smith { 34be5855fcSBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 35883fce79SBarry Smith int *diag,*jj = a->j,i,ierr; 36be5855fcSBarry Smith 37be5855fcSBarry Smith PetscFunctionBegin; 38c4992f7dSBarry Smith ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr); 39883fce79SBarry Smith diag = a->diag; 400e8e8aceSBarry Smith for (i=0; i<a->mbs; i++) { 41be5855fcSBarry Smith if (jj[diag[i]] != i) { 4229bbc08cSBarry Smith SETERRQ1(1,"Matrix is missing diagonal number %d",i); 43be5855fcSBarry Smith } 44be5855fcSBarry Smith } 45be5855fcSBarry Smith PetscFunctionReturn(0); 46be5855fcSBarry Smith } 47be5855fcSBarry Smith 485615d1e5SSatish Balay #undef __FUNC__ 49b0a32e0cSBarry Smith #define __FUNC__ "MatMarkDiagonal_SeqBAIJ" 50c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A) 51de6a44a3SBarry Smith { 52de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 5382502324SSatish Balay int i,j,*diag,m = a->mbs,ierr; 54de6a44a3SBarry Smith 553a40ed3dSBarry Smith PetscFunctionBegin; 56883fce79SBarry Smith if (a->diag) PetscFunctionReturn(0); 57883fce79SBarry Smith 58b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr); 59b0a32e0cSBarry Smith PetscLogObjectMemory(A,(m+1)*sizeof(int)); 607fc0212eSBarry Smith for (i=0; i<m; i++) { 61ecc615b2SBarry Smith diag[i] = a->i[i+1]; 62de6a44a3SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 63de6a44a3SBarry Smith if (a->j[j] == i) { 64de6a44a3SBarry Smith diag[i] = j; 65de6a44a3SBarry Smith break; 66de6a44a3SBarry Smith } 67de6a44a3SBarry Smith } 68de6a44a3SBarry Smith } 69de6a44a3SBarry Smith a->diag = diag; 703a40ed3dSBarry Smith PetscFunctionReturn(0); 71de6a44a3SBarry Smith } 722593348eSBarry Smith 732593348eSBarry Smith 74ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 753b2fbd54SBarry Smith 765615d1e5SSatish Balay #undef __FUNC__ 77b0a32e0cSBarry Smith #define __FUNC__ "MatGetRowIJ_SeqBAIJ" 780e6d2581SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 793b2fbd54SBarry Smith { 803b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 813b2fbd54SBarry Smith int ierr,n = a->mbs,i; 823b2fbd54SBarry Smith 833a40ed3dSBarry Smith PetscFunctionBegin; 843b2fbd54SBarry Smith *nn = n; 853a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 863b2fbd54SBarry Smith if (symmetric) { 873b2fbd54SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 883b2fbd54SBarry Smith } else if (oshift == 1) { 893b2fbd54SBarry Smith /* temporarily add 1 to i and j indices */ 90*435da068SBarry Smith int nz = a->i[n]; 913b2fbd54SBarry Smith for (i=0; i<nz; i++) a->j[i]++; 923b2fbd54SBarry Smith for (i=0; i<n+1; i++) a->i[i]++; 933b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 943b2fbd54SBarry Smith } else { 953b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 963b2fbd54SBarry Smith } 973b2fbd54SBarry Smith 983a40ed3dSBarry Smith PetscFunctionReturn(0); 993b2fbd54SBarry Smith } 1003b2fbd54SBarry Smith 1015615d1e5SSatish Balay #undef __FUNC__ 102b0a32e0cSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ" 103*435da068SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 1043b2fbd54SBarry Smith { 1053b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 106606d414cSSatish Balay int i,n = a->mbs,ierr; 1073b2fbd54SBarry Smith 1083a40ed3dSBarry Smith PetscFunctionBegin; 1093a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1103b2fbd54SBarry Smith if (symmetric) { 111606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 112606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 113af5da2bfSBarry Smith } else if (oshift == 1) { 114*435da068SBarry Smith int nz = a->i[n]-1; 1153b2fbd54SBarry Smith for (i=0; i<nz; i++) a->j[i]--; 1163b2fbd54SBarry Smith for (i=0; i<n+1; i++) a->i[i]--; 1173b2fbd54SBarry Smith } 1183a40ed3dSBarry Smith PetscFunctionReturn(0); 1193b2fbd54SBarry Smith } 1203b2fbd54SBarry Smith 1212d61bbb3SSatish Balay #undef __FUNC__ 122b0a32e0cSBarry Smith #define __FUNC__ "MatGetBlockSize_SeqBAIJ" 1232d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs) 1242d61bbb3SSatish Balay { 1252d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data; 1262d61bbb3SSatish Balay 1272d61bbb3SSatish Balay PetscFunctionBegin; 1282d61bbb3SSatish Balay *bs = baij->bs; 1292d61bbb3SSatish Balay PetscFunctionReturn(0); 1302d61bbb3SSatish Balay } 1312d61bbb3SSatish Balay 1322d61bbb3SSatish Balay 1332d61bbb3SSatish Balay #undef __FUNC__ 134b0a32e0cSBarry Smith #define __FUNC__ "MatDestroy_SeqBAIJ" 135e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A) 1362d61bbb3SSatish Balay { 1372d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 138e51c0b9cSSatish Balay int ierr; 1392d61bbb3SSatish Balay 140433994e6SBarry Smith PetscFunctionBegin; 141aa482453SBarry Smith #if defined(PETSC_USE_LOG) 142b0a32e0cSBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 1432d61bbb3SSatish Balay #endif 144606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 145606d414cSSatish Balay if (!a->singlemalloc) { 146606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 147606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 148606d414cSSatish Balay } 149c38d4ed2SBarry Smith if (a->row) { 150c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 151c38d4ed2SBarry Smith } 152c38d4ed2SBarry Smith if (a->col) { 153c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 154c38d4ed2SBarry Smith } 155606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 156606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 157606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 158606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 159606d414cSSatish Balay if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);} 160e51c0b9cSSatish Balay if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 161606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 162563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 163563b5814SBarry Smith if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);} 164563b5814SBarry Smith #endif 165606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 1662d61bbb3SSatish Balay PetscFunctionReturn(0); 1672d61bbb3SSatish Balay } 1682d61bbb3SSatish Balay 1692d61bbb3SSatish Balay #undef __FUNC__ 170b0a32e0cSBarry Smith #define __FUNC__ "MatSetOption_SeqBAIJ" 1712d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1722d61bbb3SSatish Balay { 1732d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1742d61bbb3SSatish Balay 1752d61bbb3SSatish Balay PetscFunctionBegin; 176c4992f7dSBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = PETSC_TRUE; 177c4992f7dSBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = PETSC_FALSE; 178c4992f7dSBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = PETSC_TRUE; 179c4992f7dSBarry Smith else if (op == MAT_COLUMNS_UNSORTED) a->sorted = PETSC_FALSE; 180c4992f7dSBarry Smith else if (op == MAT_KEEP_ZEROED_ROWS) a->keepzeroedrows = PETSC_TRUE; 1812d61bbb3SSatish Balay else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 1824787f768SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERR) a->nonew = -1; 1834787f768SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR) a->nonew = -2; 1842d61bbb3SSatish Balay else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 1852d61bbb3SSatish Balay else if (op == MAT_ROWS_SORTED || 1862d61bbb3SSatish Balay op == MAT_ROWS_UNSORTED || 1872d61bbb3SSatish Balay op == MAT_SYMMETRIC || 1882d61bbb3SSatish Balay op == MAT_STRUCTURALLY_SYMMETRIC || 1892d61bbb3SSatish Balay op == MAT_YES_NEW_DIAGONALS || 190b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES || 191b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) { 192b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 1932d61bbb3SSatish Balay } else if (op == MAT_NO_NEW_DIAGONALS) { 19429bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 1952d61bbb3SSatish Balay } else { 19629bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"unknown option"); 1972d61bbb3SSatish Balay } 1982d61bbb3SSatish Balay PetscFunctionReturn(0); 1992d61bbb3SSatish Balay } 2002d61bbb3SSatish Balay 2012d61bbb3SSatish Balay #undef __FUNC__ 202b0a32e0cSBarry Smith #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ" 2032d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 2042d61bbb3SSatish Balay { 2052d61bbb3SSatish Balay PetscFunctionBegin; 2064c49b128SBarry Smith if (m) *m = 0; 207273d9f13SBarry Smith if (n) *n = A->m; 2082d61bbb3SSatish Balay PetscFunctionReturn(0); 2092d61bbb3SSatish Balay } 2102d61bbb3SSatish Balay 2112d61bbb3SSatish Balay #undef __FUNC__ 212b0a32e0cSBarry Smith #define __FUNC__ "MatGetRow_SeqBAIJ" 2132d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2142d61bbb3SSatish Balay { 2152d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 21682502324SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr; 2173f1db9ecSBarry Smith MatScalar *aa,*aa_i; 2183f1db9ecSBarry Smith Scalar *v_i; 2192d61bbb3SSatish Balay 2202d61bbb3SSatish Balay PetscFunctionBegin; 2212d61bbb3SSatish Balay bs = a->bs; 2222d61bbb3SSatish Balay ai = a->i; 2232d61bbb3SSatish Balay aj = a->j; 2242d61bbb3SSatish Balay aa = a->a; 2252d61bbb3SSatish Balay bs2 = a->bs2; 2262d61bbb3SSatish Balay 227273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range"); 2282d61bbb3SSatish Balay 2292d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2302d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2312d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2322d61bbb3SSatish Balay *nz = bs*M; 2332d61bbb3SSatish Balay 2342d61bbb3SSatish Balay if (v) { 2352d61bbb3SSatish Balay *v = 0; 2362d61bbb3SSatish Balay if (*nz) { 237b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr); 2382d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2392d61bbb3SSatish Balay v_i = *v + i*bs; 2402d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2412d61bbb3SSatish Balay for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];} 2422d61bbb3SSatish Balay } 2432d61bbb3SSatish Balay } 2442d61bbb3SSatish Balay } 2452d61bbb3SSatish Balay 2462d61bbb3SSatish Balay if (idx) { 2472d61bbb3SSatish Balay *idx = 0; 2482d61bbb3SSatish Balay if (*nz) { 249b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr); 2502d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2512d61bbb3SSatish Balay idx_i = *idx + i*bs; 2522d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2532d61bbb3SSatish Balay for (j=0; j<bs; j++) {idx_i[j] = itmp++;} 2542d61bbb3SSatish Balay } 2552d61bbb3SSatish Balay } 2562d61bbb3SSatish Balay } 2572d61bbb3SSatish Balay PetscFunctionReturn(0); 2582d61bbb3SSatish Balay } 2592d61bbb3SSatish Balay 2602d61bbb3SSatish Balay #undef __FUNC__ 261b0a32e0cSBarry Smith #define __FUNC__ "MatRestoreRow_SeqBAIJ" 2622d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2632d61bbb3SSatish Balay { 264606d414cSSatish Balay int ierr; 265606d414cSSatish Balay 2662d61bbb3SSatish Balay PetscFunctionBegin; 267606d414cSSatish Balay if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 268606d414cSSatish Balay if (v) {if (*v) {ierr = PetscFree(*v);CHKERRQ(ierr);}} 2692d61bbb3SSatish Balay PetscFunctionReturn(0); 2702d61bbb3SSatish Balay } 2712d61bbb3SSatish Balay 2722d61bbb3SSatish Balay #undef __FUNC__ 273b0a32e0cSBarry Smith #define __FUNC__ "MatTranspose_SeqBAIJ" 2742d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2752d61bbb3SSatish Balay { 2762d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2772d61bbb3SSatish Balay Mat C; 2782d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 279273d9f13SBarry Smith int *rows,*cols,bs2=a->bs2; 280375fe846SBarry Smith Scalar *array; 2812d61bbb3SSatish Balay 2822d61bbb3SSatish Balay PetscFunctionBegin; 28329bbc08cSBarry Smith if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place"); 284b0a32e0cSBarry Smith ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr); 285549d3d68SSatish Balay ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr); 2862d61bbb3SSatish Balay 287375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 288b0a32e0cSBarry Smith ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr); 289375fe846SBarry Smith for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i]; 290375fe846SBarry Smith #else 2913eda8832SBarry Smith array = a->a; 292375fe846SBarry Smith #endif 293375fe846SBarry Smith 2942d61bbb3SSatish Balay for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1; 295273d9f13SBarry Smith ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr); 296606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 297b0a32e0cSBarry Smith ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr); 2982d61bbb3SSatish Balay cols = rows + bs; 2992d61bbb3SSatish Balay for (i=0; i<mbs; i++) { 3002d61bbb3SSatish Balay cols[0] = i*bs; 3012d61bbb3SSatish Balay for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1; 3022d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 3032d61bbb3SSatish Balay for (j=0; j<len; j++) { 3042d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 3052d61bbb3SSatish Balay for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1; 3062d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr); 3072d61bbb3SSatish Balay array += bs2; 3082d61bbb3SSatish Balay } 3092d61bbb3SSatish Balay } 310606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 311375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 312375fe846SBarry Smith ierr = PetscFree(array); 313375fe846SBarry Smith #endif 3142d61bbb3SSatish Balay 3152d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3162d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3172d61bbb3SSatish Balay 318c4992f7dSBarry Smith if (B) { 3192d61bbb3SSatish Balay *B = C; 3202d61bbb3SSatish Balay } else { 321273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 3222d61bbb3SSatish Balay } 3232d61bbb3SSatish Balay PetscFunctionReturn(0); 3242d61bbb3SSatish Balay } 3252d61bbb3SSatish Balay 3265615d1e5SSatish Balay #undef __FUNC__ 327b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary" 328b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer) 3292593348eSBarry Smith { 330b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 3319df24120SSatish Balay int i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 332b6490206SBarry Smith Scalar *aa; 333ce6f0cecSBarry Smith FILE *file; 3342593348eSBarry Smith 3353a40ed3dSBarry Smith PetscFunctionBegin; 336b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 337b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 3382593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3393b2fbd54SBarry Smith 340273d9f13SBarry Smith col_lens[1] = A->m; 341273d9f13SBarry Smith col_lens[2] = A->n; 3427e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3432593348eSBarry Smith 3442593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 345b6490206SBarry Smith count = 0; 346b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 347b6490206SBarry Smith for (j=0; j<bs; j++) { 348b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 349b6490206SBarry Smith } 3502593348eSBarry Smith } 351273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 352606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 3532593348eSBarry Smith 3542593348eSBarry Smith /* store column indices (zero start index) */ 355b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr); 356b6490206SBarry Smith count = 0; 357b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 358b6490206SBarry Smith for (j=0; j<bs; j++) { 359b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 360b6490206SBarry Smith for (l=0; l<bs; l++) { 361b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3622593348eSBarry Smith } 3632593348eSBarry Smith } 364b6490206SBarry Smith } 365b6490206SBarry Smith } 3660752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr); 367606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 3682593348eSBarry Smith 3692593348eSBarry Smith /* store nonzero values */ 370b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr); 371b6490206SBarry Smith count = 0; 372b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 373b6490206SBarry Smith for (j=0; j<bs; j++) { 374b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 375b6490206SBarry Smith for (l=0; l<bs; l++) { 3767e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 377b6490206SBarry Smith } 378b6490206SBarry Smith } 379b6490206SBarry Smith } 380b6490206SBarry Smith } 3810752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 382606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 383ce6f0cecSBarry Smith 384b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 385ce6f0cecSBarry Smith if (file) { 386ce6f0cecSBarry Smith fprintf(file,"-matload_block_size %d\n",a->bs); 387ce6f0cecSBarry Smith } 3883a40ed3dSBarry Smith PetscFunctionReturn(0); 3892593348eSBarry Smith } 3902593348eSBarry Smith 3915615d1e5SSatish Balay #undef __FUNC__ 392b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII" 393b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer) 3942593348eSBarry Smith { 395b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 396fb9695e5SSatish Balay int ierr,i,j,bs = a->bs,k,l,bs2=a->bs2; 397f3ef73ceSBarry Smith PetscViewerFormat format; 3982593348eSBarry Smith 3993a40ed3dSBarry Smith PetscFunctionBegin; 400b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 401fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) { 402b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %d\n",bs);CHKERRQ(ierr); 403fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 40429bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Matlab format not supported"); 405fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 406b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 40744cd7ae7SLois Curfman McInnes for (i=0; i<a->mbs; i++) { 40844cd7ae7SLois Curfman McInnes for (j=0; j<bs; j++) { 409b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 41044cd7ae7SLois Curfman McInnes for (k=a->i[i]; k<a->i[i+1]; k++) { 41144cd7ae7SLois Curfman McInnes for (l=0; l<bs; l++) { 412aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4130e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 414b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l, 4150e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4160e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 417b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l, 4180e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4190e6d2581SBarry Smith } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 420b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4210ef38995SBarry Smith } 42244cd7ae7SLois Curfman McInnes #else 4230ef38995SBarry Smith if (a->a[bs2*k + l*bs + j] != 0.0) { 424b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 4250ef38995SBarry Smith } 42644cd7ae7SLois Curfman McInnes #endif 42744cd7ae7SLois Curfman McInnes } 42844cd7ae7SLois Curfman McInnes } 429b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 43044cd7ae7SLois Curfman McInnes } 43144cd7ae7SLois Curfman McInnes } 432b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4330ef38995SBarry Smith } else { 434b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 435b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 436b6490206SBarry Smith for (j=0; j<bs; j++) { 437b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 438b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 439b6490206SBarry Smith for (l=0; l<bs; l++) { 440aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4410e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 442b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l, 4430e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4440e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 445b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l, 4460e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4470ef38995SBarry Smith } else { 448b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 44988685aaeSLois Curfman McInnes } 45088685aaeSLois Curfman McInnes #else 451b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 45288685aaeSLois Curfman McInnes #endif 4532593348eSBarry Smith } 4542593348eSBarry Smith } 455b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 4562593348eSBarry Smith } 4572593348eSBarry Smith } 458b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 459b6490206SBarry Smith } 460b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4613a40ed3dSBarry Smith PetscFunctionReturn(0); 4622593348eSBarry Smith } 4632593348eSBarry Smith 4645615d1e5SSatish Balay #undef __FUNC__ 465b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom" 466b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 4673270192aSSatish Balay { 46877ed5343SBarry Smith Mat A = (Mat) Aa; 4693270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ*)A->data; 470b65db4caSBarry Smith int row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2; 4710e6d2581SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 4723f1db9ecSBarry Smith MatScalar *aa; 473b0a32e0cSBarry Smith PetscViewer viewer; 4743270192aSSatish Balay 4753a40ed3dSBarry Smith PetscFunctionBegin; 4763270192aSSatish Balay 477b65db4caSBarry Smith /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/ 47877ed5343SBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 47977ed5343SBarry Smith 480b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 48177ed5343SBarry Smith 4823270192aSSatish Balay /* loop over matrix elements drawing boxes */ 483b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 4843270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 4853270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 486273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 4873270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4883270192aSSatish Balay aa = a->a + j*bs2; 4893270192aSSatish Balay for (k=0; k<bs; k++) { 4903270192aSSatish Balay for (l=0; l<bs; l++) { 4910e6d2581SBarry Smith if (PetscRealPart(*aa++) >= 0.) continue; 492b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 4933270192aSSatish Balay } 4943270192aSSatish Balay } 4953270192aSSatish Balay } 4963270192aSSatish Balay } 497b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 4983270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 4993270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 500273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5013270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5023270192aSSatish Balay aa = a->a + j*bs2; 5033270192aSSatish Balay for (k=0; k<bs; k++) { 5043270192aSSatish Balay for (l=0; l<bs; l++) { 5050e6d2581SBarry Smith if (PetscRealPart(*aa++) != 0.) continue; 506b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5073270192aSSatish Balay } 5083270192aSSatish Balay } 5093270192aSSatish Balay } 5103270192aSSatish Balay } 5113270192aSSatish Balay 512b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 5133270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5143270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 515273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5163270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5173270192aSSatish Balay aa = a->a + j*bs2; 5183270192aSSatish Balay for (k=0; k<bs; k++) { 5193270192aSSatish Balay for (l=0; l<bs; l++) { 5200e6d2581SBarry Smith if (PetscRealPart(*aa++) <= 0.) continue; 521b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5223270192aSSatish Balay } 5233270192aSSatish Balay } 5243270192aSSatish Balay } 5253270192aSSatish Balay } 52677ed5343SBarry Smith PetscFunctionReturn(0); 52777ed5343SBarry Smith } 5283270192aSSatish Balay 52977ed5343SBarry Smith #undef __FUNC__ 530b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw" 531b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer) 53277ed5343SBarry Smith { 5337dce120fSSatish Balay int ierr; 5340e6d2581SBarry Smith PetscReal xl,yl,xr,yr,w,h; 535b0a32e0cSBarry Smith PetscDraw draw; 53677ed5343SBarry Smith PetscTruth isnull; 5373270192aSSatish Balay 53877ed5343SBarry Smith PetscFunctionBegin; 53977ed5343SBarry Smith 540b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 541b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 54277ed5343SBarry Smith 54377ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 544273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 54577ed5343SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 546b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 547b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 54877ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5493a40ed3dSBarry Smith PetscFunctionReturn(0); 5503270192aSSatish Balay } 5513270192aSSatish Balay 5525615d1e5SSatish Balay #undef __FUNC__ 553b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ" 554b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer) 5552593348eSBarry Smith { 55619bcc07fSBarry Smith int ierr; 5576831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 5582593348eSBarry Smith 5593a40ed3dSBarry Smith PetscFunctionBegin; 560b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 561b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 562fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 563fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 5640f5bd95cSBarry Smith if (issocket) { 56529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported"); 5660f5bd95cSBarry Smith } else if (isascii){ 5673a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5680f5bd95cSBarry Smith } else if (isbinary) { 5693a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 5700f5bd95cSBarry Smith } else if (isdraw) { 5713a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 5725cd90555SBarry Smith } else { 57329bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name); 5742593348eSBarry Smith } 5753a40ed3dSBarry Smith PetscFunctionReturn(0); 5762593348eSBarry Smith } 577b6490206SBarry Smith 578cd0e1443SSatish Balay 5795615d1e5SSatish Balay #undef __FUNC__ 580b0a32e0cSBarry Smith #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; 5873f1db9ecSBarry Smith MatScalar *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; 59229bbc08cSBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row"); 593273d9f13SBarry Smith if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"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 */ 59729bbc08cSBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column"); 598273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"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 62495d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 62595d5f7c2SBarry Smith #undef __FUNC__ 626b0a32e0cSBarry Smith #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 62795d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv) 62895d5f7c2SBarry Smith { 629563b5814SBarry Smith Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data; 630563b5814SBarry Smith int ierr,i,N = m*n*b->bs2; 631563b5814SBarry Smith MatScalar *vsingle; 63295d5f7c2SBarry Smith 63395d5f7c2SBarry Smith PetscFunctionBegin; 634563b5814SBarry Smith if (N > b->setvalueslen) { 635563b5814SBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 636b0a32e0cSBarry Smith ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 637563b5814SBarry Smith b->setvalueslen = N; 638563b5814SBarry Smith } 639563b5814SBarry Smith vsingle = b->setvaluescopy; 64095d5f7c2SBarry Smith for (i=0; i<N; i++) { 64195d5f7c2SBarry Smith vsingle[i] = v[i]; 64295d5f7c2SBarry Smith } 64395d5f7c2SBarry Smith ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 64495d5f7c2SBarry Smith PetscFunctionReturn(0); 64595d5f7c2SBarry Smith } 64695d5f7c2SBarry Smith #endif 64795d5f7c2SBarry Smith 6482d61bbb3SSatish Balay 6495615d1e5SSatish Balay #undef __FUNC__ 650b0a32e0cSBarry Smith #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 65195d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is) 65292c4ed94SBarry Smith { 65392c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 6548a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 655273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 656549d3d68SSatish Balay int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr; 657273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 65895d5f7c2SBarry Smith MatScalar *value = v,*ap,*aa = a->a,*bap; 65992c4ed94SBarry Smith 6603a40ed3dSBarry Smith PetscFunctionBegin; 6610e324ae4SSatish Balay if (roworiented) { 6620e324ae4SSatish Balay stepval = (n-1)*bs; 6630e324ae4SSatish Balay } else { 6640e324ae4SSatish Balay stepval = (m-1)*bs; 6650e324ae4SSatish Balay } 66692c4ed94SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 66792c4ed94SBarry Smith row = im[k]; 6685ef9f2a5SBarry Smith if (row < 0) continue; 669aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 67029bbc08cSBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 67192c4ed94SBarry Smith #endif 67292c4ed94SBarry Smith rp = aj + ai[row]; 67392c4ed94SBarry Smith ap = aa + bs2*ai[row]; 67492c4ed94SBarry Smith rmax = imax[row]; 67592c4ed94SBarry Smith nrow = ailen[row]; 67692c4ed94SBarry Smith low = 0; 67792c4ed94SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 6785ef9f2a5SBarry Smith if (in[l] < 0) continue; 679aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 68029bbc08cSBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 68192c4ed94SBarry Smith #endif 68292c4ed94SBarry Smith col = in[l]; 68392c4ed94SBarry Smith if (roworiented) { 6840e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 6850e324ae4SSatish Balay } else { 6860e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 68792c4ed94SBarry Smith } 68892c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 68992c4ed94SBarry Smith while (high-low > 7) { 69092c4ed94SBarry Smith t = (low+high)/2; 69192c4ed94SBarry Smith if (rp[t] > col) high = t; 69292c4ed94SBarry Smith else low = t; 69392c4ed94SBarry Smith } 69492c4ed94SBarry Smith for (i=low; i<high; i++) { 69592c4ed94SBarry Smith if (rp[i] > col) break; 69692c4ed94SBarry Smith if (rp[i] == col) { 6978a84c255SSatish Balay bap = ap + bs2*i; 6980e324ae4SSatish Balay if (roworiented) { 6998a84c255SSatish Balay if (is == ADD_VALUES) { 700dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 701dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7028a84c255SSatish Balay bap[jj] += *value++; 703dd9472c6SBarry Smith } 704dd9472c6SBarry Smith } 7050e324ae4SSatish Balay } else { 706dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 707dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7080e324ae4SSatish Balay bap[jj] = *value++; 7098a84c255SSatish Balay } 710dd9472c6SBarry Smith } 711dd9472c6SBarry Smith } 7120e324ae4SSatish Balay } else { 7130e324ae4SSatish Balay if (is == ADD_VALUES) { 714dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 715dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7160e324ae4SSatish Balay *bap++ += *value++; 717dd9472c6SBarry Smith } 718dd9472c6SBarry Smith } 7190e324ae4SSatish Balay } else { 720dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 721dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7220e324ae4SSatish Balay *bap++ = *value++; 7230e324ae4SSatish Balay } 7248a84c255SSatish Balay } 725dd9472c6SBarry Smith } 726dd9472c6SBarry Smith } 727f1241b54SBarry Smith goto noinsert2; 72892c4ed94SBarry Smith } 72992c4ed94SBarry Smith } 73089280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 73129bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 73292c4ed94SBarry Smith if (nrow >= rmax) { 73392c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 73492c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 7353f1db9ecSBarry Smith MatScalar *new_a; 73692c4ed94SBarry Smith 73729bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 73889280ab3SLois Curfman McInnes 73992c4ed94SBarry Smith /* malloc new storage space */ 7403f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 741b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 74292c4ed94SBarry Smith new_j = (int*)(new_a + bs2*new_nz); 74392c4ed94SBarry Smith new_i = new_j + new_nz; 74492c4ed94SBarry Smith 74592c4ed94SBarry Smith /* copy over old data into new slots */ 74692c4ed94SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 74792c4ed94SBarry Smith for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 748549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr); 74992c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 750549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr); 751549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 752549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 753549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 75492c4ed94SBarry Smith /* free up old matrix storage */ 755606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 756606d414cSSatish Balay if (!a->singlemalloc) { 757606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 758606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 759606d414cSSatish Balay } 76092c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 761c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 76292c4ed94SBarry Smith 76392c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 76492c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 765b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 76692c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 76792c4ed94SBarry Smith a->reallocs++; 76892c4ed94SBarry Smith a->nz++; 76992c4ed94SBarry Smith } 77092c4ed94SBarry Smith N = nrow++ - 1; 77192c4ed94SBarry Smith /* shift up all the later entries in this row */ 77292c4ed94SBarry Smith for (ii=N; ii>=i; ii--) { 77392c4ed94SBarry Smith rp[ii+1] = rp[ii]; 774549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 77592c4ed94SBarry Smith } 776549d3d68SSatish Balay if (N >= i) { 777549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 778549d3d68SSatish Balay } 77992c4ed94SBarry Smith rp[i] = col; 7808a84c255SSatish Balay bap = ap + bs2*i; 7810e324ae4SSatish Balay if (roworiented) { 782dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 783dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7840e324ae4SSatish Balay bap[jj] = *value++; 785dd9472c6SBarry Smith } 786dd9472c6SBarry Smith } 7870e324ae4SSatish Balay } else { 788dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 789dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7900e324ae4SSatish Balay *bap++ = *value++; 7910e324ae4SSatish Balay } 792dd9472c6SBarry Smith } 793dd9472c6SBarry Smith } 794f1241b54SBarry Smith noinsert2:; 79592c4ed94SBarry Smith low = i; 79692c4ed94SBarry Smith } 79792c4ed94SBarry Smith ailen[row] = nrow; 79892c4ed94SBarry Smith } 7993a40ed3dSBarry Smith PetscFunctionReturn(0); 80092c4ed94SBarry Smith } 80192c4ed94SBarry Smith 802f2501298SSatish Balay 8035615d1e5SSatish Balay #undef __FUNC__ 804b0a32e0cSBarry Smith #define __FUNC__ "MatAssemblyEnd_SeqBAIJ" 8058f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 806584200bdSSatish Balay { 807584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 808584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 809273d9f13SBarry Smith int m = A->m,*ip,N,*ailen = a->ilen; 810549d3d68SSatish Balay int mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr; 8113f1db9ecSBarry Smith MatScalar *aa = a->a,*ap; 812584200bdSSatish Balay 8133a40ed3dSBarry Smith PetscFunctionBegin; 8143a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 815584200bdSSatish Balay 81643ee02c3SBarry Smith if (m) rmax = ailen[0]; 817584200bdSSatish Balay for (i=1; i<mbs; i++) { 818584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 819584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 820d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 821584200bdSSatish Balay if (fshift) { 822a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 823584200bdSSatish Balay N = ailen[i]; 824584200bdSSatish Balay for (j=0; j<N; j++) { 825584200bdSSatish Balay ip[j-fshift] = ip[j]; 826549d3d68SSatish Balay ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr); 827584200bdSSatish Balay } 828584200bdSSatish Balay } 829584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 830584200bdSSatish Balay } 831584200bdSSatish Balay if (mbs) { 832584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 833584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 834584200bdSSatish Balay } 835584200bdSSatish Balay /* reset ilen and imax for each row */ 836584200bdSSatish Balay for (i=0; i<mbs; i++) { 837584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 838584200bdSSatish Balay } 839a7c10996SSatish Balay a->nz = ai[mbs]; 840584200bdSSatish Balay 841584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 842584200bdSSatish Balay if (fshift && a->diag) { 843606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 844b0a32e0cSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(int)); 845584200bdSSatish Balay a->diag = 0; 846584200bdSSatish Balay } 847b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 848273d9f13SBarry Smith m,A->n,a->bs,fshift*bs2,a->nz*bs2); 849b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 850584200bdSSatish Balay a->reallocs); 851b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 852e2f3b5e9SSatish Balay a->reallocs = 0; 8530e6d2581SBarry Smith A->info.nz_unneeded = (PetscReal)fshift*bs2; 8544e220ebcSLois Curfman McInnes 8553a40ed3dSBarry Smith PetscFunctionReturn(0); 856584200bdSSatish Balay } 857584200bdSSatish Balay 8585a838052SSatish Balay 859bea157c4SSatish Balay 860bea157c4SSatish Balay /* 861bea157c4SSatish Balay This function returns an array of flags which indicate the locations of contiguous 862bea157c4SSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 863bea157c4SSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 864bea157c4SSatish Balay Assume: sizes should be long enough to hold all the values. 865bea157c4SSatish Balay */ 8665615d1e5SSatish Balay #undef __FUNC__ 867b0a32e0cSBarry Smith #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Blocks" 868bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max) 869d9b7c43dSSatish Balay { 870bea157c4SSatish Balay int i,j,k,row; 871bea157c4SSatish Balay PetscTruth flg; 8723a40ed3dSBarry Smith 873433994e6SBarry Smith PetscFunctionBegin; 874bea157c4SSatish Balay for (i=0,j=0; i<n; j++) { 875bea157c4SSatish Balay row = idx[i]; 876bea157c4SSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 877bea157c4SSatish Balay sizes[j] = 1; 878bea157c4SSatish Balay i++; 879e4fda26cSSatish Balay } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */ 880bea157c4SSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 881bea157c4SSatish Balay i++; 882bea157c4SSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 883bea157c4SSatish Balay flg = PETSC_TRUE; 884bea157c4SSatish Balay for (k=1; k<bs; k++) { 885bea157c4SSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 886bea157c4SSatish Balay flg = PETSC_FALSE; 887bea157c4SSatish Balay break; 888d9b7c43dSSatish Balay } 889bea157c4SSatish Balay } 890bea157c4SSatish Balay if (flg == PETSC_TRUE) { /* No break in the bs */ 891bea157c4SSatish Balay sizes[j] = bs; 892bea157c4SSatish Balay i+= bs; 893bea157c4SSatish Balay } else { 894bea157c4SSatish Balay sizes[j] = 1; 895bea157c4SSatish Balay i++; 896bea157c4SSatish Balay } 897bea157c4SSatish Balay } 898bea157c4SSatish Balay } 899bea157c4SSatish Balay *bs_max = j; 9003a40ed3dSBarry Smith PetscFunctionReturn(0); 901d9b7c43dSSatish Balay } 902d9b7c43dSSatish Balay 9035615d1e5SSatish Balay #undef __FUNC__ 904b0a32e0cSBarry Smith #define __FUNC__ "MatZeroRows_SeqBAIJ" 9058f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag) 906d9b7c43dSSatish Balay { 907d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 908b6815fffSBarry Smith int ierr,i,j,k,count,is_n,*is_idx,*rows; 909bea157c4SSatish Balay int bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max; 9103f1db9ecSBarry Smith Scalar zero = 0.0; 9113f1db9ecSBarry Smith MatScalar *aa; 912d9b7c43dSSatish Balay 9133a40ed3dSBarry Smith PetscFunctionBegin; 914d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 915b9b97703SBarry Smith ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr); 916d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 917d9b7c43dSSatish Balay 918bea157c4SSatish Balay /* allocate memory for rows,sizes */ 919b0a32e0cSBarry Smith ierr = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr); 920bea157c4SSatish Balay sizes = rows + is_n; 921bea157c4SSatish Balay 922563b5814SBarry Smith /* copy IS values to rows, and sort them */ 923bea157c4SSatish Balay for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; } 924bea157c4SSatish Balay ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr); 925dffd3267SBarry Smith if (baij->keepzeroedrows) { 926dffd3267SBarry Smith for (i=0; i<is_n; i++) { sizes[i] = 1; } 927dffd3267SBarry Smith bs_max = is_n; 928dffd3267SBarry Smith } else { 929bea157c4SSatish Balay ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr); 930dffd3267SBarry Smith } 931b97a56abSSatish Balay ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr); 932bea157c4SSatish Balay 933bea157c4SSatish Balay for (i=0,j=0; i<bs_max; j+=sizes[i],i++) { 934bea157c4SSatish Balay row = rows[j]; 935273d9f13SBarry Smith if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row); 936bea157c4SSatish Balay count = (baij->i[row/bs +1] - baij->i[row/bs])*bs; 937bea157c4SSatish Balay aa = baij->a + baij->i[row/bs]*bs2 + (row%bs); 938dffd3267SBarry Smith if (sizes[i] == bs && !baij->keepzeroedrows) { 939bea157c4SSatish Balay if (diag) { 940bea157c4SSatish Balay if (baij->ilen[row/bs] > 0) { 941bea157c4SSatish Balay baij->ilen[row/bs] = 1; 942bea157c4SSatish Balay baij->j[baij->i[row/bs]] = row/bs; 943bea157c4SSatish Balay ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr); 944a07cd24cSSatish Balay } 945563b5814SBarry Smith /* Now insert all the diagonal values for this bs */ 946bea157c4SSatish Balay for (k=0; k<bs; k++) { 947bea157c4SSatish Balay ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr); 948bea157c4SSatish Balay } 949bea157c4SSatish Balay } else { /* (!diag) */ 950bea157c4SSatish Balay baij->ilen[row/bs] = 0; 951bea157c4SSatish Balay } /* end (!diag) */ 952bea157c4SSatish Balay } else { /* (sizes[i] != bs) */ 953aa482453SBarry Smith #if defined (PETSC_USE_DEBUG) 95429bbc08cSBarry Smith if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1"); 955bea157c4SSatish Balay #endif 956bea157c4SSatish Balay for (k=0; k<count; k++) { 957d9b7c43dSSatish Balay aa[0] = zero; 958d9b7c43dSSatish Balay aa += bs; 959d9b7c43dSSatish Balay } 960d9b7c43dSSatish Balay if (diag) { 961f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 962d9b7c43dSSatish Balay } 963d9b7c43dSSatish Balay } 964bea157c4SSatish Balay } 965bea157c4SSatish Balay 966606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 9679a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9683a40ed3dSBarry Smith PetscFunctionReturn(0); 969d9b7c43dSSatish Balay } 9701c351548SSatish Balay 9715615d1e5SSatish Balay #undef __FUNC__ 972b0a32e0cSBarry Smith #define __FUNC__ "MatSetValues_SeqBAIJ" 9732d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9742d61bbb3SSatish Balay { 9752d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 9762d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 977273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 9782d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 979549d3d68SSatish Balay int ridx,cidx,bs2=a->bs2,ierr; 980273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 9813f1db9ecSBarry Smith MatScalar *ap,value,*aa=a->a,*bap; 9822d61bbb3SSatish Balay 9832d61bbb3SSatish Balay PetscFunctionBegin; 9842d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 9852d61bbb3SSatish Balay row = im[k]; brow = row/bs; 9865ef9f2a5SBarry Smith if (row < 0) continue; 987aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 988273d9f13SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m); 9892d61bbb3SSatish Balay #endif 9902d61bbb3SSatish Balay rp = aj + ai[brow]; 9912d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 9922d61bbb3SSatish Balay rmax = imax[brow]; 9932d61bbb3SSatish Balay nrow = ailen[brow]; 9942d61bbb3SSatish Balay low = 0; 9952d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 9965ef9f2a5SBarry Smith if (in[l] < 0) continue; 997aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 998273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n); 9992d61bbb3SSatish Balay #endif 10002d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 10012d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 10022d61bbb3SSatish Balay if (roworiented) { 10035ef9f2a5SBarry Smith value = v[l + k*n]; 10042d61bbb3SSatish Balay } else { 10052d61bbb3SSatish Balay value = v[k + l*m]; 10062d61bbb3SSatish Balay } 10072d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 10082d61bbb3SSatish Balay while (high-low > 7) { 10092d61bbb3SSatish Balay t = (low+high)/2; 10102d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 10112d61bbb3SSatish Balay else low = t; 10122d61bbb3SSatish Balay } 10132d61bbb3SSatish Balay for (i=low; i<high; i++) { 10142d61bbb3SSatish Balay if (rp[i] > bcol) break; 10152d61bbb3SSatish Balay if (rp[i] == bcol) { 10162d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 10172d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 10182d61bbb3SSatish Balay else *bap = value; 10192d61bbb3SSatish Balay goto noinsert1; 10202d61bbb3SSatish Balay } 10212d61bbb3SSatish Balay } 10222d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 102329bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10242d61bbb3SSatish Balay if (nrow >= rmax) { 10252d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 10262d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 10273f1db9ecSBarry Smith MatScalar *new_a; 10282d61bbb3SSatish Balay 102929bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10302d61bbb3SSatish Balay 10312d61bbb3SSatish Balay /* Malloc new storage space */ 10323f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 1033b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 10342d61bbb3SSatish Balay new_j = (int*)(new_a + bs2*new_nz); 10352d61bbb3SSatish Balay new_i = new_j + new_nz; 10362d61bbb3SSatish Balay 10372d61bbb3SSatish Balay /* copy over old data into new slots */ 10382d61bbb3SSatish Balay for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];} 10392d61bbb3SSatish Balay for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 1040549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr); 10412d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 1042549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr); 1043549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1044549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 1045549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 10462d61bbb3SSatish Balay /* free up old matrix storage */ 1047606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 1048606d414cSSatish Balay if (!a->singlemalloc) { 1049606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 1050606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 1051606d414cSSatish Balay } 10522d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 1053c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 10542d61bbb3SSatish Balay 10552d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 10562d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 1057b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 10582d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 10592d61bbb3SSatish Balay a->reallocs++; 10602d61bbb3SSatish Balay a->nz++; 10612d61bbb3SSatish Balay } 10622d61bbb3SSatish Balay N = nrow++ - 1; 10632d61bbb3SSatish Balay /* shift up all the later entries in this row */ 10642d61bbb3SSatish Balay for (ii=N; ii>=i; ii--) { 10652d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 1066549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 10672d61bbb3SSatish Balay } 1068549d3d68SSatish Balay if (N>=i) { 1069549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 1070549d3d68SSatish Balay } 10712d61bbb3SSatish Balay rp[i] = bcol; 10722d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10732d61bbb3SSatish Balay noinsert1:; 10742d61bbb3SSatish Balay low = i; 10752d61bbb3SSatish Balay } 10762d61bbb3SSatish Balay ailen[brow] = nrow; 10772d61bbb3SSatish Balay } 10782d61bbb3SSatish Balay PetscFunctionReturn(0); 10792d61bbb3SSatish Balay } 10802d61bbb3SSatish Balay 1081b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,MatLUInfo*,Mat*); 1082b9b97703SBarry Smith EXTERN int MatLUFactor_SeqBAIJ(Mat,IS,IS,MatLUInfo*); 1083ca44d042SBarry Smith EXTERN int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 1084ca44d042SBarry Smith EXTERN int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*); 1085ca44d042SBarry Smith EXTERN int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**); 1086ca44d042SBarry Smith EXTERN int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec); 1087ca44d042SBarry Smith EXTERN int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 1088ca44d042SBarry Smith EXTERN int MatScale_SeqBAIJ(Scalar*,Mat); 1089ca44d042SBarry Smith EXTERN int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *); 1090ca44d042SBarry Smith EXTERN int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*); 1091ca44d042SBarry Smith EXTERN int MatGetDiagonal_SeqBAIJ(Mat,Vec); 1092ca44d042SBarry Smith EXTERN int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 1093ca44d042SBarry Smith EXTERN int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 1094ca44d042SBarry Smith EXTERN int MatZeroEntries_SeqBAIJ(Mat); 10952d61bbb3SSatish Balay 1096ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 1097ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 1098ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 1099ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 1100ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 1101ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 1102ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_6(Mat,Vec,Vec); 1103ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 1104ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec); 1105ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec); 1106ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec); 1107ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec); 1108ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec); 1109ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec); 1110ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec); 11112d61bbb3SSatish Balay 1112ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 1113ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 1114ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 1115ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 1116ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 1117ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 1118ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*); 11192d61bbb3SSatish Balay 1120ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 1121ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 1122ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 1123ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 1124ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 1125ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_6(Mat,Vec,Vec); 1126ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 1127ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 11282d61bbb3SSatish Balay 1129ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 1130ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 1131ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 1132ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 1133ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 1134ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec); 1135ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 1136ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 11372d61bbb3SSatish Balay 11382d61bbb3SSatish Balay #undef __FUNC__ 1139b0a32e0cSBarry Smith #define __FUNC__ "MatILUFactor_SeqBAIJ" 11405ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 11412d61bbb3SSatish Balay { 11422d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data; 11432d61bbb3SSatish Balay Mat outA; 11442d61bbb3SSatish Balay int ierr; 1145667159a5SBarry Smith PetscTruth row_identity,col_identity; 11462d61bbb3SSatish Balay 11472d61bbb3SSatish Balay PetscFunctionBegin; 114829bbc08cSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU"); 1149667159a5SBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1150667159a5SBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1151667159a5SBarry Smith if (!row_identity || !col_identity) { 115229bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1153667159a5SBarry Smith } 11542d61bbb3SSatish Balay 11552d61bbb3SSatish Balay outA = inA; 11562d61bbb3SSatish Balay inA->factor = FACTOR_LU; 11572d61bbb3SSatish Balay 11582d61bbb3SSatish Balay if (!a->diag) { 1159c4992f7dSBarry Smith ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr); 11602d61bbb3SSatish Balay } 11612d61bbb3SSatish Balay /* 116215091d37SBarry Smith Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver 116315091d37SBarry Smith for ILU(0) factorization with natural ordering 11642d61bbb3SSatish Balay */ 116515091d37SBarry Smith switch (a->bs) { 1166f1af5d2fSBarry Smith case 1: 1167e37c484bSBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1168e37c484bSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_1_NaturalOrdering; 1169e37c484bSBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_1_NaturalOrdering; 1170b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=1\n"); 117115091d37SBarry Smith case 2: 117215091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering; 117315091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_2_NaturalOrdering; 11747c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering; 1175b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n"); 117615091d37SBarry Smith break; 117715091d37SBarry Smith case 3: 117815091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering; 117915091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_3_NaturalOrdering; 11807c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering; 1181b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n"); 118215091d37SBarry Smith break; 118315091d37SBarry Smith case 4: 1184667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering; 1185f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 11867c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering; 1187b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n"); 118815091d37SBarry Smith break; 118915091d37SBarry Smith case 5: 1190667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering; 1191667159a5SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_5_NaturalOrdering; 11927c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering; 1193b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n"); 119415091d37SBarry Smith break; 119515091d37SBarry Smith case 6: 119615091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering; 119715091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_6_NaturalOrdering; 11987c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering; 1199b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n"); 120015091d37SBarry Smith break; 120115091d37SBarry Smith case 7: 120215091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering; 12037c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering; 120415091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_7_NaturalOrdering; 1205b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n"); 120615091d37SBarry Smith break; 1207c38d4ed2SBarry Smith default: 1208c38d4ed2SBarry Smith a->row = row; 1209c38d4ed2SBarry Smith a->col = col; 1210c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1211c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1212c38d4ed2SBarry Smith 1213c38d4ed2SBarry Smith /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 12144c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1215b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1216c38d4ed2SBarry Smith 1217c38d4ed2SBarry Smith if (!a->solve_work) { 1218b0a32e0cSBarry Smith ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr); 1219b0a32e0cSBarry Smith PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar)); 1220c38d4ed2SBarry Smith } 12212d61bbb3SSatish Balay } 12222d61bbb3SSatish Balay 1223667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr); 1224667159a5SBarry Smith 12252d61bbb3SSatish Balay PetscFunctionReturn(0); 12262d61bbb3SSatish Balay } 12272d61bbb3SSatish Balay #undef __FUNC__ 1228b0a32e0cSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ" 1229ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1230ba4ca20aSSatish Balay { 1231c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1232ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1233d132466eSBarry Smith int ierr; 1234ba4ca20aSSatish Balay 12353a40ed3dSBarry Smith PetscFunctionBegin; 1236c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1237d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1238d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n");CHKERRQ(ierr); 12393a40ed3dSBarry Smith PetscFunctionReturn(0); 1240ba4ca20aSSatish Balay } 1241d9b7c43dSSatish Balay 1242fb2e594dSBarry Smith EXTERN_C_BEGIN 124327a8da17SBarry Smith #undef __FUNC__ 1244b0a32e0cSBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 124527a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 124627a8da17SBarry Smith { 124727a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 124827a8da17SBarry Smith int i,nz,n; 124927a8da17SBarry Smith 125027a8da17SBarry Smith PetscFunctionBegin; 125127a8da17SBarry Smith nz = baij->maxnz; 1252273d9f13SBarry Smith n = mat->n; 125327a8da17SBarry Smith for (i=0; i<nz; i++) { 125427a8da17SBarry Smith baij->j[i] = indices[i]; 125527a8da17SBarry Smith } 125627a8da17SBarry Smith baij->nz = nz; 125727a8da17SBarry Smith for (i=0; i<n; i++) { 125827a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 125927a8da17SBarry Smith } 126027a8da17SBarry Smith 126127a8da17SBarry Smith PetscFunctionReturn(0); 126227a8da17SBarry Smith } 1263fb2e594dSBarry Smith EXTERN_C_END 126427a8da17SBarry Smith 126527a8da17SBarry Smith #undef __FUNC__ 1266b0a32e0cSBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices" 126727a8da17SBarry Smith /*@ 126827a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 126927a8da17SBarry Smith in the matrix. 127027a8da17SBarry Smith 127127a8da17SBarry Smith Input Parameters: 127227a8da17SBarry Smith + mat - the SeqBAIJ matrix 127327a8da17SBarry Smith - indices - the column indices 127427a8da17SBarry Smith 127515091d37SBarry Smith Level: advanced 127615091d37SBarry Smith 127727a8da17SBarry Smith Notes: 127827a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 127927a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 128027a8da17SBarry Smith of the MatSetValues() operation. 128127a8da17SBarry Smith 128227a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 128327a8da17SBarry Smith MatCreateSeqBAIJ(). 128427a8da17SBarry Smith 128527a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 128627a8da17SBarry Smith 128727a8da17SBarry Smith @*/ 128827a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 128927a8da17SBarry Smith { 129027a8da17SBarry Smith int ierr,(*f)(Mat,int *); 129127a8da17SBarry Smith 129227a8da17SBarry Smith PetscFunctionBegin; 129327a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1294549d3d68SSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr); 129527a8da17SBarry Smith if (f) { 129627a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 129727a8da17SBarry Smith } else { 129829bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 129927a8da17SBarry Smith } 130027a8da17SBarry Smith PetscFunctionReturn(0); 130127a8da17SBarry Smith } 130227a8da17SBarry Smith 1303273d9f13SBarry Smith #undef __FUNC__ 1304273d9f13SBarry Smith #define __FUNC__ "MatGetRowMax_SeqBAIJ" 1305273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v) 1306273d9f13SBarry Smith { 1307273d9f13SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1308273d9f13SBarry Smith int ierr,i,j,n,row,bs,*ai,*aj,mbs; 1309273d9f13SBarry Smith PetscReal atmp; 1310273d9f13SBarry Smith Scalar *x,zero = 0.0; 1311273d9f13SBarry Smith MatScalar *aa; 1312273d9f13SBarry Smith int ncols,brow,krow,kcol; 1313273d9f13SBarry Smith 1314273d9f13SBarry Smith PetscFunctionBegin; 1315273d9f13SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1316273d9f13SBarry Smith bs = a->bs; 1317273d9f13SBarry Smith aa = a->a; 1318273d9f13SBarry Smith ai = a->i; 1319273d9f13SBarry Smith aj = a->j; 1320273d9f13SBarry Smith mbs = a->mbs; 1321273d9f13SBarry Smith 1322273d9f13SBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 1323273d9f13SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1324273d9f13SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1325273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1326273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1327273d9f13SBarry Smith ncols = ai[1] - ai[0]; ai++; 1328273d9f13SBarry Smith brow = bs*i; 1329273d9f13SBarry Smith for (j=0; j<ncols; j++){ 1330273d9f13SBarry Smith /* bcol = bs*(*aj); */ 1331273d9f13SBarry Smith for (kcol=0; kcol<bs; kcol++){ 1332273d9f13SBarry Smith for (krow=0; krow<bs; krow++){ 1333273d9f13SBarry Smith atmp = PetscAbsScalar(*aa); aa++; 1334273d9f13SBarry Smith row = brow + krow; /* row index */ 1335273d9f13SBarry Smith /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */ 1336273d9f13SBarry Smith if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp; 1337273d9f13SBarry Smith } 1338273d9f13SBarry Smith } 1339273d9f13SBarry Smith aj++; 1340273d9f13SBarry Smith } 1341273d9f13SBarry Smith } 1342273d9f13SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1343273d9f13SBarry Smith PetscFunctionReturn(0); 1344273d9f13SBarry Smith } 1345273d9f13SBarry Smith 1346273d9f13SBarry Smith #undef __FUNC__ 1347b0a32e0cSBarry Smith #define __FUNC__ "MatSetUpPreallocation_SeqBAIJ" 1348273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A) 1349273d9f13SBarry Smith { 1350273d9f13SBarry Smith int ierr; 1351273d9f13SBarry Smith 1352273d9f13SBarry Smith PetscFunctionBegin; 1353273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr); 1354273d9f13SBarry Smith PetscFunctionReturn(0); 1355273d9f13SBarry Smith } 1356273d9f13SBarry Smith 1357f2a5309cSSatish Balay #undef __FUNC__ 1358f2a5309cSSatish Balay #define __FUNC__ "MatGetArray_SeqBAIJ" 1359f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array) 1360f2a5309cSSatish Balay { 1361f2a5309cSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1362f2a5309cSSatish Balay PetscFunctionBegin; 1363f2a5309cSSatish Balay *array = a->a; 1364f2a5309cSSatish Balay PetscFunctionReturn(0); 1365f2a5309cSSatish Balay } 1366f2a5309cSSatish Balay 1367f2a5309cSSatish Balay #undef __FUNC__ 1368f2a5309cSSatish Balay #define __FUNC__ "MatRestoreArray_SeqBAIJ" 1369f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array) 1370f2a5309cSSatish Balay { 1371f2a5309cSSatish Balay PetscFunctionBegin; 1372f2a5309cSSatish Balay PetscFunctionReturn(0); 1373f2a5309cSSatish Balay } 1374f2a5309cSSatish Balay 13752593348eSBarry Smith /* -------------------------------------------------------------------*/ 1376cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1377cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1378cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1379cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1380cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 13817c922b88SBarry Smith MatMultTranspose_SeqBAIJ, 13827c922b88SBarry Smith MatMultTransposeAdd_SeqBAIJ, 1383cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1384cc2dc46cSBarry Smith 0, 1385cc2dc46cSBarry Smith 0, 1386cc2dc46cSBarry Smith 0, 1387cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1388cc2dc46cSBarry Smith 0, 1389b6490206SBarry Smith 0, 1390f2501298SSatish Balay MatTranspose_SeqBAIJ, 1391cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1392cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1393cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1394cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1395cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1396b6490206SBarry Smith 0, 1397cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1398cc2dc46cSBarry Smith 0, 1399cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1400cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1401cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1402cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1403cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1404cc2dc46cSBarry Smith 0, 1405cc2dc46cSBarry Smith 0, 1406273d9f13SBarry Smith MatSetUpPreallocation_SeqBAIJ, 1407273d9f13SBarry Smith 0, 1408cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1409cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1410cc2dc46cSBarry Smith 0, 1411f2a5309cSSatish Balay MatGetArray_SeqBAIJ, 1412f2a5309cSSatish Balay MatRestoreArray_SeqBAIJ, 14132e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1414cc2dc46cSBarry Smith 0, 1415cc2dc46cSBarry Smith 0, 1416cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1417cc2dc46cSBarry Smith 0, 1418cc2dc46cSBarry Smith 0, 1419cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1420cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1421cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1422cc2dc46cSBarry Smith 0, 1423cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1424cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1425cc2dc46cSBarry Smith 0, 1426cc2dc46cSBarry Smith 0, 1427cc2dc46cSBarry Smith 0, 1428cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 14293b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 143092c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1431cc2dc46cSBarry Smith 0, 1432cc2dc46cSBarry Smith 0, 1433cc2dc46cSBarry Smith 0, 1434cc2dc46cSBarry Smith 0, 1435cc2dc46cSBarry Smith 0, 1436cc2dc46cSBarry Smith 0, 1437d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1438cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1439b9b97703SBarry Smith MatDestroy_SeqBAIJ, 1440b9b97703SBarry Smith MatView_SeqBAIJ, 1441273d9f13SBarry Smith MatGetMaps_Petsc, 1442273d9f13SBarry Smith 0, 1443273d9f13SBarry Smith 0, 1444273d9f13SBarry Smith 0, 1445273d9f13SBarry Smith 0, 1446273d9f13SBarry Smith 0, 1447273d9f13SBarry Smith 0, 1448273d9f13SBarry Smith MatGetRowMax_SeqBAIJ, 1449273d9f13SBarry Smith MatConvert_Basic}; 14502593348eSBarry Smith 14513e90b805SBarry Smith EXTERN_C_BEGIN 14523e90b805SBarry Smith #undef __FUNC__ 1453b0a32e0cSBarry Smith #define __FUNC__ "MatStoreValues_SeqBAIJ" 14543e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat) 14553e90b805SBarry Smith { 14563e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1457273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2; 1458d132466eSBarry Smith int ierr; 14593e90b805SBarry Smith 14603e90b805SBarry Smith PetscFunctionBegin; 14613e90b805SBarry Smith if (aij->nonew != 1) { 146229bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14633e90b805SBarry Smith } 14643e90b805SBarry Smith 14653e90b805SBarry Smith /* allocate space for values if not already there */ 14663e90b805SBarry Smith if (!aij->saved_values) { 1467f2a5309cSSatish Balay ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr); 14683e90b805SBarry Smith } 14693e90b805SBarry Smith 14703e90b805SBarry Smith /* copy values over */ 1471d132466eSBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr); 14723e90b805SBarry Smith PetscFunctionReturn(0); 14733e90b805SBarry Smith } 14743e90b805SBarry Smith EXTERN_C_END 14753e90b805SBarry Smith 14763e90b805SBarry Smith EXTERN_C_BEGIN 14773e90b805SBarry Smith #undef __FUNC__ 1478b0a32e0cSBarry Smith #define __FUNC__ "MatRetrieveValues_SeqBAIJ" 147932e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat) 14803e90b805SBarry Smith { 14813e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1482273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr; 14833e90b805SBarry Smith 14843e90b805SBarry Smith PetscFunctionBegin; 14853e90b805SBarry Smith if (aij->nonew != 1) { 148629bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14873e90b805SBarry Smith } 14883e90b805SBarry Smith if (!aij->saved_values) { 148929bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 14903e90b805SBarry Smith } 14913e90b805SBarry Smith 14923e90b805SBarry Smith /* copy values over */ 1493549d3d68SSatish Balay ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr); 14943e90b805SBarry Smith PetscFunctionReturn(0); 14953e90b805SBarry Smith } 14963e90b805SBarry Smith EXTERN_C_END 14973e90b805SBarry Smith 1498273d9f13SBarry Smith EXTERN_C_BEGIN 1499273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*); 1500273d9f13SBarry Smith EXTERN_C_END 1501273d9f13SBarry Smith 1502273d9f13SBarry Smith EXTERN_C_BEGIN 15035615d1e5SSatish Balay #undef __FUNC__ 1504b0a32e0cSBarry Smith #define __FUNC__ "MatCreate_SeqBAIJ" 1505273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B) 15062593348eSBarry Smith { 1507273d9f13SBarry Smith int ierr,size; 1508b6490206SBarry Smith Mat_SeqBAIJ *b; 15093b2fbd54SBarry Smith 15103a40ed3dSBarry Smith PetscFunctionBegin; 1511273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 151229bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1513b6490206SBarry Smith 1514273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 1515273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 1516b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr); 1517b0a32e0cSBarry Smith B->data = (void*)b; 1518549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr); 1519549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 15202593348eSBarry Smith B->factor = 0; 15212593348eSBarry Smith B->lupivotthreshold = 1.0; 152290f02eecSBarry Smith B->mapping = 0; 15232593348eSBarry Smith b->row = 0; 15242593348eSBarry Smith b->col = 0; 1525e51c0b9cSSatish Balay b->icol = 0; 15262593348eSBarry Smith b->reallocs = 0; 15273e90b805SBarry Smith b->saved_values = 0; 1528cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 1529563b5814SBarry Smith b->setvalueslen = 0; 1530563b5814SBarry Smith b->setvaluescopy = PETSC_NULL; 1531563b5814SBarry Smith #endif 15322593348eSBarry Smith 1533273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 1534273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 1535a5ae1ecdSBarry Smith 1536c4992f7dSBarry Smith b->sorted = PETSC_FALSE; 1537c4992f7dSBarry Smith b->roworiented = PETSC_TRUE; 15382593348eSBarry Smith b->nonew = 0; 15392593348eSBarry Smith b->diag = 0; 15402593348eSBarry Smith b->solve_work = 0; 1541de6a44a3SBarry Smith b->mult_work = 0; 15422593348eSBarry Smith b->spptr = 0; 15430e6d2581SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1544883fce79SBarry Smith b->keepzeroedrows = PETSC_FALSE; 15454e220ebcSLois Curfman McInnes 1546f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 15473e90b805SBarry Smith "MatStoreValues_SeqBAIJ", 1548bc4b532fSSatish Balay MatStoreValues_SeqBAIJ);CHKERRQ(ierr); 1549f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 15503e90b805SBarry Smith "MatRetrieveValues_SeqBAIJ", 1551bc4b532fSSatish Balay MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr); 1552f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 155327a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 1554bc4b532fSSatish Balay MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 1555273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C", 1556273d9f13SBarry Smith "MatConvert_SeqBAIJ_SeqAIJ", 1557273d9f13SBarry Smith MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr); 15583a40ed3dSBarry Smith PetscFunctionReturn(0); 15592593348eSBarry Smith } 1560273d9f13SBarry Smith EXTERN_C_END 15612593348eSBarry Smith 15625615d1e5SSatish Balay #undef __FUNC__ 1563b0a32e0cSBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ" 15642e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 15652593348eSBarry Smith { 15662593348eSBarry Smith Mat C; 1567b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data; 156827a8da17SBarry Smith int i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1569de6a44a3SBarry Smith 15703a40ed3dSBarry Smith PetscFunctionBegin; 157129bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 15722593348eSBarry Smith 15732593348eSBarry Smith *B = 0; 1574273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 1575273d9f13SBarry Smith ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr); 1576273d9f13SBarry Smith c = (Mat_SeqBAIJ*)C->data; 157744cd7ae7SLois Curfman McInnes 1578b6490206SBarry Smith c->bs = a->bs; 15799df24120SSatish Balay c->bs2 = a->bs2; 1580b6490206SBarry Smith c->mbs = a->mbs; 1581b6490206SBarry Smith c->nbs = a->nbs; 158235d8aa7fSBarry Smith ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 15832593348eSBarry Smith 1584b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 1585b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 1586b6490206SBarry Smith for (i=0; i<mbs; i++) { 15872593348eSBarry Smith c->imax[i] = a->imax[i]; 15882593348eSBarry Smith c->ilen[i] = a->ilen[i]; 15892593348eSBarry Smith } 15902593348eSBarry Smith 15912593348eSBarry Smith /* allocate the matrix space */ 1592c4992f7dSBarry Smith c->singlemalloc = PETSC_TRUE; 15933f1db9ecSBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int)); 1594b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 15957e67e3f9SSatish Balay c->j = (int*)(c->a + nz*bs2); 1596de6a44a3SBarry Smith c->i = c->j + nz; 1597549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr); 1598b6490206SBarry Smith if (mbs > 0) { 1599549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr); 16002e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 1601549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16022e8a6d31SBarry Smith } else { 1603549d3d68SSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16042593348eSBarry Smith } 16052593348eSBarry Smith } 16062593348eSBarry Smith 1607b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 16082593348eSBarry Smith c->sorted = a->sorted; 16092593348eSBarry Smith c->roworiented = a->roworiented; 16102593348eSBarry Smith c->nonew = a->nonew; 16112593348eSBarry Smith 16122593348eSBarry Smith if (a->diag) { 1613b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 1614b0a32e0cSBarry Smith PetscLogObjectMemory(C,(mbs+1)*sizeof(int)); 1615b6490206SBarry Smith for (i=0; i<mbs; i++) { 16162593348eSBarry Smith c->diag[i] = a->diag[i]; 16172593348eSBarry Smith } 161898305bb5SBarry Smith } else c->diag = 0; 16192593348eSBarry Smith c->nz = a->nz; 16202593348eSBarry Smith c->maxnz = a->maxnz; 16212593348eSBarry Smith c->solve_work = 0; 16222593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 16237fc0212eSBarry Smith c->mult_work = 0; 1624273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 1625273d9f13SBarry Smith C->assembled = PETSC_TRUE; 16262593348eSBarry Smith *B = C; 1627b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 16283a40ed3dSBarry Smith PetscFunctionReturn(0); 16292593348eSBarry Smith } 16302593348eSBarry Smith 1631273d9f13SBarry Smith EXTERN_C_BEGIN 16325615d1e5SSatish Balay #undef __FUNC__ 1633b0a32e0cSBarry Smith #define __FUNC__ "MatLoad_SeqBAIJ" 1634b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A) 16352593348eSBarry Smith { 1636b6490206SBarry Smith Mat_SeqBAIJ *a; 16372593348eSBarry Smith Mat B; 1638f1af5d2fSBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1; 1639b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 164035aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1641a7c10996SSatish Balay int *masked,nmask,tmp,bs2,ishift; 1642b6490206SBarry Smith Scalar *aa; 164319bcc07fSBarry Smith MPI_Comm comm = ((PetscObject)viewer)->comm; 16442593348eSBarry Smith 16453a40ed3dSBarry Smith PetscFunctionBegin; 1646b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 1647de6a44a3SBarry Smith bs2 = bs*bs; 1648b6490206SBarry Smith 1649d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 165029bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 1651b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 16520752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 165329bbc08cSBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 16542593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 16552593348eSBarry Smith 1656d64ed03dSBarry Smith if (header[3] < 0) { 165729bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ"); 1658d64ed03dSBarry Smith } 1659d64ed03dSBarry Smith 166029bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 166135aab85fSBarry Smith 166235aab85fSBarry Smith /* 166335aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 166435aab85fSBarry Smith divisible by the blocksize 166535aab85fSBarry Smith */ 1666b6490206SBarry Smith mbs = M/bs; 166735aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 166835aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 166935aab85fSBarry Smith else mbs++; 167035aab85fSBarry Smith if (extra_rows) { 1671b0a32e0cSBarry Smith PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 167235aab85fSBarry Smith } 1673b6490206SBarry Smith 16742593348eSBarry Smith /* read in row lengths */ 1675b0a32e0cSBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr); 16760752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 167735aab85fSBarry Smith for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 16782593348eSBarry Smith 1679b6490206SBarry Smith /* read in column indices */ 1680b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr); 16810752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 168235aab85fSBarry Smith for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 1683b6490206SBarry Smith 1684b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1685b0a32e0cSBarry Smith ierr = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr); 1686549d3d68SSatish Balay ierr = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr); 1687b0a32e0cSBarry Smith ierr = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr); 1688549d3d68SSatish Balay ierr = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr); 168935aab85fSBarry Smith masked = mask + mbs; 1690b6490206SBarry Smith rowcount = 0; nzcount = 0; 1691b6490206SBarry Smith for (i=0; i<mbs; i++) { 169235aab85fSBarry Smith nmask = 0; 1693b6490206SBarry Smith for (j=0; j<bs; j++) { 1694b6490206SBarry Smith kmax = rowlengths[rowcount]; 1695b6490206SBarry Smith for (k=0; k<kmax; k++) { 169635aab85fSBarry Smith tmp = jj[nzcount++]/bs; 169735aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1698b6490206SBarry Smith } 1699b6490206SBarry Smith rowcount++; 1700b6490206SBarry Smith } 170135aab85fSBarry Smith browlengths[i] += nmask; 170235aab85fSBarry Smith /* zero out the mask elements we set */ 170335aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1704b6490206SBarry Smith } 1705b6490206SBarry Smith 17062593348eSBarry Smith /* create our matrix */ 17073eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 17082593348eSBarry Smith B = *A; 1709b6490206SBarry Smith a = (Mat_SeqBAIJ*)B->data; 17102593348eSBarry Smith 17112593348eSBarry Smith /* set matrix "i" values */ 1712de6a44a3SBarry Smith a->i[0] = 0; 1713b6490206SBarry Smith for (i=1; i<= mbs; i++) { 1714b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1715b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 17162593348eSBarry Smith } 1717b6490206SBarry Smith a->nz = 0; 1718b6490206SBarry Smith for (i=0; i<mbs; i++) a->nz += browlengths[i]; 17192593348eSBarry Smith 1720b6490206SBarry Smith /* read in nonzero values */ 1721b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr); 17220752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 172335aab85fSBarry Smith for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 1724b6490206SBarry Smith 1725b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1726b6490206SBarry Smith nzcount = 0; jcount = 0; 1727b6490206SBarry Smith for (i=0; i<mbs; i++) { 1728b6490206SBarry Smith nzcountb = nzcount; 172935aab85fSBarry Smith nmask = 0; 1730b6490206SBarry Smith for (j=0; j<bs; j++) { 1731b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1732b6490206SBarry Smith for (k=0; k<kmax; k++) { 173335aab85fSBarry Smith tmp = jj[nzcount++]/bs; 173435aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1735b6490206SBarry Smith } 1736b6490206SBarry Smith } 1737de6a44a3SBarry Smith /* sort the masked values */ 1738433994e6SBarry Smith ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 1739de6a44a3SBarry Smith 1740b6490206SBarry Smith /* set "j" values into matrix */ 1741b6490206SBarry Smith maskcount = 1; 174235aab85fSBarry Smith for (j=0; j<nmask; j++) { 174335aab85fSBarry Smith a->j[jcount++] = masked[j]; 1744de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1745b6490206SBarry Smith } 1746b6490206SBarry Smith /* set "a" values into matrix */ 1747de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1748b6490206SBarry Smith for (j=0; j<bs; j++) { 1749b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1750b6490206SBarry Smith for (k=0; k<kmax; k++) { 1751de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1752de6a44a3SBarry Smith block = mask[tmp] - 1; 1753de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1754de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1755375fe846SBarry Smith a->a[idx] = (MatScalar)aa[nzcountb++]; 1756b6490206SBarry Smith } 1757b6490206SBarry Smith } 175835aab85fSBarry Smith /* zero out the mask elements we set */ 175935aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1760b6490206SBarry Smith } 176129bbc08cSBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 1762b6490206SBarry Smith 1763606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 1764606d414cSSatish Balay ierr = PetscFree(browlengths);CHKERRQ(ierr); 1765606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 1766606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 1767606d414cSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 1768b6490206SBarry Smith 1769b6490206SBarry Smith B->assembled = PETSC_TRUE; 1770de6a44a3SBarry Smith 17719c01be13SBarry Smith ierr = MatView_Private(B);CHKERRQ(ierr); 17723a40ed3dSBarry Smith PetscFunctionReturn(0); 17732593348eSBarry Smith } 1774273d9f13SBarry Smith EXTERN_C_END 17752593348eSBarry Smith 1776273d9f13SBarry Smith #undef __FUNC__ 1777b0a32e0cSBarry Smith #define __FUNC__ "MatCreateSeqBAIJ" 1778273d9f13SBarry Smith /*@C 1779273d9f13SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 1780273d9f13SBarry Smith compressed row) format. For good matrix assembly performance the 1781273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1782273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1783273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 17842593348eSBarry Smith 1785273d9f13SBarry Smith Collective on MPI_Comm 1786273d9f13SBarry Smith 1787273d9f13SBarry Smith Input Parameters: 1788273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 1789273d9f13SBarry Smith . bs - size of block 1790273d9f13SBarry Smith . m - number of rows 1791273d9f13SBarry Smith . n - number of columns 179235d8aa7fSBarry Smith . nz - number of nonzero blocks per block row (same for all rows) 179335d8aa7fSBarry Smith - nnz - array containing the number of nonzero blocks in the various block rows 1794273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1795273d9f13SBarry Smith 1796273d9f13SBarry Smith Output Parameter: 1797273d9f13SBarry Smith . A - the matrix 1798273d9f13SBarry Smith 1799273d9f13SBarry Smith Options Database Keys: 1800273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1801273d9f13SBarry Smith block calculations (much slower) 1802273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1803273d9f13SBarry Smith 1804273d9f13SBarry Smith Level: intermediate 1805273d9f13SBarry Smith 1806273d9f13SBarry Smith Notes: 180735d8aa7fSBarry Smith A nonzero block is any block that as 1 or more nonzeros in it 180835d8aa7fSBarry Smith 1809273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1810273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1811273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1812273d9f13SBarry Smith 1813273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1814273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1815273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1816273d9f13SBarry Smith matrices. 1817273d9f13SBarry Smith 1818273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1819273d9f13SBarry Smith @*/ 1820273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A) 1821273d9f13SBarry Smith { 1822273d9f13SBarry Smith int ierr; 1823273d9f13SBarry Smith 1824273d9f13SBarry Smith PetscFunctionBegin; 1825273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 1826273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr); 1827273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr); 1828273d9f13SBarry Smith PetscFunctionReturn(0); 1829273d9f13SBarry Smith } 1830273d9f13SBarry Smith 1831273d9f13SBarry Smith #undef __FUNC__ 1832b0a32e0cSBarry Smith #define __FUNC__ "MatSeqBAIJSetPreallocation" 1833273d9f13SBarry Smith /*@C 1834273d9f13SBarry Smith MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros 1835273d9f13SBarry Smith per row in the matrix. For good matrix assembly performance the 1836273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1837273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1838273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 1839273d9f13SBarry Smith 1840273d9f13SBarry Smith Collective on MPI_Comm 1841273d9f13SBarry Smith 1842273d9f13SBarry Smith Input Parameters: 1843273d9f13SBarry Smith + A - the matrix 1844273d9f13SBarry Smith . bs - size of block 1845273d9f13SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1846273d9f13SBarry Smith - nnz - array containing the number of block nonzeros in the various block rows 1847273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1848273d9f13SBarry Smith 1849273d9f13SBarry Smith Options Database Keys: 1850273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1851273d9f13SBarry Smith block calculations (much slower) 1852273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1853273d9f13SBarry Smith 1854273d9f13SBarry Smith Level: intermediate 1855273d9f13SBarry Smith 1856273d9f13SBarry Smith Notes: 1857273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1858273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1859273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1860273d9f13SBarry Smith 1861273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1862273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1863273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1864273d9f13SBarry Smith matrices. 1865273d9f13SBarry Smith 1866273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1867273d9f13SBarry Smith @*/ 1868273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz) 1869273d9f13SBarry Smith { 1870273d9f13SBarry Smith Mat_SeqBAIJ *b; 1871273d9f13SBarry Smith int i,len,ierr,mbs,nbs,bs2,newbs = bs; 1872273d9f13SBarry Smith PetscTruth flg; 1873273d9f13SBarry Smith 1874273d9f13SBarry Smith PetscFunctionBegin; 1875273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr); 1876273d9f13SBarry Smith if (!flg) PetscFunctionReturn(0); 1877273d9f13SBarry Smith 1878273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1879b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr); 1880273d9f13SBarry Smith if (nnz && newbs != bs) { 1881273d9f13SBarry Smith SETERRQ(1,"Cannot change blocksize from command line if setting nnz"); 1882273d9f13SBarry Smith } 1883273d9f13SBarry Smith bs = newbs; 1884273d9f13SBarry Smith 1885273d9f13SBarry Smith mbs = B->m/bs; 1886273d9f13SBarry Smith nbs = B->n/bs; 1887273d9f13SBarry Smith bs2 = bs*bs; 1888273d9f13SBarry Smith 1889273d9f13SBarry Smith if (mbs*bs!=B->m || nbs*bs!=B->n) { 189035d8aa7fSBarry Smith SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs); 1891273d9f13SBarry Smith } 1892273d9f13SBarry Smith 1893*435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1894*435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 1895273d9f13SBarry Smith if (nnz) { 1896273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1897273d9f13SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 1898273d9f13SBarry Smith } 1899273d9f13SBarry Smith } 1900273d9f13SBarry Smith 1901273d9f13SBarry Smith b = (Mat_SeqBAIJ*)B->data; 1902b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr); 1903273d9f13SBarry Smith if (!flg) { 1904273d9f13SBarry Smith switch (bs) { 1905273d9f13SBarry Smith case 1: 1906273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1907273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1908273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_1; 1909273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1910273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 1911273d9f13SBarry Smith break; 1912273d9f13SBarry Smith case 2: 1913273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1914273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1915273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_2; 1916273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1917273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 1918273d9f13SBarry Smith break; 1919273d9f13SBarry Smith case 3: 1920273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1921273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1922273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_3; 1923273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1924273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 1925273d9f13SBarry Smith break; 1926273d9f13SBarry Smith case 4: 1927273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1928273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1929273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4; 1930273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1931273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 1932273d9f13SBarry Smith break; 1933273d9f13SBarry Smith case 5: 1934273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1935273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1936273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5; 1937273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1938273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 1939273d9f13SBarry Smith break; 1940273d9f13SBarry Smith case 6: 1941273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6; 1942273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_6; 1943273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6; 1944273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_6; 1945273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_6; 1946273d9f13SBarry Smith break; 1947273d9f13SBarry Smith case 7: 1948273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1949273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1950273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7; 1951273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 1952273d9f13SBarry Smith break; 1953273d9f13SBarry Smith default: 1954273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_N; 1955273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_N; 1956273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_N; 1957273d9f13SBarry Smith break; 1958273d9f13SBarry Smith } 1959273d9f13SBarry Smith } 1960273d9f13SBarry Smith b->bs = bs; 1961273d9f13SBarry Smith b->mbs = mbs; 1962273d9f13SBarry Smith b->nbs = nbs; 1963b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 1964273d9f13SBarry Smith if (!nnz) { 1965*435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1966273d9f13SBarry Smith else if (nz <= 0) nz = 1; 1967273d9f13SBarry Smith for (i=0; i<mbs; i++) b->imax[i] = nz; 1968273d9f13SBarry Smith nz = nz*mbs; 1969273d9f13SBarry Smith } else { 1970273d9f13SBarry Smith nz = 0; 1971273d9f13SBarry Smith for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 1972273d9f13SBarry Smith } 1973273d9f13SBarry Smith 1974273d9f13SBarry Smith /* allocate the matrix space */ 1975273d9f13SBarry Smith len = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int); 1976b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 1977273d9f13SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1978273d9f13SBarry Smith b->j = (int*)(b->a + nz*bs2); 1979273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 1980273d9f13SBarry Smith b->i = b->j + nz; 1981273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 1982273d9f13SBarry Smith 1983273d9f13SBarry Smith b->i[0] = 0; 1984273d9f13SBarry Smith for (i=1; i<mbs+1; i++) { 1985273d9f13SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 1986273d9f13SBarry Smith } 1987273d9f13SBarry Smith 1988273d9f13SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 198916d6aa21SSatish Balay ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 1990b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1991273d9f13SBarry Smith for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 1992273d9f13SBarry Smith 1993273d9f13SBarry Smith b->bs = bs; 1994273d9f13SBarry Smith b->bs2 = bs2; 1995273d9f13SBarry Smith b->mbs = mbs; 1996273d9f13SBarry Smith b->nz = 0; 1997273d9f13SBarry Smith b->maxnz = nz*bs2; 1998273d9f13SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1999273d9f13SBarry Smith PetscFunctionReturn(0); 2000273d9f13SBarry Smith } 20012593348eSBarry Smith 2002