1*f2a5309cSSatish Balay /*$Id: baij.c,v 1.218 2001/01/20 03:34:53 bsmith 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 */ 903b2fbd54SBarry Smith int nz = a->i[n] + 1; 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" 1033b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 1043b2fbd54SBarry Smith PetscTruth *done) 1053b2fbd54SBarry Smith { 1063b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 107606d414cSSatish Balay int i,n = a->mbs,ierr; 1083b2fbd54SBarry Smith 1093a40ed3dSBarry Smith PetscFunctionBegin; 1103a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1113b2fbd54SBarry Smith if (symmetric) { 112606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 113606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 114af5da2bfSBarry Smith } else if (oshift == 1) { 1153b2fbd54SBarry Smith int nz = a->i[n]; 1163b2fbd54SBarry Smith for (i=0; i<nz; i++) a->j[i]--; 1173b2fbd54SBarry Smith for (i=0; i<n+1; i++) a->i[i]--; 1183b2fbd54SBarry Smith } 1193a40ed3dSBarry Smith PetscFunctionReturn(0); 1203b2fbd54SBarry Smith } 1213b2fbd54SBarry Smith 1222d61bbb3SSatish Balay #undef __FUNC__ 123b0a32e0cSBarry Smith #define __FUNC__ "MatGetBlockSize_SeqBAIJ" 1242d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs) 1252d61bbb3SSatish Balay { 1262d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data; 1272d61bbb3SSatish Balay 1282d61bbb3SSatish Balay PetscFunctionBegin; 1292d61bbb3SSatish Balay *bs = baij->bs; 1302d61bbb3SSatish Balay PetscFunctionReturn(0); 1312d61bbb3SSatish Balay } 1322d61bbb3SSatish Balay 1332d61bbb3SSatish Balay 1342d61bbb3SSatish Balay #undef __FUNC__ 135b0a32e0cSBarry Smith #define __FUNC__ "MatDestroy_SeqBAIJ" 136e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A) 1372d61bbb3SSatish Balay { 1382d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 139e51c0b9cSSatish Balay int ierr; 1402d61bbb3SSatish Balay 141433994e6SBarry Smith PetscFunctionBegin; 142aa482453SBarry Smith #if defined(PETSC_USE_LOG) 143b0a32e0cSBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 1442d61bbb3SSatish Balay #endif 145606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 146606d414cSSatish Balay if (!a->singlemalloc) { 147606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 148606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 149606d414cSSatish Balay } 150c38d4ed2SBarry Smith if (a->row) { 151c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 152c38d4ed2SBarry Smith } 153c38d4ed2SBarry Smith if (a->col) { 154c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 155c38d4ed2SBarry Smith } 156606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 157606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 158606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 159606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 160606d414cSSatish Balay if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);} 161e51c0b9cSSatish Balay if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 162606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 163563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 164563b5814SBarry Smith if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);} 165563b5814SBarry Smith #endif 166606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 1672d61bbb3SSatish Balay PetscFunctionReturn(0); 1682d61bbb3SSatish Balay } 1692d61bbb3SSatish Balay 1702d61bbb3SSatish Balay #undef __FUNC__ 171b0a32e0cSBarry Smith #define __FUNC__ "MatSetOption_SeqBAIJ" 1722d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1732d61bbb3SSatish Balay { 1742d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1752d61bbb3SSatish Balay 1762d61bbb3SSatish Balay PetscFunctionBegin; 177c4992f7dSBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = PETSC_TRUE; 178c4992f7dSBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = PETSC_FALSE; 179c4992f7dSBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = PETSC_TRUE; 180c4992f7dSBarry Smith else if (op == MAT_COLUMNS_UNSORTED) a->sorted = PETSC_FALSE; 181c4992f7dSBarry Smith else if (op == MAT_KEEP_ZEROED_ROWS) a->keepzeroedrows = PETSC_TRUE; 1822d61bbb3SSatish Balay else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 1834787f768SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERR) a->nonew = -1; 1844787f768SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR) a->nonew = -2; 1852d61bbb3SSatish Balay else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 1862d61bbb3SSatish Balay else if (op == MAT_ROWS_SORTED || 1872d61bbb3SSatish Balay op == MAT_ROWS_UNSORTED || 1882d61bbb3SSatish Balay op == MAT_SYMMETRIC || 1892d61bbb3SSatish Balay op == MAT_STRUCTURALLY_SYMMETRIC || 1902d61bbb3SSatish Balay op == MAT_YES_NEW_DIAGONALS || 191b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES || 192b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) { 193b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 1942d61bbb3SSatish Balay } else if (op == MAT_NO_NEW_DIAGONALS) { 19529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 1962d61bbb3SSatish Balay } else { 19729bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"unknown option"); 1982d61bbb3SSatish Balay } 1992d61bbb3SSatish Balay PetscFunctionReturn(0); 2002d61bbb3SSatish Balay } 2012d61bbb3SSatish Balay 2022d61bbb3SSatish Balay #undef __FUNC__ 203b0a32e0cSBarry Smith #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ" 2042d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 2052d61bbb3SSatish Balay { 2062d61bbb3SSatish Balay PetscFunctionBegin; 2074c49b128SBarry Smith if (m) *m = 0; 208273d9f13SBarry Smith if (n) *n = A->m; 2092d61bbb3SSatish Balay PetscFunctionReturn(0); 2102d61bbb3SSatish Balay } 2112d61bbb3SSatish Balay 2122d61bbb3SSatish Balay #undef __FUNC__ 213b0a32e0cSBarry Smith #define __FUNC__ "MatGetRow_SeqBAIJ" 2142d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2152d61bbb3SSatish Balay { 2162d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 21782502324SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr; 2183f1db9ecSBarry Smith MatScalar *aa,*aa_i; 2193f1db9ecSBarry Smith Scalar *v_i; 2202d61bbb3SSatish Balay 2212d61bbb3SSatish Balay PetscFunctionBegin; 2222d61bbb3SSatish Balay bs = a->bs; 2232d61bbb3SSatish Balay ai = a->i; 2242d61bbb3SSatish Balay aj = a->j; 2252d61bbb3SSatish Balay aa = a->a; 2262d61bbb3SSatish Balay bs2 = a->bs2; 2272d61bbb3SSatish Balay 228273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range"); 2292d61bbb3SSatish Balay 2302d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2312d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2322d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2332d61bbb3SSatish Balay *nz = bs*M; 2342d61bbb3SSatish Balay 2352d61bbb3SSatish Balay if (v) { 2362d61bbb3SSatish Balay *v = 0; 2372d61bbb3SSatish Balay if (*nz) { 238b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr); 2392d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2402d61bbb3SSatish Balay v_i = *v + i*bs; 2412d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2422d61bbb3SSatish Balay for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];} 2432d61bbb3SSatish Balay } 2442d61bbb3SSatish Balay } 2452d61bbb3SSatish Balay } 2462d61bbb3SSatish Balay 2472d61bbb3SSatish Balay if (idx) { 2482d61bbb3SSatish Balay *idx = 0; 2492d61bbb3SSatish Balay if (*nz) { 250b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr); 2512d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2522d61bbb3SSatish Balay idx_i = *idx + i*bs; 2532d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2542d61bbb3SSatish Balay for (j=0; j<bs; j++) {idx_i[j] = itmp++;} 2552d61bbb3SSatish Balay } 2562d61bbb3SSatish Balay } 2572d61bbb3SSatish Balay } 2582d61bbb3SSatish Balay PetscFunctionReturn(0); 2592d61bbb3SSatish Balay } 2602d61bbb3SSatish Balay 2612d61bbb3SSatish Balay #undef __FUNC__ 262b0a32e0cSBarry Smith #define __FUNC__ "MatRestoreRow_SeqBAIJ" 2632d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2642d61bbb3SSatish Balay { 265606d414cSSatish Balay int ierr; 266606d414cSSatish Balay 2672d61bbb3SSatish Balay PetscFunctionBegin; 268606d414cSSatish Balay if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 269606d414cSSatish Balay if (v) {if (*v) {ierr = PetscFree(*v);CHKERRQ(ierr);}} 2702d61bbb3SSatish Balay PetscFunctionReturn(0); 2712d61bbb3SSatish Balay } 2722d61bbb3SSatish Balay 2732d61bbb3SSatish Balay #undef __FUNC__ 274b0a32e0cSBarry Smith #define __FUNC__ "MatTranspose_SeqBAIJ" 2752d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2762d61bbb3SSatish Balay { 2772d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2782d61bbb3SSatish Balay Mat C; 2792d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 280273d9f13SBarry Smith int *rows,*cols,bs2=a->bs2; 281375fe846SBarry Smith Scalar *array; 2822d61bbb3SSatish Balay 2832d61bbb3SSatish Balay PetscFunctionBegin; 28429bbc08cSBarry Smith if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place"); 285b0a32e0cSBarry Smith ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr); 286549d3d68SSatish Balay ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr); 2872d61bbb3SSatish Balay 288375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 289b0a32e0cSBarry Smith ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr); 290375fe846SBarry Smith for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i]; 291375fe846SBarry Smith #else 2923eda8832SBarry Smith array = a->a; 293375fe846SBarry Smith #endif 294375fe846SBarry Smith 2952d61bbb3SSatish Balay for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1; 296273d9f13SBarry Smith ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr); 297606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 298b0a32e0cSBarry Smith ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr); 2992d61bbb3SSatish Balay cols = rows + bs; 3002d61bbb3SSatish Balay for (i=0; i<mbs; i++) { 3012d61bbb3SSatish Balay cols[0] = i*bs; 3022d61bbb3SSatish Balay for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1; 3032d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 3042d61bbb3SSatish Balay for (j=0; j<len; j++) { 3052d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 3062d61bbb3SSatish Balay for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1; 3072d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr); 3082d61bbb3SSatish Balay array += bs2; 3092d61bbb3SSatish Balay } 3102d61bbb3SSatish Balay } 311606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 312375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 313375fe846SBarry Smith ierr = PetscFree(array); 314375fe846SBarry Smith #endif 3152d61bbb3SSatish Balay 3162d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3172d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3182d61bbb3SSatish Balay 319c4992f7dSBarry Smith if (B) { 3202d61bbb3SSatish Balay *B = C; 3212d61bbb3SSatish Balay } else { 322273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 3232d61bbb3SSatish Balay } 3242d61bbb3SSatish Balay PetscFunctionReturn(0); 3252d61bbb3SSatish Balay } 3262d61bbb3SSatish Balay 3275615d1e5SSatish Balay #undef __FUNC__ 328b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary" 329b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer) 3302593348eSBarry Smith { 331b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 3329df24120SSatish Balay int i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 333b6490206SBarry Smith Scalar *aa; 334ce6f0cecSBarry Smith FILE *file; 3352593348eSBarry Smith 3363a40ed3dSBarry Smith PetscFunctionBegin; 337b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 338b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 3392593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3403b2fbd54SBarry Smith 341273d9f13SBarry Smith col_lens[1] = A->m; 342273d9f13SBarry Smith col_lens[2] = A->n; 3437e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3442593348eSBarry Smith 3452593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 346b6490206SBarry Smith count = 0; 347b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 348b6490206SBarry Smith for (j=0; j<bs; j++) { 349b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 350b6490206SBarry Smith } 3512593348eSBarry Smith } 352273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 353606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 3542593348eSBarry Smith 3552593348eSBarry Smith /* store column indices (zero start index) */ 356b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr); 357b6490206SBarry Smith count = 0; 358b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 359b6490206SBarry Smith for (j=0; j<bs; j++) { 360b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 361b6490206SBarry Smith for (l=0; l<bs; l++) { 362b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3632593348eSBarry Smith } 3642593348eSBarry Smith } 365b6490206SBarry Smith } 366b6490206SBarry Smith } 3670752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr); 368606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 3692593348eSBarry Smith 3702593348eSBarry Smith /* store nonzero values */ 371b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr); 372b6490206SBarry Smith count = 0; 373b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 374b6490206SBarry Smith for (j=0; j<bs; j++) { 375b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 376b6490206SBarry Smith for (l=0; l<bs; l++) { 3777e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 378b6490206SBarry Smith } 379b6490206SBarry Smith } 380b6490206SBarry Smith } 381b6490206SBarry Smith } 3820752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 383606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 384ce6f0cecSBarry Smith 385b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 386ce6f0cecSBarry Smith if (file) { 387ce6f0cecSBarry Smith fprintf(file,"-matload_block_size %d\n",a->bs); 388ce6f0cecSBarry Smith } 3893a40ed3dSBarry Smith PetscFunctionReturn(0); 3902593348eSBarry Smith } 3912593348eSBarry Smith 3925615d1e5SSatish Balay #undef __FUNC__ 393b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII" 394b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer) 3952593348eSBarry Smith { 396b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 397fb9695e5SSatish Balay int ierr,i,j,bs = a->bs,k,l,bs2=a->bs2; 398f3ef73ceSBarry Smith PetscViewerFormat format; 3992593348eSBarry Smith 4003a40ed3dSBarry Smith PetscFunctionBegin; 401b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 402fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) { 403b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %d\n",bs);CHKERRQ(ierr); 404fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 40529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Matlab format not supported"); 406fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 407b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 40844cd7ae7SLois Curfman McInnes for (i=0; i<a->mbs; i++) { 40944cd7ae7SLois Curfman McInnes for (j=0; j<bs; j++) { 410b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 41144cd7ae7SLois Curfman McInnes for (k=a->i[i]; k<a->i[i+1]; k++) { 41244cd7ae7SLois Curfman McInnes for (l=0; l<bs; l++) { 413aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4140e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 415b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l, 4160e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4170e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 418b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l, 4190e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4200e6d2581SBarry Smith } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 421b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4220ef38995SBarry Smith } 42344cd7ae7SLois Curfman McInnes #else 4240ef38995SBarry Smith if (a->a[bs2*k + l*bs + j] != 0.0) { 425b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 4260ef38995SBarry Smith } 42744cd7ae7SLois Curfman McInnes #endif 42844cd7ae7SLois Curfman McInnes } 42944cd7ae7SLois Curfman McInnes } 430b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 43144cd7ae7SLois Curfman McInnes } 43244cd7ae7SLois Curfman McInnes } 433b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4340ef38995SBarry Smith } else { 435b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 436b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 437b6490206SBarry Smith for (j=0; j<bs; j++) { 438b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 439b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 440b6490206SBarry Smith for (l=0; l<bs; l++) { 441aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4420e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 443b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l, 4440e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4450e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 446b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l, 4470e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4480ef38995SBarry Smith } else { 449b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 45088685aaeSLois Curfman McInnes } 45188685aaeSLois Curfman McInnes #else 452b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 45388685aaeSLois Curfman McInnes #endif 4542593348eSBarry Smith } 4552593348eSBarry Smith } 456b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 4572593348eSBarry Smith } 4582593348eSBarry Smith } 459b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 460b6490206SBarry Smith } 461b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4623a40ed3dSBarry Smith PetscFunctionReturn(0); 4632593348eSBarry Smith } 4642593348eSBarry Smith 4655615d1e5SSatish Balay #undef __FUNC__ 466b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom" 467b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 4683270192aSSatish Balay { 46977ed5343SBarry Smith Mat A = (Mat) Aa; 4703270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ*)A->data; 471b65db4caSBarry Smith int row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2; 4720e6d2581SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 4733f1db9ecSBarry Smith MatScalar *aa; 474b0a32e0cSBarry Smith PetscViewer viewer; 4753270192aSSatish Balay 4763a40ed3dSBarry Smith PetscFunctionBegin; 4773270192aSSatish Balay 478b65db4caSBarry Smith /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/ 47977ed5343SBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 48077ed5343SBarry Smith 481b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 48277ed5343SBarry Smith 4833270192aSSatish Balay /* loop over matrix elements drawing boxes */ 484b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 4853270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 4863270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 487273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 4883270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4893270192aSSatish Balay aa = a->a + j*bs2; 4903270192aSSatish Balay for (k=0; k<bs; k++) { 4913270192aSSatish Balay for (l=0; l<bs; l++) { 4920e6d2581SBarry Smith if (PetscRealPart(*aa++) >= 0.) continue; 493b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 4943270192aSSatish Balay } 4953270192aSSatish Balay } 4963270192aSSatish Balay } 4973270192aSSatish Balay } 498b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 4993270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5003270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 501273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5023270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5033270192aSSatish Balay aa = a->a + j*bs2; 5043270192aSSatish Balay for (k=0; k<bs; k++) { 5053270192aSSatish Balay for (l=0; l<bs; l++) { 5060e6d2581SBarry Smith if (PetscRealPart(*aa++) != 0.) continue; 507b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5083270192aSSatish Balay } 5093270192aSSatish Balay } 5103270192aSSatish Balay } 5113270192aSSatish Balay } 5123270192aSSatish Balay 513b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 5143270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5153270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 516273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5173270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5183270192aSSatish Balay aa = a->a + j*bs2; 5193270192aSSatish Balay for (k=0; k<bs; k++) { 5203270192aSSatish Balay for (l=0; l<bs; l++) { 5210e6d2581SBarry Smith if (PetscRealPart(*aa++) <= 0.) continue; 522b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5233270192aSSatish Balay } 5243270192aSSatish Balay } 5253270192aSSatish Balay } 5263270192aSSatish Balay } 52777ed5343SBarry Smith PetscFunctionReturn(0); 52877ed5343SBarry Smith } 5293270192aSSatish Balay 53077ed5343SBarry Smith #undef __FUNC__ 531b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw" 532b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer) 53377ed5343SBarry Smith { 5347dce120fSSatish Balay int ierr; 5350e6d2581SBarry Smith PetscReal xl,yl,xr,yr,w,h; 536b0a32e0cSBarry Smith PetscDraw draw; 53777ed5343SBarry Smith PetscTruth isnull; 5383270192aSSatish Balay 53977ed5343SBarry Smith PetscFunctionBegin; 54077ed5343SBarry Smith 541b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 542b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 54377ed5343SBarry Smith 54477ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 545273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 54677ed5343SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 547b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 548b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 54977ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5503a40ed3dSBarry Smith PetscFunctionReturn(0); 5513270192aSSatish Balay } 5523270192aSSatish Balay 5535615d1e5SSatish Balay #undef __FUNC__ 554b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ" 555b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer) 5562593348eSBarry Smith { 55719bcc07fSBarry Smith int ierr; 5586831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 5592593348eSBarry Smith 5603a40ed3dSBarry Smith PetscFunctionBegin; 561b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 562b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 563fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 564fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 5650f5bd95cSBarry Smith if (issocket) { 56629bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported"); 5670f5bd95cSBarry Smith } else if (isascii){ 5683a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5690f5bd95cSBarry Smith } else if (isbinary) { 5703a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 5710f5bd95cSBarry Smith } else if (isdraw) { 5723a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 5735cd90555SBarry Smith } else { 57429bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name); 5752593348eSBarry Smith } 5763a40ed3dSBarry Smith PetscFunctionReturn(0); 5772593348eSBarry Smith } 578b6490206SBarry Smith 579cd0e1443SSatish Balay 5805615d1e5SSatish Balay #undef __FUNC__ 581b0a32e0cSBarry Smith #define __FUNC__ "MatGetValues_SeqBAIJ" 5822d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 583cd0e1443SSatish Balay { 584cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 5852d61bbb3SSatish Balay int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 5862d61bbb3SSatish Balay int *ai = a->i,*ailen = a->ilen; 5872d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 5883f1db9ecSBarry Smith MatScalar *ap,*aa = a->a,zero = 0.0; 589cd0e1443SSatish Balay 5903a40ed3dSBarry Smith PetscFunctionBegin; 5912d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over rows */ 592cd0e1443SSatish Balay row = im[k]; brow = row/bs; 59329bbc08cSBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row"); 594273d9f13SBarry Smith if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 5952d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 5962c3acbe9SBarry Smith nrow = ailen[brow]; 5972d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over columns */ 59829bbc08cSBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column"); 599273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 6002d61bbb3SSatish Balay col = in[l] ; 6012d61bbb3SSatish Balay bcol = col/bs; 6022d61bbb3SSatish Balay cidx = col%bs; 6032d61bbb3SSatish Balay ridx = row%bs; 6042d61bbb3SSatish Balay high = nrow; 6052d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6062d61bbb3SSatish Balay while (high-low > 5) { 607cd0e1443SSatish Balay t = (low+high)/2; 608cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 609cd0e1443SSatish Balay else low = t; 610cd0e1443SSatish Balay } 611cd0e1443SSatish Balay for (i=low; i<high; i++) { 612cd0e1443SSatish Balay if (rp[i] > bcol) break; 613cd0e1443SSatish Balay if (rp[i] == bcol) { 6142d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6152d61bbb3SSatish Balay goto finished; 616cd0e1443SSatish Balay } 617cd0e1443SSatish Balay } 6182d61bbb3SSatish Balay *v++ = zero; 6192d61bbb3SSatish Balay finished:; 620cd0e1443SSatish Balay } 621cd0e1443SSatish Balay } 6223a40ed3dSBarry Smith PetscFunctionReturn(0); 623cd0e1443SSatish Balay } 624cd0e1443SSatish Balay 62595d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 62695d5f7c2SBarry Smith #undef __FUNC__ 627b0a32e0cSBarry Smith #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 62895d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv) 62995d5f7c2SBarry Smith { 630563b5814SBarry Smith Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data; 631563b5814SBarry Smith int ierr,i,N = m*n*b->bs2; 632563b5814SBarry Smith MatScalar *vsingle; 63395d5f7c2SBarry Smith 63495d5f7c2SBarry Smith PetscFunctionBegin; 635563b5814SBarry Smith if (N > b->setvalueslen) { 636563b5814SBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 637b0a32e0cSBarry Smith ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 638563b5814SBarry Smith b->setvalueslen = N; 639563b5814SBarry Smith } 640563b5814SBarry Smith vsingle = b->setvaluescopy; 64195d5f7c2SBarry Smith for (i=0; i<N; i++) { 64295d5f7c2SBarry Smith vsingle[i] = v[i]; 64395d5f7c2SBarry Smith } 64495d5f7c2SBarry Smith ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 64595d5f7c2SBarry Smith PetscFunctionReturn(0); 64695d5f7c2SBarry Smith } 64795d5f7c2SBarry Smith #endif 64895d5f7c2SBarry Smith 6492d61bbb3SSatish Balay 6505615d1e5SSatish Balay #undef __FUNC__ 651b0a32e0cSBarry Smith #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ" 65295d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is) 65392c4ed94SBarry Smith { 65492c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 6558a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 656273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 657549d3d68SSatish Balay int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr; 658273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 65995d5f7c2SBarry Smith MatScalar *value = v,*ap,*aa = a->a,*bap; 66092c4ed94SBarry Smith 6613a40ed3dSBarry Smith PetscFunctionBegin; 6620e324ae4SSatish Balay if (roworiented) { 6630e324ae4SSatish Balay stepval = (n-1)*bs; 6640e324ae4SSatish Balay } else { 6650e324ae4SSatish Balay stepval = (m-1)*bs; 6660e324ae4SSatish Balay } 66792c4ed94SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 66892c4ed94SBarry Smith row = im[k]; 6695ef9f2a5SBarry Smith if (row < 0) continue; 670aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 67129bbc08cSBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 67292c4ed94SBarry Smith #endif 67392c4ed94SBarry Smith rp = aj + ai[row]; 67492c4ed94SBarry Smith ap = aa + bs2*ai[row]; 67592c4ed94SBarry Smith rmax = imax[row]; 67692c4ed94SBarry Smith nrow = ailen[row]; 67792c4ed94SBarry Smith low = 0; 67892c4ed94SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 6795ef9f2a5SBarry Smith if (in[l] < 0) continue; 680aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 68129bbc08cSBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 68292c4ed94SBarry Smith #endif 68392c4ed94SBarry Smith col = in[l]; 68492c4ed94SBarry Smith if (roworiented) { 6850e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 6860e324ae4SSatish Balay } else { 6870e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 68892c4ed94SBarry Smith } 68992c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 69092c4ed94SBarry Smith while (high-low > 7) { 69192c4ed94SBarry Smith t = (low+high)/2; 69292c4ed94SBarry Smith if (rp[t] > col) high = t; 69392c4ed94SBarry Smith else low = t; 69492c4ed94SBarry Smith } 69592c4ed94SBarry Smith for (i=low; i<high; i++) { 69692c4ed94SBarry Smith if (rp[i] > col) break; 69792c4ed94SBarry Smith if (rp[i] == col) { 6988a84c255SSatish Balay bap = ap + bs2*i; 6990e324ae4SSatish Balay if (roworiented) { 7008a84c255SSatish Balay if (is == ADD_VALUES) { 701dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 702dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7038a84c255SSatish Balay bap[jj] += *value++; 704dd9472c6SBarry Smith } 705dd9472c6SBarry Smith } 7060e324ae4SSatish Balay } else { 707dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 708dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7090e324ae4SSatish Balay bap[jj] = *value++; 7108a84c255SSatish Balay } 711dd9472c6SBarry Smith } 712dd9472c6SBarry Smith } 7130e324ae4SSatish Balay } else { 7140e324ae4SSatish Balay if (is == ADD_VALUES) { 715dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 716dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7170e324ae4SSatish Balay *bap++ += *value++; 718dd9472c6SBarry Smith } 719dd9472c6SBarry Smith } 7200e324ae4SSatish Balay } else { 721dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 722dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7230e324ae4SSatish Balay *bap++ = *value++; 7240e324ae4SSatish Balay } 7258a84c255SSatish Balay } 726dd9472c6SBarry Smith } 727dd9472c6SBarry Smith } 728f1241b54SBarry Smith goto noinsert2; 72992c4ed94SBarry Smith } 73092c4ed94SBarry Smith } 73189280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 73229bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 73392c4ed94SBarry Smith if (nrow >= rmax) { 73492c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 73592c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 7363f1db9ecSBarry Smith MatScalar *new_a; 73792c4ed94SBarry Smith 73829bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 73989280ab3SLois Curfman McInnes 74092c4ed94SBarry Smith /* malloc new storage space */ 7413f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 742b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 74392c4ed94SBarry Smith new_j = (int*)(new_a + bs2*new_nz); 74492c4ed94SBarry Smith new_i = new_j + new_nz; 74592c4ed94SBarry Smith 74692c4ed94SBarry Smith /* copy over old data into new slots */ 74792c4ed94SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 74892c4ed94SBarry Smith for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 749549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr); 75092c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 751549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr); 752549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 753549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 754549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 75592c4ed94SBarry Smith /* free up old matrix storage */ 756606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 757606d414cSSatish Balay if (!a->singlemalloc) { 758606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 759606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 760606d414cSSatish Balay } 76192c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 762c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 76392c4ed94SBarry Smith 76492c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 76592c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 766b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 76792c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 76892c4ed94SBarry Smith a->reallocs++; 76992c4ed94SBarry Smith a->nz++; 77092c4ed94SBarry Smith } 77192c4ed94SBarry Smith N = nrow++ - 1; 77292c4ed94SBarry Smith /* shift up all the later entries in this row */ 77392c4ed94SBarry Smith for (ii=N; ii>=i; ii--) { 77492c4ed94SBarry Smith rp[ii+1] = rp[ii]; 775549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 77692c4ed94SBarry Smith } 777549d3d68SSatish Balay if (N >= i) { 778549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 779549d3d68SSatish Balay } 78092c4ed94SBarry Smith rp[i] = col; 7818a84c255SSatish Balay bap = ap + bs2*i; 7820e324ae4SSatish Balay if (roworiented) { 783dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 784dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7850e324ae4SSatish Balay bap[jj] = *value++; 786dd9472c6SBarry Smith } 787dd9472c6SBarry Smith } 7880e324ae4SSatish Balay } else { 789dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 790dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7910e324ae4SSatish Balay *bap++ = *value++; 7920e324ae4SSatish Balay } 793dd9472c6SBarry Smith } 794dd9472c6SBarry Smith } 795f1241b54SBarry Smith noinsert2:; 79692c4ed94SBarry Smith low = i; 79792c4ed94SBarry Smith } 79892c4ed94SBarry Smith ailen[row] = nrow; 79992c4ed94SBarry Smith } 8003a40ed3dSBarry Smith PetscFunctionReturn(0); 80192c4ed94SBarry Smith } 80292c4ed94SBarry Smith 803f2501298SSatish Balay 8045615d1e5SSatish Balay #undef __FUNC__ 805b0a32e0cSBarry Smith #define __FUNC__ "MatAssemblyEnd_SeqBAIJ" 8068f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 807584200bdSSatish Balay { 808584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 809584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 810273d9f13SBarry Smith int m = A->m,*ip,N,*ailen = a->ilen; 811549d3d68SSatish Balay int mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr; 8123f1db9ecSBarry Smith MatScalar *aa = a->a,*ap; 813584200bdSSatish Balay 8143a40ed3dSBarry Smith PetscFunctionBegin; 8153a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 816584200bdSSatish Balay 81743ee02c3SBarry Smith if (m) rmax = ailen[0]; 818584200bdSSatish Balay for (i=1; i<mbs; i++) { 819584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 820584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 821d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 822584200bdSSatish Balay if (fshift) { 823a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 824584200bdSSatish Balay N = ailen[i]; 825584200bdSSatish Balay for (j=0; j<N; j++) { 826584200bdSSatish Balay ip[j-fshift] = ip[j]; 827549d3d68SSatish Balay ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr); 828584200bdSSatish Balay } 829584200bdSSatish Balay } 830584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 831584200bdSSatish Balay } 832584200bdSSatish Balay if (mbs) { 833584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 834584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 835584200bdSSatish Balay } 836584200bdSSatish Balay /* reset ilen and imax for each row */ 837584200bdSSatish Balay for (i=0; i<mbs; i++) { 838584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 839584200bdSSatish Balay } 840a7c10996SSatish Balay a->nz = ai[mbs]; 841584200bdSSatish Balay 842584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 843584200bdSSatish Balay if (fshift && a->diag) { 844606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 845b0a32e0cSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(int)); 846584200bdSSatish Balay a->diag = 0; 847584200bdSSatish Balay } 848b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 849273d9f13SBarry Smith m,A->n,a->bs,fshift*bs2,a->nz*bs2); 850b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 851584200bdSSatish Balay a->reallocs); 852b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 853e2f3b5e9SSatish Balay a->reallocs = 0; 8540e6d2581SBarry Smith A->info.nz_unneeded = (PetscReal)fshift*bs2; 8554e220ebcSLois Curfman McInnes 8563a40ed3dSBarry Smith PetscFunctionReturn(0); 857584200bdSSatish Balay } 858584200bdSSatish Balay 8595a838052SSatish Balay 860bea157c4SSatish Balay 861bea157c4SSatish Balay /* 862bea157c4SSatish Balay This function returns an array of flags which indicate the locations of contiguous 863bea157c4SSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 864bea157c4SSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 865bea157c4SSatish Balay Assume: sizes should be long enough to hold all the values. 866bea157c4SSatish Balay */ 8675615d1e5SSatish Balay #undef __FUNC__ 868b0a32e0cSBarry Smith #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Blocks" 869bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max) 870d9b7c43dSSatish Balay { 871bea157c4SSatish Balay int i,j,k,row; 872bea157c4SSatish Balay PetscTruth flg; 8733a40ed3dSBarry Smith 874433994e6SBarry Smith PetscFunctionBegin; 875bea157c4SSatish Balay for (i=0,j=0; i<n; j++) { 876bea157c4SSatish Balay row = idx[i]; 877bea157c4SSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 878bea157c4SSatish Balay sizes[j] = 1; 879bea157c4SSatish Balay i++; 880e4fda26cSSatish Balay } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */ 881bea157c4SSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 882bea157c4SSatish Balay i++; 883bea157c4SSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 884bea157c4SSatish Balay flg = PETSC_TRUE; 885bea157c4SSatish Balay for (k=1; k<bs; k++) { 886bea157c4SSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 887bea157c4SSatish Balay flg = PETSC_FALSE; 888bea157c4SSatish Balay break; 889d9b7c43dSSatish Balay } 890bea157c4SSatish Balay } 891bea157c4SSatish Balay if (flg == PETSC_TRUE) { /* No break in the bs */ 892bea157c4SSatish Balay sizes[j] = bs; 893bea157c4SSatish Balay i+= bs; 894bea157c4SSatish Balay } else { 895bea157c4SSatish Balay sizes[j] = 1; 896bea157c4SSatish Balay i++; 897bea157c4SSatish Balay } 898bea157c4SSatish Balay } 899bea157c4SSatish Balay } 900bea157c4SSatish Balay *bs_max = j; 9013a40ed3dSBarry Smith PetscFunctionReturn(0); 902d9b7c43dSSatish Balay } 903d9b7c43dSSatish Balay 9045615d1e5SSatish Balay #undef __FUNC__ 905b0a32e0cSBarry Smith #define __FUNC__ "MatZeroRows_SeqBAIJ" 9068f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag) 907d9b7c43dSSatish Balay { 908d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 909b6815fffSBarry Smith int ierr,i,j,k,count,is_n,*is_idx,*rows; 910bea157c4SSatish Balay int bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max; 9113f1db9ecSBarry Smith Scalar zero = 0.0; 9123f1db9ecSBarry Smith MatScalar *aa; 913d9b7c43dSSatish Balay 9143a40ed3dSBarry Smith PetscFunctionBegin; 915d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 916b9b97703SBarry Smith ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr); 917d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 918d9b7c43dSSatish Balay 919bea157c4SSatish Balay /* allocate memory for rows,sizes */ 920b0a32e0cSBarry Smith ierr = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr); 921bea157c4SSatish Balay sizes = rows + is_n; 922bea157c4SSatish Balay 923563b5814SBarry Smith /* copy IS values to rows, and sort them */ 924bea157c4SSatish Balay for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; } 925bea157c4SSatish Balay ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr); 926dffd3267SBarry Smith if (baij->keepzeroedrows) { 927dffd3267SBarry Smith for (i=0; i<is_n; i++) { sizes[i] = 1; } 928dffd3267SBarry Smith bs_max = is_n; 929dffd3267SBarry Smith } else { 930bea157c4SSatish Balay ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr); 931dffd3267SBarry Smith } 932b97a56abSSatish Balay ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr); 933bea157c4SSatish Balay 934bea157c4SSatish Balay for (i=0,j=0; i<bs_max; j+=sizes[i],i++) { 935bea157c4SSatish Balay row = rows[j]; 936273d9f13SBarry Smith if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row); 937bea157c4SSatish Balay count = (baij->i[row/bs +1] - baij->i[row/bs])*bs; 938bea157c4SSatish Balay aa = baij->a + baij->i[row/bs]*bs2 + (row%bs); 939dffd3267SBarry Smith if (sizes[i] == bs && !baij->keepzeroedrows) { 940bea157c4SSatish Balay if (diag) { 941bea157c4SSatish Balay if (baij->ilen[row/bs] > 0) { 942bea157c4SSatish Balay baij->ilen[row/bs] = 1; 943bea157c4SSatish Balay baij->j[baij->i[row/bs]] = row/bs; 944bea157c4SSatish Balay ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr); 945a07cd24cSSatish Balay } 946563b5814SBarry Smith /* Now insert all the diagonal values for this bs */ 947bea157c4SSatish Balay for (k=0; k<bs; k++) { 948bea157c4SSatish Balay ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr); 949bea157c4SSatish Balay } 950bea157c4SSatish Balay } else { /* (!diag) */ 951bea157c4SSatish Balay baij->ilen[row/bs] = 0; 952bea157c4SSatish Balay } /* end (!diag) */ 953bea157c4SSatish Balay } else { /* (sizes[i] != bs) */ 954aa482453SBarry Smith #if defined (PETSC_USE_DEBUG) 95529bbc08cSBarry Smith if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1"); 956bea157c4SSatish Balay #endif 957bea157c4SSatish Balay for (k=0; k<count; k++) { 958d9b7c43dSSatish Balay aa[0] = zero; 959d9b7c43dSSatish Balay aa += bs; 960d9b7c43dSSatish Balay } 961d9b7c43dSSatish Balay if (diag) { 962f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 963d9b7c43dSSatish Balay } 964d9b7c43dSSatish Balay } 965bea157c4SSatish Balay } 966bea157c4SSatish Balay 967606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 9689a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9693a40ed3dSBarry Smith PetscFunctionReturn(0); 970d9b7c43dSSatish Balay } 9711c351548SSatish Balay 9725615d1e5SSatish Balay #undef __FUNC__ 973b0a32e0cSBarry Smith #define __FUNC__ "MatSetValues_SeqBAIJ" 9742d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9752d61bbb3SSatish Balay { 9762d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 9772d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 978273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 9792d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 980549d3d68SSatish Balay int ridx,cidx,bs2=a->bs2,ierr; 981273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 9823f1db9ecSBarry Smith MatScalar *ap,value,*aa=a->a,*bap; 9832d61bbb3SSatish Balay 9842d61bbb3SSatish Balay PetscFunctionBegin; 9852d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 9862d61bbb3SSatish Balay row = im[k]; brow = row/bs; 9875ef9f2a5SBarry Smith if (row < 0) continue; 988aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 989273d9f13SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m); 9902d61bbb3SSatish Balay #endif 9912d61bbb3SSatish Balay rp = aj + ai[brow]; 9922d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 9932d61bbb3SSatish Balay rmax = imax[brow]; 9942d61bbb3SSatish Balay nrow = ailen[brow]; 9952d61bbb3SSatish Balay low = 0; 9962d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 9975ef9f2a5SBarry Smith if (in[l] < 0) continue; 998aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 999273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n); 10002d61bbb3SSatish Balay #endif 10012d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 10022d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 10032d61bbb3SSatish Balay if (roworiented) { 10045ef9f2a5SBarry Smith value = v[l + k*n]; 10052d61bbb3SSatish Balay } else { 10062d61bbb3SSatish Balay value = v[k + l*m]; 10072d61bbb3SSatish Balay } 10082d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 10092d61bbb3SSatish Balay while (high-low > 7) { 10102d61bbb3SSatish Balay t = (low+high)/2; 10112d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 10122d61bbb3SSatish Balay else low = t; 10132d61bbb3SSatish Balay } 10142d61bbb3SSatish Balay for (i=low; i<high; i++) { 10152d61bbb3SSatish Balay if (rp[i] > bcol) break; 10162d61bbb3SSatish Balay if (rp[i] == bcol) { 10172d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 10182d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 10192d61bbb3SSatish Balay else *bap = value; 10202d61bbb3SSatish Balay goto noinsert1; 10212d61bbb3SSatish Balay } 10222d61bbb3SSatish Balay } 10232d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 102429bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10252d61bbb3SSatish Balay if (nrow >= rmax) { 10262d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 10272d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 10283f1db9ecSBarry Smith MatScalar *new_a; 10292d61bbb3SSatish Balay 103029bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10312d61bbb3SSatish Balay 10322d61bbb3SSatish Balay /* Malloc new storage space */ 10333f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 1034b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 10352d61bbb3SSatish Balay new_j = (int*)(new_a + bs2*new_nz); 10362d61bbb3SSatish Balay new_i = new_j + new_nz; 10372d61bbb3SSatish Balay 10382d61bbb3SSatish Balay /* copy over old data into new slots */ 10392d61bbb3SSatish Balay for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];} 10402d61bbb3SSatish Balay for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 1041549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr); 10422d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 1043549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr); 1044549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1045549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 1046549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 10472d61bbb3SSatish Balay /* free up old matrix storage */ 1048606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 1049606d414cSSatish Balay if (!a->singlemalloc) { 1050606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 1051606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 1052606d414cSSatish Balay } 10532d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 1054c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 10552d61bbb3SSatish Balay 10562d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 10572d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 1058b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 10592d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 10602d61bbb3SSatish Balay a->reallocs++; 10612d61bbb3SSatish Balay a->nz++; 10622d61bbb3SSatish Balay } 10632d61bbb3SSatish Balay N = nrow++ - 1; 10642d61bbb3SSatish Balay /* shift up all the later entries in this row */ 10652d61bbb3SSatish Balay for (ii=N; ii>=i; ii--) { 10662d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 1067549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 10682d61bbb3SSatish Balay } 1069549d3d68SSatish Balay if (N>=i) { 1070549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 1071549d3d68SSatish Balay } 10722d61bbb3SSatish Balay rp[i] = bcol; 10732d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10742d61bbb3SSatish Balay noinsert1:; 10752d61bbb3SSatish Balay low = i; 10762d61bbb3SSatish Balay } 10772d61bbb3SSatish Balay ailen[brow] = nrow; 10782d61bbb3SSatish Balay } 10792d61bbb3SSatish Balay PetscFunctionReturn(0); 10802d61bbb3SSatish Balay } 10812d61bbb3SSatish Balay 1082b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,MatLUInfo*,Mat*); 1083b9b97703SBarry Smith EXTERN int MatLUFactor_SeqBAIJ(Mat,IS,IS,MatLUInfo*); 1084ca44d042SBarry Smith EXTERN int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 1085ca44d042SBarry Smith EXTERN int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*); 1086ca44d042SBarry Smith EXTERN int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**); 1087ca44d042SBarry Smith EXTERN int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec); 1088ca44d042SBarry Smith EXTERN int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 1089ca44d042SBarry Smith EXTERN int MatScale_SeqBAIJ(Scalar*,Mat); 1090ca44d042SBarry Smith EXTERN int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *); 1091ca44d042SBarry Smith EXTERN int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*); 1092ca44d042SBarry Smith EXTERN int MatGetDiagonal_SeqBAIJ(Mat,Vec); 1093ca44d042SBarry Smith EXTERN int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 1094ca44d042SBarry Smith EXTERN int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 1095ca44d042SBarry Smith EXTERN int MatZeroEntries_SeqBAIJ(Mat); 10962d61bbb3SSatish Balay 1097ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 1098ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 1099ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 1100ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 1101ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 1102ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 1103ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_6(Mat,Vec,Vec); 1104ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 1105ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec); 1106ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec); 1107ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec); 1108ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec); 1109ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec); 1110ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec); 1111ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec); 11122d61bbb3SSatish Balay 1113ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 1114ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 1115ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 1116ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 1117ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 1118ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 1119ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*); 11202d61bbb3SSatish Balay 1121ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 1122ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 1123ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 1124ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 1125ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 1126ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_6(Mat,Vec,Vec); 1127ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 1128ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 11292d61bbb3SSatish Balay 1130ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 1131ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 1132ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 1133ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 1134ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 1135ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec); 1136ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 1137ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 11382d61bbb3SSatish Balay 11392d61bbb3SSatish Balay #undef __FUNC__ 1140b0a32e0cSBarry Smith #define __FUNC__ "MatILUFactor_SeqBAIJ" 11415ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 11422d61bbb3SSatish Balay { 11432d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data; 11442d61bbb3SSatish Balay Mat outA; 11452d61bbb3SSatish Balay int ierr; 1146667159a5SBarry Smith PetscTruth row_identity,col_identity; 11472d61bbb3SSatish Balay 11482d61bbb3SSatish Balay PetscFunctionBegin; 114929bbc08cSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU"); 1150667159a5SBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1151667159a5SBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1152667159a5SBarry Smith if (!row_identity || !col_identity) { 115329bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1154667159a5SBarry Smith } 11552d61bbb3SSatish Balay 11562d61bbb3SSatish Balay outA = inA; 11572d61bbb3SSatish Balay inA->factor = FACTOR_LU; 11582d61bbb3SSatish Balay 11592d61bbb3SSatish Balay if (!a->diag) { 1160c4992f7dSBarry Smith ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr); 11612d61bbb3SSatish Balay } 11622d61bbb3SSatish Balay /* 116315091d37SBarry Smith Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver 116415091d37SBarry Smith for ILU(0) factorization with natural ordering 11652d61bbb3SSatish Balay */ 116615091d37SBarry Smith switch (a->bs) { 1167f1af5d2fSBarry Smith case 1: 1168e37c484bSBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1169e37c484bSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_1_NaturalOrdering; 1170e37c484bSBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_1_NaturalOrdering; 1171b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=1\n"); 117215091d37SBarry Smith case 2: 117315091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering; 117415091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_2_NaturalOrdering; 11757c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering; 1176b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n"); 117715091d37SBarry Smith break; 117815091d37SBarry Smith case 3: 117915091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering; 118015091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_3_NaturalOrdering; 11817c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering; 1182b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n"); 118315091d37SBarry Smith break; 118415091d37SBarry Smith case 4: 1185667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering; 1186f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 11877c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering; 1188b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n"); 118915091d37SBarry Smith break; 119015091d37SBarry Smith case 5: 1191667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering; 1192667159a5SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_5_NaturalOrdering; 11937c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering; 1194b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n"); 119515091d37SBarry Smith break; 119615091d37SBarry Smith case 6: 119715091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering; 119815091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_6_NaturalOrdering; 11997c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering; 1200b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n"); 120115091d37SBarry Smith break; 120215091d37SBarry Smith case 7: 120315091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering; 12047c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering; 120515091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_7_NaturalOrdering; 1206b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n"); 120715091d37SBarry Smith break; 1208c38d4ed2SBarry Smith default: 1209c38d4ed2SBarry Smith a->row = row; 1210c38d4ed2SBarry Smith a->col = col; 1211c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1212c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1213c38d4ed2SBarry Smith 1214c38d4ed2SBarry Smith /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 12154c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1216b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1217c38d4ed2SBarry Smith 1218c38d4ed2SBarry Smith if (!a->solve_work) { 1219b0a32e0cSBarry Smith ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr); 1220b0a32e0cSBarry Smith PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar)); 1221c38d4ed2SBarry Smith } 12222d61bbb3SSatish Balay } 12232d61bbb3SSatish Balay 1224667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr); 1225667159a5SBarry Smith 12262d61bbb3SSatish Balay PetscFunctionReturn(0); 12272d61bbb3SSatish Balay } 12282d61bbb3SSatish Balay #undef __FUNC__ 1229b0a32e0cSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ" 1230ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1231ba4ca20aSSatish Balay { 1232c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1233ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1234d132466eSBarry Smith int ierr; 1235ba4ca20aSSatish Balay 12363a40ed3dSBarry Smith PetscFunctionBegin; 1237c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1238d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1239d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n");CHKERRQ(ierr); 12403a40ed3dSBarry Smith PetscFunctionReturn(0); 1241ba4ca20aSSatish Balay } 1242d9b7c43dSSatish Balay 1243fb2e594dSBarry Smith EXTERN_C_BEGIN 124427a8da17SBarry Smith #undef __FUNC__ 1245b0a32e0cSBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 124627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 124727a8da17SBarry Smith { 124827a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 124927a8da17SBarry Smith int i,nz,n; 125027a8da17SBarry Smith 125127a8da17SBarry Smith PetscFunctionBegin; 125227a8da17SBarry Smith nz = baij->maxnz; 1253273d9f13SBarry Smith n = mat->n; 125427a8da17SBarry Smith for (i=0; i<nz; i++) { 125527a8da17SBarry Smith baij->j[i] = indices[i]; 125627a8da17SBarry Smith } 125727a8da17SBarry Smith baij->nz = nz; 125827a8da17SBarry Smith for (i=0; i<n; i++) { 125927a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 126027a8da17SBarry Smith } 126127a8da17SBarry Smith 126227a8da17SBarry Smith PetscFunctionReturn(0); 126327a8da17SBarry Smith } 1264fb2e594dSBarry Smith EXTERN_C_END 126527a8da17SBarry Smith 126627a8da17SBarry Smith #undef __FUNC__ 1267b0a32e0cSBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices" 126827a8da17SBarry Smith /*@ 126927a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 127027a8da17SBarry Smith in the matrix. 127127a8da17SBarry Smith 127227a8da17SBarry Smith Input Parameters: 127327a8da17SBarry Smith + mat - the SeqBAIJ matrix 127427a8da17SBarry Smith - indices - the column indices 127527a8da17SBarry Smith 127615091d37SBarry Smith Level: advanced 127715091d37SBarry Smith 127827a8da17SBarry Smith Notes: 127927a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 128027a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 128127a8da17SBarry Smith of the MatSetValues() operation. 128227a8da17SBarry Smith 128327a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 128427a8da17SBarry Smith MatCreateSeqBAIJ(). 128527a8da17SBarry Smith 128627a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 128727a8da17SBarry Smith 128827a8da17SBarry Smith @*/ 128927a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 129027a8da17SBarry Smith { 129127a8da17SBarry Smith int ierr,(*f)(Mat,int *); 129227a8da17SBarry Smith 129327a8da17SBarry Smith PetscFunctionBegin; 129427a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1295549d3d68SSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr); 129627a8da17SBarry Smith if (f) { 129727a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 129827a8da17SBarry Smith } else { 129929bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 130027a8da17SBarry Smith } 130127a8da17SBarry Smith PetscFunctionReturn(0); 130227a8da17SBarry Smith } 130327a8da17SBarry Smith 1304273d9f13SBarry Smith #undef __FUNC__ 1305273d9f13SBarry Smith #define __FUNC__ "MatGetRowMax_SeqBAIJ" 1306273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v) 1307273d9f13SBarry Smith { 1308273d9f13SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1309273d9f13SBarry Smith int ierr,i,j,n,row,bs,*ai,*aj,mbs; 1310273d9f13SBarry Smith PetscReal atmp; 1311273d9f13SBarry Smith Scalar *x,zero = 0.0; 1312273d9f13SBarry Smith MatScalar *aa; 1313273d9f13SBarry Smith int ncols,brow,krow,kcol; 1314273d9f13SBarry Smith 1315273d9f13SBarry Smith PetscFunctionBegin; 1316273d9f13SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1317273d9f13SBarry Smith bs = a->bs; 1318273d9f13SBarry Smith aa = a->a; 1319273d9f13SBarry Smith ai = a->i; 1320273d9f13SBarry Smith aj = a->j; 1321273d9f13SBarry Smith mbs = a->mbs; 1322273d9f13SBarry Smith 1323273d9f13SBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 1324273d9f13SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1325273d9f13SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1326273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1327273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1328273d9f13SBarry Smith ncols = ai[1] - ai[0]; ai++; 1329273d9f13SBarry Smith brow = bs*i; 1330273d9f13SBarry Smith for (j=0; j<ncols; j++){ 1331273d9f13SBarry Smith /* bcol = bs*(*aj); */ 1332273d9f13SBarry Smith for (kcol=0; kcol<bs; kcol++){ 1333273d9f13SBarry Smith for (krow=0; krow<bs; krow++){ 1334273d9f13SBarry Smith atmp = PetscAbsScalar(*aa); aa++; 1335273d9f13SBarry Smith row = brow + krow; /* row index */ 1336273d9f13SBarry Smith /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */ 1337273d9f13SBarry Smith if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp; 1338273d9f13SBarry Smith } 1339273d9f13SBarry Smith } 1340273d9f13SBarry Smith aj++; 1341273d9f13SBarry Smith } 1342273d9f13SBarry Smith } 1343273d9f13SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1344273d9f13SBarry Smith PetscFunctionReturn(0); 1345273d9f13SBarry Smith } 1346273d9f13SBarry Smith 1347273d9f13SBarry Smith #undef __FUNC__ 1348b0a32e0cSBarry Smith #define __FUNC__ "MatSetUpPreallocation_SeqBAIJ" 1349273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A) 1350273d9f13SBarry Smith { 1351273d9f13SBarry Smith int ierr; 1352273d9f13SBarry Smith 1353273d9f13SBarry Smith PetscFunctionBegin; 1354273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr); 1355273d9f13SBarry Smith PetscFunctionReturn(0); 1356273d9f13SBarry Smith } 1357273d9f13SBarry Smith 1358*f2a5309cSSatish Balay #undef __FUNC__ 1359*f2a5309cSSatish Balay #define __FUNC__ "MatGetArray_SeqBAIJ" 1360*f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array) 1361*f2a5309cSSatish Balay { 1362*f2a5309cSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1363*f2a5309cSSatish Balay PetscFunctionBegin; 1364*f2a5309cSSatish Balay *array = a->a; 1365*f2a5309cSSatish Balay PetscFunctionReturn(0); 1366*f2a5309cSSatish Balay } 1367*f2a5309cSSatish Balay 1368*f2a5309cSSatish Balay #undef __FUNC__ 1369*f2a5309cSSatish Balay #define __FUNC__ "MatRestoreArray_SeqBAIJ" 1370*f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array) 1371*f2a5309cSSatish Balay { 1372*f2a5309cSSatish Balay PetscFunctionBegin; 1373*f2a5309cSSatish Balay PetscFunctionReturn(0); 1374*f2a5309cSSatish Balay } 1375*f2a5309cSSatish Balay 13762593348eSBarry Smith /* -------------------------------------------------------------------*/ 1377cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1378cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1379cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1380cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1381cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 13827c922b88SBarry Smith MatMultTranspose_SeqBAIJ, 13837c922b88SBarry Smith MatMultTransposeAdd_SeqBAIJ, 1384cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1385cc2dc46cSBarry Smith 0, 1386cc2dc46cSBarry Smith 0, 1387cc2dc46cSBarry Smith 0, 1388cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1389cc2dc46cSBarry Smith 0, 1390b6490206SBarry Smith 0, 1391f2501298SSatish Balay MatTranspose_SeqBAIJ, 1392cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1393cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1394cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1395cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1396cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1397b6490206SBarry Smith 0, 1398cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1399cc2dc46cSBarry Smith 0, 1400cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1401cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1402cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1403cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1404cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1405cc2dc46cSBarry Smith 0, 1406cc2dc46cSBarry Smith 0, 1407273d9f13SBarry Smith MatSetUpPreallocation_SeqBAIJ, 1408273d9f13SBarry Smith 0, 1409cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1410cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1411cc2dc46cSBarry Smith 0, 1412*f2a5309cSSatish Balay MatGetArray_SeqBAIJ, 1413*f2a5309cSSatish Balay MatRestoreArray_SeqBAIJ, 14142e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1415cc2dc46cSBarry Smith 0, 1416cc2dc46cSBarry Smith 0, 1417cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1418cc2dc46cSBarry Smith 0, 1419cc2dc46cSBarry Smith 0, 1420cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1421cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1422cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1423cc2dc46cSBarry Smith 0, 1424cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1425cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1426cc2dc46cSBarry Smith 0, 1427cc2dc46cSBarry Smith 0, 1428cc2dc46cSBarry Smith 0, 1429cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 14303b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 143192c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1432cc2dc46cSBarry Smith 0, 1433cc2dc46cSBarry Smith 0, 1434cc2dc46cSBarry Smith 0, 1435cc2dc46cSBarry Smith 0, 1436cc2dc46cSBarry Smith 0, 1437cc2dc46cSBarry Smith 0, 1438d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1439cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1440b9b97703SBarry Smith MatDestroy_SeqBAIJ, 1441b9b97703SBarry Smith MatView_SeqBAIJ, 1442273d9f13SBarry Smith MatGetMaps_Petsc, 1443273d9f13SBarry Smith 0, 1444273d9f13SBarry Smith 0, 1445273d9f13SBarry Smith 0, 1446273d9f13SBarry Smith 0, 1447273d9f13SBarry Smith 0, 1448273d9f13SBarry Smith 0, 1449273d9f13SBarry Smith MatGetRowMax_SeqBAIJ, 1450273d9f13SBarry Smith MatConvert_Basic}; 14512593348eSBarry Smith 14523e90b805SBarry Smith EXTERN_C_BEGIN 14533e90b805SBarry Smith #undef __FUNC__ 1454b0a32e0cSBarry Smith #define __FUNC__ "MatStoreValues_SeqBAIJ" 14553e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat) 14563e90b805SBarry Smith { 14573e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1458273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2; 1459d132466eSBarry Smith int ierr; 14603e90b805SBarry Smith 14613e90b805SBarry Smith PetscFunctionBegin; 14623e90b805SBarry Smith if (aij->nonew != 1) { 146329bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14643e90b805SBarry Smith } 14653e90b805SBarry Smith 14663e90b805SBarry Smith /* allocate space for values if not already there */ 14673e90b805SBarry Smith if (!aij->saved_values) { 1468*f2a5309cSSatish Balay ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr); 14693e90b805SBarry Smith } 14703e90b805SBarry Smith 14713e90b805SBarry Smith /* copy values over */ 1472d132466eSBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr); 14733e90b805SBarry Smith PetscFunctionReturn(0); 14743e90b805SBarry Smith } 14753e90b805SBarry Smith EXTERN_C_END 14763e90b805SBarry Smith 14773e90b805SBarry Smith EXTERN_C_BEGIN 14783e90b805SBarry Smith #undef __FUNC__ 1479b0a32e0cSBarry Smith #define __FUNC__ "MatRetrieveValues_SeqBAIJ" 148032e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat) 14813e90b805SBarry Smith { 14823e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1483273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr; 14843e90b805SBarry Smith 14853e90b805SBarry Smith PetscFunctionBegin; 14863e90b805SBarry Smith if (aij->nonew != 1) { 148729bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14883e90b805SBarry Smith } 14893e90b805SBarry Smith if (!aij->saved_values) { 149029bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 14913e90b805SBarry Smith } 14923e90b805SBarry Smith 14933e90b805SBarry Smith /* copy values over */ 1494549d3d68SSatish Balay ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr); 14953e90b805SBarry Smith PetscFunctionReturn(0); 14963e90b805SBarry Smith } 14973e90b805SBarry Smith EXTERN_C_END 14983e90b805SBarry Smith 1499273d9f13SBarry Smith EXTERN_C_BEGIN 1500273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*); 1501273d9f13SBarry Smith EXTERN_C_END 1502273d9f13SBarry Smith 1503273d9f13SBarry Smith EXTERN_C_BEGIN 15045615d1e5SSatish Balay #undef __FUNC__ 1505b0a32e0cSBarry Smith #define __FUNC__ "MatCreate_SeqBAIJ" 1506273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B) 15072593348eSBarry Smith { 1508273d9f13SBarry Smith int ierr,size; 1509b6490206SBarry Smith Mat_SeqBAIJ *b; 15103b2fbd54SBarry Smith 15113a40ed3dSBarry Smith PetscFunctionBegin; 1512273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 151329bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1514b6490206SBarry Smith 1515273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 1516273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 1517b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr); 1518b0a32e0cSBarry Smith B->data = (void*)b; 1519549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr); 1520549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 15212593348eSBarry Smith B->factor = 0; 15222593348eSBarry Smith B->lupivotthreshold = 1.0; 152390f02eecSBarry Smith B->mapping = 0; 15242593348eSBarry Smith b->row = 0; 15252593348eSBarry Smith b->col = 0; 1526e51c0b9cSSatish Balay b->icol = 0; 15272593348eSBarry Smith b->reallocs = 0; 15283e90b805SBarry Smith b->saved_values = 0; 1529563b5814SBarry Smith #if defined(PEYSC_USE_MAT_SINGLE) 1530563b5814SBarry Smith b->setvalueslen = 0; 1531563b5814SBarry Smith b->setvaluescopy = PETSC_NULL; 1532563b5814SBarry Smith #endif 15332593348eSBarry Smith 1534273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 1535273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 1536a5ae1ecdSBarry Smith 1537c4992f7dSBarry Smith b->sorted = PETSC_FALSE; 1538c4992f7dSBarry Smith b->roworiented = PETSC_TRUE; 15392593348eSBarry Smith b->nonew = 0; 15402593348eSBarry Smith b->diag = 0; 15412593348eSBarry Smith b->solve_work = 0; 1542de6a44a3SBarry Smith b->mult_work = 0; 15432593348eSBarry Smith b->spptr = 0; 15440e6d2581SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1545883fce79SBarry Smith b->keepzeroedrows = PETSC_FALSE; 15464e220ebcSLois Curfman McInnes 1547f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 15483e90b805SBarry Smith "MatStoreValues_SeqBAIJ", 1549bc4b532fSSatish Balay MatStoreValues_SeqBAIJ);CHKERRQ(ierr); 1550f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 15513e90b805SBarry Smith "MatRetrieveValues_SeqBAIJ", 1552bc4b532fSSatish Balay MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr); 1553f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 155427a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 1555bc4b532fSSatish Balay MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 1556273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C", 1557273d9f13SBarry Smith "MatConvert_SeqBAIJ_SeqAIJ", 1558273d9f13SBarry Smith MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr); 15593a40ed3dSBarry Smith PetscFunctionReturn(0); 15602593348eSBarry Smith } 1561273d9f13SBarry Smith EXTERN_C_END 15622593348eSBarry Smith 15635615d1e5SSatish Balay #undef __FUNC__ 1564b0a32e0cSBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ" 15652e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 15662593348eSBarry Smith { 15672593348eSBarry Smith Mat C; 1568b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data; 156927a8da17SBarry Smith int i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1570de6a44a3SBarry Smith 15713a40ed3dSBarry Smith PetscFunctionBegin; 157229bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 15732593348eSBarry Smith 15742593348eSBarry Smith *B = 0; 1575273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 1576273d9f13SBarry Smith ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr); 1577273d9f13SBarry Smith c = (Mat_SeqBAIJ*)C->data; 157844cd7ae7SLois Curfman McInnes 1579b6490206SBarry Smith c->bs = a->bs; 15809df24120SSatish Balay c->bs2 = a->bs2; 1581b6490206SBarry Smith c->mbs = a->mbs; 1582b6490206SBarry Smith c->nbs = a->nbs; 158335d8aa7fSBarry Smith ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 15842593348eSBarry Smith 1585b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 1586b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 1587b6490206SBarry Smith for (i=0; i<mbs; i++) { 15882593348eSBarry Smith c->imax[i] = a->imax[i]; 15892593348eSBarry Smith c->ilen[i] = a->ilen[i]; 15902593348eSBarry Smith } 15912593348eSBarry Smith 15922593348eSBarry Smith /* allocate the matrix space */ 1593c4992f7dSBarry Smith c->singlemalloc = PETSC_TRUE; 15943f1db9ecSBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int)); 1595b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 15967e67e3f9SSatish Balay c->j = (int*)(c->a + nz*bs2); 1597de6a44a3SBarry Smith c->i = c->j + nz; 1598549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr); 1599b6490206SBarry Smith if (mbs > 0) { 1600549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr); 16012e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 1602549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16032e8a6d31SBarry Smith } else { 1604549d3d68SSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16052593348eSBarry Smith } 16062593348eSBarry Smith } 16072593348eSBarry Smith 1608b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 16092593348eSBarry Smith c->sorted = a->sorted; 16102593348eSBarry Smith c->roworiented = a->roworiented; 16112593348eSBarry Smith c->nonew = a->nonew; 16122593348eSBarry Smith 16132593348eSBarry Smith if (a->diag) { 1614b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 1615b0a32e0cSBarry Smith PetscLogObjectMemory(C,(mbs+1)*sizeof(int)); 1616b6490206SBarry Smith for (i=0; i<mbs; i++) { 16172593348eSBarry Smith c->diag[i] = a->diag[i]; 16182593348eSBarry Smith } 161998305bb5SBarry Smith } else c->diag = 0; 16202593348eSBarry Smith c->nz = a->nz; 16212593348eSBarry Smith c->maxnz = a->maxnz; 16222593348eSBarry Smith c->solve_work = 0; 16232593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 16247fc0212eSBarry Smith c->mult_work = 0; 1625273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 1626273d9f13SBarry Smith C->assembled = PETSC_TRUE; 16272593348eSBarry Smith *B = C; 1628b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 16293a40ed3dSBarry Smith PetscFunctionReturn(0); 16302593348eSBarry Smith } 16312593348eSBarry Smith 1632273d9f13SBarry Smith EXTERN_C_BEGIN 16335615d1e5SSatish Balay #undef __FUNC__ 1634b0a32e0cSBarry Smith #define __FUNC__ "MatLoad_SeqBAIJ" 1635b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A) 16362593348eSBarry Smith { 1637b6490206SBarry Smith Mat_SeqBAIJ *a; 16382593348eSBarry Smith Mat B; 1639f1af5d2fSBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1; 1640b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 164135aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1642a7c10996SSatish Balay int *masked,nmask,tmp,bs2,ishift; 1643b6490206SBarry Smith Scalar *aa; 164419bcc07fSBarry Smith MPI_Comm comm = ((PetscObject)viewer)->comm; 16452593348eSBarry Smith 16463a40ed3dSBarry Smith PetscFunctionBegin; 1647b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 1648de6a44a3SBarry Smith bs2 = bs*bs; 1649b6490206SBarry Smith 1650d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 165129bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 1652b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 16530752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 165429bbc08cSBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 16552593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 16562593348eSBarry Smith 1657d64ed03dSBarry Smith if (header[3] < 0) { 165829bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ"); 1659d64ed03dSBarry Smith } 1660d64ed03dSBarry Smith 166129bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 166235aab85fSBarry Smith 166335aab85fSBarry Smith /* 166435aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 166535aab85fSBarry Smith divisible by the blocksize 166635aab85fSBarry Smith */ 1667b6490206SBarry Smith mbs = M/bs; 166835aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 166935aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 167035aab85fSBarry Smith else mbs++; 167135aab85fSBarry Smith if (extra_rows) { 1672b0a32e0cSBarry Smith PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 167335aab85fSBarry Smith } 1674b6490206SBarry Smith 16752593348eSBarry Smith /* read in row lengths */ 1676b0a32e0cSBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr); 16770752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 167835aab85fSBarry Smith for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 16792593348eSBarry Smith 1680b6490206SBarry Smith /* read in column indices */ 1681b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr); 16820752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 168335aab85fSBarry Smith for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 1684b6490206SBarry Smith 1685b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1686b0a32e0cSBarry Smith ierr = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr); 1687549d3d68SSatish Balay ierr = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr); 1688b0a32e0cSBarry Smith ierr = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr); 1689549d3d68SSatish Balay ierr = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr); 169035aab85fSBarry Smith masked = mask + mbs; 1691b6490206SBarry Smith rowcount = 0; nzcount = 0; 1692b6490206SBarry Smith for (i=0; i<mbs; i++) { 169335aab85fSBarry Smith nmask = 0; 1694b6490206SBarry Smith for (j=0; j<bs; j++) { 1695b6490206SBarry Smith kmax = rowlengths[rowcount]; 1696b6490206SBarry Smith for (k=0; k<kmax; k++) { 169735aab85fSBarry Smith tmp = jj[nzcount++]/bs; 169835aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1699b6490206SBarry Smith } 1700b6490206SBarry Smith rowcount++; 1701b6490206SBarry Smith } 170235aab85fSBarry Smith browlengths[i] += nmask; 170335aab85fSBarry Smith /* zero out the mask elements we set */ 170435aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1705b6490206SBarry Smith } 1706b6490206SBarry Smith 17072593348eSBarry Smith /* create our matrix */ 17083eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 17092593348eSBarry Smith B = *A; 1710b6490206SBarry Smith a = (Mat_SeqBAIJ*)B->data; 17112593348eSBarry Smith 17122593348eSBarry Smith /* set matrix "i" values */ 1713de6a44a3SBarry Smith a->i[0] = 0; 1714b6490206SBarry Smith for (i=1; i<= mbs; i++) { 1715b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1716b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 17172593348eSBarry Smith } 1718b6490206SBarry Smith a->nz = 0; 1719b6490206SBarry Smith for (i=0; i<mbs; i++) a->nz += browlengths[i]; 17202593348eSBarry Smith 1721b6490206SBarry Smith /* read in nonzero values */ 1722b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr); 17230752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 172435aab85fSBarry Smith for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 1725b6490206SBarry Smith 1726b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1727b6490206SBarry Smith nzcount = 0; jcount = 0; 1728b6490206SBarry Smith for (i=0; i<mbs; i++) { 1729b6490206SBarry Smith nzcountb = nzcount; 173035aab85fSBarry Smith nmask = 0; 1731b6490206SBarry Smith for (j=0; j<bs; j++) { 1732b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1733b6490206SBarry Smith for (k=0; k<kmax; k++) { 173435aab85fSBarry Smith tmp = jj[nzcount++]/bs; 173535aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1736b6490206SBarry Smith } 1737b6490206SBarry Smith rowcount++; 1738b6490206SBarry Smith } 1739de6a44a3SBarry Smith /* sort the masked values */ 1740433994e6SBarry Smith ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 1741de6a44a3SBarry Smith 1742b6490206SBarry Smith /* set "j" values into matrix */ 1743b6490206SBarry Smith maskcount = 1; 174435aab85fSBarry Smith for (j=0; j<nmask; j++) { 174535aab85fSBarry Smith a->j[jcount++] = masked[j]; 1746de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1747b6490206SBarry Smith } 1748b6490206SBarry Smith /* set "a" values into matrix */ 1749de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1750b6490206SBarry Smith for (j=0; j<bs; j++) { 1751b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1752b6490206SBarry Smith for (k=0; k<kmax; k++) { 1753de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1754de6a44a3SBarry Smith block = mask[tmp] - 1; 1755de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1756de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1757375fe846SBarry Smith a->a[idx] = (MatScalar)aa[nzcountb++]; 1758b6490206SBarry Smith } 1759b6490206SBarry Smith } 176035aab85fSBarry Smith /* zero out the mask elements we set */ 176135aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1762b6490206SBarry Smith } 176329bbc08cSBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 1764b6490206SBarry Smith 1765606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 1766606d414cSSatish Balay ierr = PetscFree(browlengths);CHKERRQ(ierr); 1767606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 1768606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 1769606d414cSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 1770b6490206SBarry Smith 1771b6490206SBarry Smith B->assembled = PETSC_TRUE; 1772de6a44a3SBarry Smith 17739c01be13SBarry Smith ierr = MatView_Private(B);CHKERRQ(ierr); 17743a40ed3dSBarry Smith PetscFunctionReturn(0); 17752593348eSBarry Smith } 1776273d9f13SBarry Smith EXTERN_C_END 17772593348eSBarry Smith 1778273d9f13SBarry Smith #undef __FUNC__ 1779b0a32e0cSBarry Smith #define __FUNC__ "MatCreateSeqBAIJ" 1780273d9f13SBarry Smith /*@C 1781273d9f13SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 1782273d9f13SBarry Smith compressed row) format. For good matrix assembly performance the 1783273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1784273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1785273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 17862593348eSBarry Smith 1787273d9f13SBarry Smith Collective on MPI_Comm 1788273d9f13SBarry Smith 1789273d9f13SBarry Smith Input Parameters: 1790273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 1791273d9f13SBarry Smith . bs - size of block 1792273d9f13SBarry Smith . m - number of rows 1793273d9f13SBarry Smith . n - number of columns 179435d8aa7fSBarry Smith . nz - number of nonzero blocks per block row (same for all rows) 179535d8aa7fSBarry Smith - nnz - array containing the number of nonzero blocks in the various block rows 1796273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1797273d9f13SBarry Smith 1798273d9f13SBarry Smith Output Parameter: 1799273d9f13SBarry Smith . A - the matrix 1800273d9f13SBarry Smith 1801273d9f13SBarry Smith Options Database Keys: 1802273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1803273d9f13SBarry Smith block calculations (much slower) 1804273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1805273d9f13SBarry Smith 1806273d9f13SBarry Smith Level: intermediate 1807273d9f13SBarry Smith 1808273d9f13SBarry Smith Notes: 180935d8aa7fSBarry Smith A nonzero block is any block that as 1 or more nonzeros in it 181035d8aa7fSBarry Smith 1811273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1812273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1813273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1814273d9f13SBarry Smith 1815273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1816273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1817273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1818273d9f13SBarry Smith matrices. 1819273d9f13SBarry Smith 1820273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1821273d9f13SBarry Smith @*/ 1822273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A) 1823273d9f13SBarry Smith { 1824273d9f13SBarry Smith int ierr; 1825273d9f13SBarry Smith 1826273d9f13SBarry Smith PetscFunctionBegin; 1827273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 1828273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr); 1829273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr); 1830273d9f13SBarry Smith PetscFunctionReturn(0); 1831273d9f13SBarry Smith } 1832273d9f13SBarry Smith 1833273d9f13SBarry Smith #undef __FUNC__ 1834b0a32e0cSBarry Smith #define __FUNC__ "MatSeqBAIJSetPreallocation" 1835273d9f13SBarry Smith /*@C 1836273d9f13SBarry Smith MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros 1837273d9f13SBarry Smith per row in the matrix. For good matrix assembly performance the 1838273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1839273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1840273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 1841273d9f13SBarry Smith 1842273d9f13SBarry Smith Collective on MPI_Comm 1843273d9f13SBarry Smith 1844273d9f13SBarry Smith Input Parameters: 1845273d9f13SBarry Smith + A - the matrix 1846273d9f13SBarry Smith . bs - size of block 1847273d9f13SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1848273d9f13SBarry Smith - nnz - array containing the number of block nonzeros in the various block rows 1849273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1850273d9f13SBarry Smith 1851273d9f13SBarry Smith Options Database Keys: 1852273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1853273d9f13SBarry Smith block calculations (much slower) 1854273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1855273d9f13SBarry Smith 1856273d9f13SBarry Smith Level: intermediate 1857273d9f13SBarry Smith 1858273d9f13SBarry Smith Notes: 1859273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1860273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1861273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1862273d9f13SBarry Smith 1863273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1864273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1865273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1866273d9f13SBarry Smith matrices. 1867273d9f13SBarry Smith 1868273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1869273d9f13SBarry Smith @*/ 1870273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz) 1871273d9f13SBarry Smith { 1872273d9f13SBarry Smith Mat_SeqBAIJ *b; 1873273d9f13SBarry Smith int i,len,ierr,mbs,nbs,bs2,newbs = bs; 1874273d9f13SBarry Smith PetscTruth flg; 1875273d9f13SBarry Smith 1876273d9f13SBarry Smith PetscFunctionBegin; 1877273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr); 1878273d9f13SBarry Smith if (!flg) PetscFunctionReturn(0); 1879273d9f13SBarry Smith 1880273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1881b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr); 1882273d9f13SBarry Smith if (nnz && newbs != bs) { 1883273d9f13SBarry Smith SETERRQ(1,"Cannot change blocksize from command line if setting nnz"); 1884273d9f13SBarry Smith } 1885273d9f13SBarry Smith bs = newbs; 1886273d9f13SBarry Smith 1887273d9f13SBarry Smith mbs = B->m/bs; 1888273d9f13SBarry Smith nbs = B->n/bs; 1889273d9f13SBarry Smith bs2 = bs*bs; 1890273d9f13SBarry Smith 1891273d9f13SBarry Smith if (mbs*bs!=B->m || nbs*bs!=B->n) { 189235d8aa7fSBarry Smith SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs); 1893273d9f13SBarry Smith } 1894273d9f13SBarry Smith 1895273d9f13SBarry Smith if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than -2: value %d",nz); 1896273d9f13SBarry Smith if (nnz) { 1897273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1898273d9f13SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 1899273d9f13SBarry Smith } 1900273d9f13SBarry Smith } 1901273d9f13SBarry Smith 1902273d9f13SBarry Smith b = (Mat_SeqBAIJ*)B->data; 1903b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr); 1904273d9f13SBarry Smith if (!flg) { 1905273d9f13SBarry Smith switch (bs) { 1906273d9f13SBarry Smith case 1: 1907273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1908273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1909273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_1; 1910273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1911273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 1912273d9f13SBarry Smith break; 1913273d9f13SBarry Smith case 2: 1914273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1915273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1916273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_2; 1917273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1918273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 1919273d9f13SBarry Smith break; 1920273d9f13SBarry Smith case 3: 1921273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1922273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1923273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_3; 1924273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1925273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 1926273d9f13SBarry Smith break; 1927273d9f13SBarry Smith case 4: 1928273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1929273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1930273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4; 1931273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1932273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 1933273d9f13SBarry Smith break; 1934273d9f13SBarry Smith case 5: 1935273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1936273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1937273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5; 1938273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1939273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 1940273d9f13SBarry Smith break; 1941273d9f13SBarry Smith case 6: 1942273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6; 1943273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_6; 1944273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6; 1945273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_6; 1946273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_6; 1947273d9f13SBarry Smith break; 1948273d9f13SBarry Smith case 7: 1949273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1950273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1951273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7; 1952273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 1953273d9f13SBarry Smith break; 1954273d9f13SBarry Smith default: 1955273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_N; 1956273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_N; 1957273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_N; 1958273d9f13SBarry Smith break; 1959273d9f13SBarry Smith } 1960273d9f13SBarry Smith } 1961273d9f13SBarry Smith b->bs = bs; 1962273d9f13SBarry Smith b->mbs = mbs; 1963273d9f13SBarry Smith b->nbs = nbs; 1964b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 1965273d9f13SBarry Smith if (!nnz) { 1966273d9f13SBarry Smith if (nz == PETSC_DEFAULT) nz = 5; 1967273d9f13SBarry Smith else if (nz <= 0) nz = 1; 1968273d9f13SBarry Smith for (i=0; i<mbs; i++) b->imax[i] = nz; 1969273d9f13SBarry Smith nz = nz*mbs; 1970273d9f13SBarry Smith } else { 1971273d9f13SBarry Smith nz = 0; 1972273d9f13SBarry Smith for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 1973273d9f13SBarry Smith } 1974273d9f13SBarry Smith 1975273d9f13SBarry Smith /* allocate the matrix space */ 1976273d9f13SBarry Smith len = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int); 1977b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 1978273d9f13SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1979273d9f13SBarry Smith b->j = (int*)(b->a + nz*bs2); 1980273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 1981273d9f13SBarry Smith b->i = b->j + nz; 1982273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 1983273d9f13SBarry Smith 1984273d9f13SBarry Smith b->i[0] = 0; 1985273d9f13SBarry Smith for (i=1; i<mbs+1; i++) { 1986273d9f13SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 1987273d9f13SBarry Smith } 1988273d9f13SBarry Smith 1989273d9f13SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 1990b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen); 1991b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1992273d9f13SBarry Smith for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 1993273d9f13SBarry Smith 1994273d9f13SBarry Smith b->bs = bs; 1995273d9f13SBarry Smith b->bs2 = bs2; 1996273d9f13SBarry Smith b->mbs = mbs; 1997273d9f13SBarry Smith b->nz = 0; 1998273d9f13SBarry Smith b->maxnz = nz*bs2; 1999273d9f13SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 2000273d9f13SBarry Smith PetscFunctionReturn(0); 2001273d9f13SBarry Smith } 20022593348eSBarry Smith 2003