1*35662bc6SKris Buschelman /*$Id: baij.c,v 1.228 2001/06/21 22:55:30 buschelm Exp buschelm $*/ 22593348eSBarry Smith 32593348eSBarry Smith /* 4b6490206SBarry Smith Defines the basic matrix operations for the BAIJ (compressed row) 52593348eSBarry Smith matrix storage format. 62593348eSBarry Smith */ 7a2ccead7SSatish Balay #include "petscsys.h" /*I "petscmat.h" I*/ 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 */ 304a2ae208SSatish Balay #undef __FUNCT__ 314a2ae208SSatish Balay #define __FUNCT__ "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 484a2ae208SSatish Balay #undef __FUNCT__ 494a2ae208SSatish Balay #define __FUNCT__ "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 764a2ae208SSatish Balay #undef __FUNCT__ 774a2ae208SSatish Balay #define __FUNCT__ "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 */ 90435da068SBarry Smith int nz = a->i[n]; 913b2fbd54SBarry Smith for (i=0; i<nz; i++) a->j[i]++; 923b2fbd54SBarry Smith for (i=0; i<n+1; i++) a->i[i]++; 933b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 943b2fbd54SBarry Smith } else { 953b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 963b2fbd54SBarry Smith } 973b2fbd54SBarry Smith 983a40ed3dSBarry Smith PetscFunctionReturn(0); 993b2fbd54SBarry Smith } 1003b2fbd54SBarry Smith 1014a2ae208SSatish Balay #undef __FUNCT__ 1024a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqBAIJ" 103435da068SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 1043b2fbd54SBarry Smith { 1053b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 106606d414cSSatish Balay int i,n = a->mbs,ierr; 1073b2fbd54SBarry Smith 1083a40ed3dSBarry Smith PetscFunctionBegin; 1093a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1103b2fbd54SBarry Smith if (symmetric) { 111606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 112606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 113af5da2bfSBarry Smith } else if (oshift == 1) { 114435da068SBarry Smith int nz = a->i[n]-1; 1153b2fbd54SBarry Smith for (i=0; i<nz; i++) a->j[i]--; 1163b2fbd54SBarry Smith for (i=0; i<n+1; i++) a->i[i]--; 1173b2fbd54SBarry Smith } 1183a40ed3dSBarry Smith PetscFunctionReturn(0); 1193b2fbd54SBarry Smith } 1203b2fbd54SBarry Smith 1214a2ae208SSatish Balay #undef __FUNCT__ 1224a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqBAIJ" 1232d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs) 1242d61bbb3SSatish Balay { 1252d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data; 1262d61bbb3SSatish Balay 1272d61bbb3SSatish Balay PetscFunctionBegin; 1282d61bbb3SSatish Balay *bs = baij->bs; 1292d61bbb3SSatish Balay PetscFunctionReturn(0); 1302d61bbb3SSatish Balay } 1312d61bbb3SSatish Balay 1322d61bbb3SSatish Balay 1334a2ae208SSatish Balay #undef __FUNCT__ 1344a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqBAIJ" 135e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A) 1362d61bbb3SSatish Balay { 1372d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 138e51c0b9cSSatish Balay int ierr; 1392d61bbb3SSatish Balay 140433994e6SBarry Smith PetscFunctionBegin; 141aa482453SBarry Smith #if defined(PETSC_USE_LOG) 142b0a32e0cSBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 1432d61bbb3SSatish Balay #endif 144606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 145606d414cSSatish Balay if (!a->singlemalloc) { 146606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 147606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 148606d414cSSatish Balay } 149c38d4ed2SBarry Smith if (a->row) { 150c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 151c38d4ed2SBarry Smith } 152c38d4ed2SBarry Smith if (a->col) { 153c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 154c38d4ed2SBarry Smith } 155606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 156606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 157606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 158606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 159606d414cSSatish Balay if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);} 160e51c0b9cSSatish Balay if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 161606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 162563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 163563b5814SBarry Smith if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);} 164563b5814SBarry Smith #endif 165606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 1662d61bbb3SSatish Balay PetscFunctionReturn(0); 1672d61bbb3SSatish Balay } 1682d61bbb3SSatish Balay 1694a2ae208SSatish Balay #undef __FUNCT__ 1704a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqBAIJ" 1712d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1722d61bbb3SSatish Balay { 1732d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1742d61bbb3SSatish Balay 1752d61bbb3SSatish Balay PetscFunctionBegin; 176aa275fccSKris Buschelman switch (op) { 177aa275fccSKris Buschelman case MAT_ROW_ORIENTED: 178aa275fccSKris Buschelman a->roworiented = PETSC_TRUE; 179aa275fccSKris Buschelman break; 180aa275fccSKris Buschelman case MAT_COLUMN_ORIENTED: 181aa275fccSKris Buschelman a->roworiented = PETSC_FALSE; 182aa275fccSKris Buschelman break; 183aa275fccSKris Buschelman case MAT_COLUMNS_SORTED: 184aa275fccSKris Buschelman a->sorted = PETSC_TRUE; 185aa275fccSKris Buschelman break; 186aa275fccSKris Buschelman case MAT_COLUMNS_UNSORTED: 187aa275fccSKris Buschelman a->sorted = PETSC_FALSE; 188aa275fccSKris Buschelman break; 189aa275fccSKris Buschelman case MAT_KEEP_ZEROED_ROWS: 190aa275fccSKris Buschelman a->keepzeroedrows = PETSC_TRUE; 191aa275fccSKris Buschelman break; 192aa275fccSKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 193aa275fccSKris Buschelman a->nonew = 1; 194aa275fccSKris Buschelman break; 195aa275fccSKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 196aa275fccSKris Buschelman a->nonew = -1; 197aa275fccSKris Buschelman break; 198aa275fccSKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 199aa275fccSKris Buschelman a->nonew = -2; 200aa275fccSKris Buschelman break; 201aa275fccSKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 202aa275fccSKris Buschelman a->nonew = 0; 203aa275fccSKris Buschelman break; 204aa275fccSKris Buschelman case MAT_ROWS_SORTED: 205aa275fccSKris Buschelman case MAT_ROWS_UNSORTED: 206aa275fccSKris Buschelman case MAT_YES_NEW_DIAGONALS: 207aa275fccSKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 208aa275fccSKris Buschelman case MAT_USE_HASH_TABLE: 209b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 210aa275fccSKris Buschelman break; 211aa275fccSKris Buschelman case MAT_NO_NEW_DIAGONALS: 21229bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 213aa275fccSKris Buschelman default: 21429bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"unknown option"); 2152d61bbb3SSatish Balay } 2162d61bbb3SSatish Balay PetscFunctionReturn(0); 2172d61bbb3SSatish Balay } 2182d61bbb3SSatish Balay 2194a2ae208SSatish Balay #undef __FUNCT__ 2204a2ae208SSatish Balay #define __FUNCT__ "MatGetOwnershipRange_SeqBAIJ" 2212d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 2222d61bbb3SSatish Balay { 2232d61bbb3SSatish Balay PetscFunctionBegin; 2244c49b128SBarry Smith if (m) *m = 0; 225273d9f13SBarry Smith if (n) *n = A->m; 2262d61bbb3SSatish Balay PetscFunctionReturn(0); 2272d61bbb3SSatish Balay } 2282d61bbb3SSatish Balay 2294a2ae208SSatish Balay #undef __FUNCT__ 2304a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ" 2312d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2322d61bbb3SSatish Balay { 2332d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 23482502324SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr; 2353f1db9ecSBarry Smith MatScalar *aa,*aa_i; 2363f1db9ecSBarry Smith Scalar *v_i; 2372d61bbb3SSatish Balay 2382d61bbb3SSatish Balay PetscFunctionBegin; 2392d61bbb3SSatish Balay bs = a->bs; 2402d61bbb3SSatish Balay ai = a->i; 2412d61bbb3SSatish Balay aj = a->j; 2422d61bbb3SSatish Balay aa = a->a; 2432d61bbb3SSatish Balay bs2 = a->bs2; 2442d61bbb3SSatish Balay 245273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range"); 2462d61bbb3SSatish Balay 2472d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2482d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2492d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2502d61bbb3SSatish Balay *nz = bs*M; 2512d61bbb3SSatish Balay 2522d61bbb3SSatish Balay if (v) { 2532d61bbb3SSatish Balay *v = 0; 2542d61bbb3SSatish Balay if (*nz) { 255b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr); 2562d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2572d61bbb3SSatish Balay v_i = *v + i*bs; 2582d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2592d61bbb3SSatish Balay for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];} 2602d61bbb3SSatish Balay } 2612d61bbb3SSatish Balay } 2622d61bbb3SSatish Balay } 2632d61bbb3SSatish Balay 2642d61bbb3SSatish Balay if (idx) { 2652d61bbb3SSatish Balay *idx = 0; 2662d61bbb3SSatish Balay if (*nz) { 267b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr); 2682d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2692d61bbb3SSatish Balay idx_i = *idx + i*bs; 2702d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2712d61bbb3SSatish Balay for (j=0; j<bs; j++) {idx_i[j] = itmp++;} 2722d61bbb3SSatish Balay } 2732d61bbb3SSatish Balay } 2742d61bbb3SSatish Balay } 2752d61bbb3SSatish Balay PetscFunctionReturn(0); 2762d61bbb3SSatish Balay } 2772d61bbb3SSatish Balay 2784a2ae208SSatish Balay #undef __FUNCT__ 2794a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ" 2802d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2812d61bbb3SSatish Balay { 282606d414cSSatish Balay int ierr; 283606d414cSSatish Balay 2842d61bbb3SSatish Balay PetscFunctionBegin; 285606d414cSSatish Balay if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 286606d414cSSatish Balay if (v) {if (*v) {ierr = PetscFree(*v);CHKERRQ(ierr);}} 2872d61bbb3SSatish Balay PetscFunctionReturn(0); 2882d61bbb3SSatish Balay } 2892d61bbb3SSatish Balay 2904a2ae208SSatish Balay #undef __FUNCT__ 2914a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ" 2922d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2932d61bbb3SSatish Balay { 2942d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2952d61bbb3SSatish Balay Mat C; 2962d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 297273d9f13SBarry Smith int *rows,*cols,bs2=a->bs2; 298375fe846SBarry Smith Scalar *array; 2992d61bbb3SSatish Balay 3002d61bbb3SSatish Balay PetscFunctionBegin; 30129bbc08cSBarry Smith if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place"); 302b0a32e0cSBarry Smith ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr); 303549d3d68SSatish Balay ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr); 3042d61bbb3SSatish Balay 305375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 306b0a32e0cSBarry Smith ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr); 307375fe846SBarry Smith for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i]; 308375fe846SBarry Smith #else 3093eda8832SBarry Smith array = a->a; 310375fe846SBarry Smith #endif 311375fe846SBarry Smith 3122d61bbb3SSatish Balay for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1; 313273d9f13SBarry Smith ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr); 314606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 315b0a32e0cSBarry Smith ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr); 3162d61bbb3SSatish Balay cols = rows + bs; 3172d61bbb3SSatish Balay for (i=0; i<mbs; i++) { 3182d61bbb3SSatish Balay cols[0] = i*bs; 3192d61bbb3SSatish Balay for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1; 3202d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 3212d61bbb3SSatish Balay for (j=0; j<len; j++) { 3222d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 3232d61bbb3SSatish Balay for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1; 3242d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr); 3252d61bbb3SSatish Balay array += bs2; 3262d61bbb3SSatish Balay } 3272d61bbb3SSatish Balay } 328606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 329375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 330375fe846SBarry Smith ierr = PetscFree(array); 331375fe846SBarry Smith #endif 3322d61bbb3SSatish Balay 3332d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3342d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3352d61bbb3SSatish Balay 336c4992f7dSBarry Smith if (B) { 3372d61bbb3SSatish Balay *B = C; 3382d61bbb3SSatish Balay } else { 339273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 3402d61bbb3SSatish Balay } 3412d61bbb3SSatish Balay PetscFunctionReturn(0); 3422d61bbb3SSatish Balay } 3432d61bbb3SSatish Balay 3444a2ae208SSatish Balay #undef __FUNCT__ 3454a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary" 346b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer) 3472593348eSBarry Smith { 348b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 3499df24120SSatish Balay int i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 350b6490206SBarry Smith Scalar *aa; 351ce6f0cecSBarry Smith FILE *file; 3522593348eSBarry Smith 3533a40ed3dSBarry Smith PetscFunctionBegin; 354b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 355b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 3562593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3573b2fbd54SBarry Smith 358273d9f13SBarry Smith col_lens[1] = A->m; 359273d9f13SBarry Smith col_lens[2] = A->n; 3607e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3612593348eSBarry Smith 3622593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 363b6490206SBarry Smith count = 0; 364b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 365b6490206SBarry Smith for (j=0; j<bs; j++) { 366b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 367b6490206SBarry Smith } 3682593348eSBarry Smith } 369273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 370606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 3712593348eSBarry Smith 3722593348eSBarry Smith /* store column indices (zero start index) */ 373b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr); 374b6490206SBarry Smith count = 0; 375b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 376b6490206SBarry Smith for (j=0; j<bs; j++) { 377b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 378b6490206SBarry Smith for (l=0; l<bs; l++) { 379b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3802593348eSBarry Smith } 3812593348eSBarry Smith } 382b6490206SBarry Smith } 383b6490206SBarry Smith } 3840752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr); 385606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 3862593348eSBarry Smith 3872593348eSBarry Smith /* store nonzero values */ 388b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr); 389b6490206SBarry Smith count = 0; 390b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 391b6490206SBarry Smith for (j=0; j<bs; j++) { 392b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 393b6490206SBarry Smith for (l=0; l<bs; l++) { 3947e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 395b6490206SBarry Smith } 396b6490206SBarry Smith } 397b6490206SBarry Smith } 398b6490206SBarry Smith } 3990752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 400606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 401ce6f0cecSBarry Smith 402b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 403ce6f0cecSBarry Smith if (file) { 404ce6f0cecSBarry Smith fprintf(file,"-matload_block_size %d\n",a->bs); 405ce6f0cecSBarry Smith } 4063a40ed3dSBarry Smith PetscFunctionReturn(0); 4072593348eSBarry Smith } 4082593348eSBarry Smith 4094a2ae208SSatish Balay #undef __FUNCT__ 4104a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII" 411b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer) 4122593348eSBarry Smith { 413b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 414fb9695e5SSatish Balay int ierr,i,j,bs = a->bs,k,l,bs2=a->bs2; 415f3ef73ceSBarry Smith PetscViewerFormat format; 4162593348eSBarry Smith 4173a40ed3dSBarry Smith PetscFunctionBegin; 418b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 419fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) { 420b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %d\n",bs);CHKERRQ(ierr); 421fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 42229bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Matlab format not supported"); 423fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 424b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 42544cd7ae7SLois Curfman McInnes for (i=0; i<a->mbs; i++) { 42644cd7ae7SLois Curfman McInnes for (j=0; j<bs; j++) { 427b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 42844cd7ae7SLois Curfman McInnes for (k=a->i[i]; k<a->i[i+1]; k++) { 42944cd7ae7SLois Curfman McInnes for (l=0; l<bs; l++) { 430aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4310e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 432b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l, 4330e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4340e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 435b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l, 4360e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4370e6d2581SBarry Smith } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 438b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4390ef38995SBarry Smith } 44044cd7ae7SLois Curfman McInnes #else 4410ef38995SBarry Smith if (a->a[bs2*k + l*bs + j] != 0.0) { 442b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 4430ef38995SBarry Smith } 44444cd7ae7SLois Curfman McInnes #endif 44544cd7ae7SLois Curfman McInnes } 44644cd7ae7SLois Curfman McInnes } 447b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 44844cd7ae7SLois Curfman McInnes } 44944cd7ae7SLois Curfman McInnes } 450b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4510ef38995SBarry Smith } else { 452b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 453b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 454b6490206SBarry Smith for (j=0; j<bs; j++) { 455b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 456b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 457b6490206SBarry Smith for (l=0; l<bs; l++) { 458aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4590e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 460b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l, 4610e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4620e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 463b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l, 4640e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4650ef38995SBarry Smith } else { 466b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 46788685aaeSLois Curfman McInnes } 46888685aaeSLois Curfman McInnes #else 469b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 47088685aaeSLois Curfman McInnes #endif 4712593348eSBarry Smith } 4722593348eSBarry Smith } 473b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 4742593348eSBarry Smith } 4752593348eSBarry Smith } 476b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 477b6490206SBarry Smith } 478b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4793a40ed3dSBarry Smith PetscFunctionReturn(0); 4802593348eSBarry Smith } 4812593348eSBarry Smith 4824a2ae208SSatish Balay #undef __FUNCT__ 4834a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom" 484b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 4853270192aSSatish Balay { 48677ed5343SBarry Smith Mat A = (Mat) Aa; 4873270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ*)A->data; 488b65db4caSBarry Smith int row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2; 4890e6d2581SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 4903f1db9ecSBarry Smith MatScalar *aa; 491b0a32e0cSBarry Smith PetscViewer viewer; 4923270192aSSatish Balay 4933a40ed3dSBarry Smith PetscFunctionBegin; 4943270192aSSatish Balay 495b65db4caSBarry Smith /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/ 49677ed5343SBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 49777ed5343SBarry Smith 498b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 49977ed5343SBarry Smith 5003270192aSSatish Balay /* loop over matrix elements drawing boxes */ 501b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 5023270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5033270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 504273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5053270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5063270192aSSatish Balay aa = a->a + j*bs2; 5073270192aSSatish Balay for (k=0; k<bs; k++) { 5083270192aSSatish Balay for (l=0; l<bs; l++) { 5090e6d2581SBarry Smith if (PetscRealPart(*aa++) >= 0.) continue; 510b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5113270192aSSatish Balay } 5123270192aSSatish Balay } 5133270192aSSatish Balay } 5143270192aSSatish Balay } 515b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 5163270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5173270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 518273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5193270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5203270192aSSatish Balay aa = a->a + j*bs2; 5213270192aSSatish Balay for (k=0; k<bs; k++) { 5223270192aSSatish Balay for (l=0; l<bs; l++) { 5230e6d2581SBarry Smith if (PetscRealPart(*aa++) != 0.) continue; 524b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5253270192aSSatish Balay } 5263270192aSSatish Balay } 5273270192aSSatish Balay } 5283270192aSSatish Balay } 5293270192aSSatish Balay 530b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 5313270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5323270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 533273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5343270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5353270192aSSatish Balay aa = a->a + j*bs2; 5363270192aSSatish Balay for (k=0; k<bs; k++) { 5373270192aSSatish Balay for (l=0; l<bs; l++) { 5380e6d2581SBarry Smith if (PetscRealPart(*aa++) <= 0.) continue; 539b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5403270192aSSatish Balay } 5413270192aSSatish Balay } 5423270192aSSatish Balay } 5433270192aSSatish Balay } 54477ed5343SBarry Smith PetscFunctionReturn(0); 54577ed5343SBarry Smith } 5463270192aSSatish Balay 5474a2ae208SSatish Balay #undef __FUNCT__ 5484a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw" 549b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer) 55077ed5343SBarry Smith { 5517dce120fSSatish Balay int ierr; 5520e6d2581SBarry Smith PetscReal xl,yl,xr,yr,w,h; 553b0a32e0cSBarry Smith PetscDraw draw; 55477ed5343SBarry Smith PetscTruth isnull; 5553270192aSSatish Balay 55677ed5343SBarry Smith PetscFunctionBegin; 55777ed5343SBarry Smith 558b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 559b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 56077ed5343SBarry Smith 56177ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 562273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 56377ed5343SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 564b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 565b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 56677ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5673a40ed3dSBarry Smith PetscFunctionReturn(0); 5683270192aSSatish Balay } 5693270192aSSatish Balay 5704a2ae208SSatish Balay #undef __FUNCT__ 5714a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ" 572b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer) 5732593348eSBarry Smith { 57419bcc07fSBarry Smith int ierr; 5756831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 5762593348eSBarry Smith 5773a40ed3dSBarry Smith PetscFunctionBegin; 578b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 579b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 580fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 581fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 5820f5bd95cSBarry Smith if (issocket) { 58329bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported"); 5840f5bd95cSBarry Smith } else if (isascii){ 5853a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5860f5bd95cSBarry Smith } else if (isbinary) { 5873a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 5880f5bd95cSBarry Smith } else if (isdraw) { 5893a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 5905cd90555SBarry Smith } else { 59129bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name); 5922593348eSBarry Smith } 5933a40ed3dSBarry Smith PetscFunctionReturn(0); 5942593348eSBarry Smith } 595b6490206SBarry Smith 596cd0e1443SSatish Balay 5974a2ae208SSatish Balay #undef __FUNCT__ 5984a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ" 5992d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 600cd0e1443SSatish Balay { 601cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 6022d61bbb3SSatish Balay int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 6032d61bbb3SSatish Balay int *ai = a->i,*ailen = a->ilen; 6042d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 6053f1db9ecSBarry Smith MatScalar *ap,*aa = a->a,zero = 0.0; 606cd0e1443SSatish Balay 6073a40ed3dSBarry Smith PetscFunctionBegin; 6082d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over rows */ 609cd0e1443SSatish Balay row = im[k]; brow = row/bs; 61029bbc08cSBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row"); 611273d9f13SBarry Smith if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 6122d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 6132c3acbe9SBarry Smith nrow = ailen[brow]; 6142d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over columns */ 61529bbc08cSBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column"); 616273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 6172d61bbb3SSatish Balay col = in[l] ; 6182d61bbb3SSatish Balay bcol = col/bs; 6192d61bbb3SSatish Balay cidx = col%bs; 6202d61bbb3SSatish Balay ridx = row%bs; 6212d61bbb3SSatish Balay high = nrow; 6222d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6232d61bbb3SSatish Balay while (high-low > 5) { 624cd0e1443SSatish Balay t = (low+high)/2; 625cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 626cd0e1443SSatish Balay else low = t; 627cd0e1443SSatish Balay } 628cd0e1443SSatish Balay for (i=low; i<high; i++) { 629cd0e1443SSatish Balay if (rp[i] > bcol) break; 630cd0e1443SSatish Balay if (rp[i] == bcol) { 6312d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6322d61bbb3SSatish Balay goto finished; 633cd0e1443SSatish Balay } 634cd0e1443SSatish Balay } 6352d61bbb3SSatish Balay *v++ = zero; 6362d61bbb3SSatish Balay finished:; 637cd0e1443SSatish Balay } 638cd0e1443SSatish Balay } 6393a40ed3dSBarry Smith PetscFunctionReturn(0); 640cd0e1443SSatish Balay } 641cd0e1443SSatish Balay 64295d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 6434a2ae208SSatish Balay #undef __FUNCT__ 6444a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ" 64595d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv) 64695d5f7c2SBarry Smith { 647563b5814SBarry Smith Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data; 648563b5814SBarry Smith int ierr,i,N = m*n*b->bs2; 649563b5814SBarry Smith MatScalar *vsingle; 65095d5f7c2SBarry Smith 65195d5f7c2SBarry Smith PetscFunctionBegin; 652563b5814SBarry Smith if (N > b->setvalueslen) { 653563b5814SBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 654b0a32e0cSBarry Smith ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 655563b5814SBarry Smith b->setvalueslen = N; 656563b5814SBarry Smith } 657563b5814SBarry Smith vsingle = b->setvaluescopy; 65895d5f7c2SBarry Smith for (i=0; i<N; i++) { 65995d5f7c2SBarry Smith vsingle[i] = v[i]; 66095d5f7c2SBarry Smith } 66195d5f7c2SBarry Smith ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 66295d5f7c2SBarry Smith PetscFunctionReturn(0); 66395d5f7c2SBarry Smith } 66495d5f7c2SBarry Smith #endif 66595d5f7c2SBarry Smith 6662d61bbb3SSatish Balay 6674a2ae208SSatish Balay #undef __FUNCT__ 6684a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ" 66995d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is) 67092c4ed94SBarry Smith { 67192c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 6728a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 673273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 674549d3d68SSatish Balay int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr; 675273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 67695d5f7c2SBarry Smith MatScalar *value = v,*ap,*aa = a->a,*bap; 67792c4ed94SBarry Smith 6783a40ed3dSBarry Smith PetscFunctionBegin; 6790e324ae4SSatish Balay if (roworiented) { 6800e324ae4SSatish Balay stepval = (n-1)*bs; 6810e324ae4SSatish Balay } else { 6820e324ae4SSatish Balay stepval = (m-1)*bs; 6830e324ae4SSatish Balay } 68492c4ed94SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 68592c4ed94SBarry Smith row = im[k]; 6865ef9f2a5SBarry Smith if (row < 0) continue; 687aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 68829bbc08cSBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 68992c4ed94SBarry Smith #endif 69092c4ed94SBarry Smith rp = aj + ai[row]; 69192c4ed94SBarry Smith ap = aa + bs2*ai[row]; 69292c4ed94SBarry Smith rmax = imax[row]; 69392c4ed94SBarry Smith nrow = ailen[row]; 69492c4ed94SBarry Smith low = 0; 69592c4ed94SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 6965ef9f2a5SBarry Smith if (in[l] < 0) continue; 697aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 69829bbc08cSBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 69992c4ed94SBarry Smith #endif 70092c4ed94SBarry Smith col = in[l]; 70192c4ed94SBarry Smith if (roworiented) { 7020e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 7030e324ae4SSatish Balay } else { 7040e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 70592c4ed94SBarry Smith } 70692c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 70792c4ed94SBarry Smith while (high-low > 7) { 70892c4ed94SBarry Smith t = (low+high)/2; 70992c4ed94SBarry Smith if (rp[t] > col) high = t; 71092c4ed94SBarry Smith else low = t; 71192c4ed94SBarry Smith } 71292c4ed94SBarry Smith for (i=low; i<high; i++) { 71392c4ed94SBarry Smith if (rp[i] > col) break; 71492c4ed94SBarry Smith if (rp[i] == col) { 7158a84c255SSatish Balay bap = ap + bs2*i; 7160e324ae4SSatish Balay if (roworiented) { 7178a84c255SSatish Balay if (is == ADD_VALUES) { 718dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 719dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7208a84c255SSatish Balay bap[jj] += *value++; 721dd9472c6SBarry Smith } 722dd9472c6SBarry Smith } 7230e324ae4SSatish Balay } else { 724dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 725dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7260e324ae4SSatish Balay bap[jj] = *value++; 7278a84c255SSatish Balay } 728dd9472c6SBarry Smith } 729dd9472c6SBarry Smith } 7300e324ae4SSatish Balay } else { 7310e324ae4SSatish Balay if (is == ADD_VALUES) { 732dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 733dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7340e324ae4SSatish Balay *bap++ += *value++; 735dd9472c6SBarry Smith } 736dd9472c6SBarry Smith } 7370e324ae4SSatish Balay } else { 738dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 739dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7400e324ae4SSatish Balay *bap++ = *value++; 7410e324ae4SSatish Balay } 7428a84c255SSatish Balay } 743dd9472c6SBarry Smith } 744dd9472c6SBarry Smith } 745f1241b54SBarry Smith goto noinsert2; 74692c4ed94SBarry Smith } 74792c4ed94SBarry Smith } 74889280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 74929bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 75092c4ed94SBarry Smith if (nrow >= rmax) { 75192c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 75292c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 7533f1db9ecSBarry Smith MatScalar *new_a; 75492c4ed94SBarry Smith 75529bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 75689280ab3SLois Curfman McInnes 75792c4ed94SBarry Smith /* malloc new storage space */ 7583f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 759b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 76092c4ed94SBarry Smith new_j = (int*)(new_a + bs2*new_nz); 76192c4ed94SBarry Smith new_i = new_j + new_nz; 76292c4ed94SBarry Smith 76392c4ed94SBarry Smith /* copy over old data into new slots */ 76492c4ed94SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 76592c4ed94SBarry Smith for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 766549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr); 76792c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 768549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr); 769549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 770549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 771549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 77292c4ed94SBarry Smith /* free up old matrix storage */ 773606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 774606d414cSSatish Balay if (!a->singlemalloc) { 775606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 776606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 777606d414cSSatish Balay } 77892c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 779c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 78092c4ed94SBarry Smith 78192c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 78292c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 783b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 78492c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 78592c4ed94SBarry Smith a->reallocs++; 78692c4ed94SBarry Smith a->nz++; 78792c4ed94SBarry Smith } 78892c4ed94SBarry Smith N = nrow++ - 1; 78992c4ed94SBarry Smith /* shift up all the later entries in this row */ 79092c4ed94SBarry Smith for (ii=N; ii>=i; ii--) { 79192c4ed94SBarry Smith rp[ii+1] = rp[ii]; 792549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 79392c4ed94SBarry Smith } 794549d3d68SSatish Balay if (N >= i) { 795549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 796549d3d68SSatish Balay } 79792c4ed94SBarry Smith rp[i] = col; 7988a84c255SSatish Balay bap = ap + bs2*i; 7990e324ae4SSatish Balay if (roworiented) { 800dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 801dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 8020e324ae4SSatish Balay bap[jj] = *value++; 803dd9472c6SBarry Smith } 804dd9472c6SBarry Smith } 8050e324ae4SSatish Balay } else { 806dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 807dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 8080e324ae4SSatish Balay *bap++ = *value++; 8090e324ae4SSatish Balay } 810dd9472c6SBarry Smith } 811dd9472c6SBarry Smith } 812f1241b54SBarry Smith noinsert2:; 81392c4ed94SBarry Smith low = i; 81492c4ed94SBarry Smith } 81592c4ed94SBarry Smith ailen[row] = nrow; 81692c4ed94SBarry Smith } 8173a40ed3dSBarry Smith PetscFunctionReturn(0); 81892c4ed94SBarry Smith } 81992c4ed94SBarry Smith 820f2501298SSatish Balay 8214a2ae208SSatish Balay #undef __FUNCT__ 8224a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ" 8238f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 824584200bdSSatish Balay { 825584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 826584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 827273d9f13SBarry Smith int m = A->m,*ip,N,*ailen = a->ilen; 828549d3d68SSatish Balay int mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr; 8293f1db9ecSBarry Smith MatScalar *aa = a->a,*ap; 830584200bdSSatish Balay 8313a40ed3dSBarry Smith PetscFunctionBegin; 8323a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 833584200bdSSatish Balay 83443ee02c3SBarry Smith if (m) rmax = ailen[0]; 835584200bdSSatish Balay for (i=1; i<mbs; i++) { 836584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 837584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 838d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 839584200bdSSatish Balay if (fshift) { 840a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 841584200bdSSatish Balay N = ailen[i]; 842584200bdSSatish Balay for (j=0; j<N; j++) { 843584200bdSSatish Balay ip[j-fshift] = ip[j]; 844549d3d68SSatish Balay ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr); 845584200bdSSatish Balay } 846584200bdSSatish Balay } 847584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 848584200bdSSatish Balay } 849584200bdSSatish Balay if (mbs) { 850584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 851584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 852584200bdSSatish Balay } 853584200bdSSatish Balay /* reset ilen and imax for each row */ 854584200bdSSatish Balay for (i=0; i<mbs; i++) { 855584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 856584200bdSSatish Balay } 857a7c10996SSatish Balay a->nz = ai[mbs]; 858584200bdSSatish Balay 859584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 860584200bdSSatish Balay if (fshift && a->diag) { 861606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 862b0a32e0cSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(int)); 863584200bdSSatish Balay a->diag = 0; 864584200bdSSatish Balay } 865b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 866273d9f13SBarry Smith m,A->n,a->bs,fshift*bs2,a->nz*bs2); 867b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 868584200bdSSatish Balay a->reallocs); 869b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 870e2f3b5e9SSatish Balay a->reallocs = 0; 8710e6d2581SBarry Smith A->info.nz_unneeded = (PetscReal)fshift*bs2; 8724e220ebcSLois Curfman McInnes 8733a40ed3dSBarry Smith PetscFunctionReturn(0); 874584200bdSSatish Balay } 875584200bdSSatish Balay 8765a838052SSatish Balay 877bea157c4SSatish Balay 878bea157c4SSatish Balay /* 879bea157c4SSatish Balay This function returns an array of flags which indicate the locations of contiguous 880bea157c4SSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 881bea157c4SSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 882bea157c4SSatish Balay Assume: sizes should be long enough to hold all the values. 883bea157c4SSatish Balay */ 8844a2ae208SSatish Balay #undef __FUNCT__ 8854a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks" 886bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max) 887d9b7c43dSSatish Balay { 888bea157c4SSatish Balay int i,j,k,row; 889bea157c4SSatish Balay PetscTruth flg; 8903a40ed3dSBarry Smith 891433994e6SBarry Smith PetscFunctionBegin; 892bea157c4SSatish Balay for (i=0,j=0; i<n; j++) { 893bea157c4SSatish Balay row = idx[i]; 894bea157c4SSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 895bea157c4SSatish Balay sizes[j] = 1; 896bea157c4SSatish Balay i++; 897e4fda26cSSatish Balay } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */ 898bea157c4SSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 899bea157c4SSatish Balay i++; 900bea157c4SSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 901bea157c4SSatish Balay flg = PETSC_TRUE; 902bea157c4SSatish Balay for (k=1; k<bs; k++) { 903bea157c4SSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 904bea157c4SSatish Balay flg = PETSC_FALSE; 905bea157c4SSatish Balay break; 906d9b7c43dSSatish Balay } 907bea157c4SSatish Balay } 908bea157c4SSatish Balay if (flg == PETSC_TRUE) { /* No break in the bs */ 909bea157c4SSatish Balay sizes[j] = bs; 910bea157c4SSatish Balay i+= bs; 911bea157c4SSatish Balay } else { 912bea157c4SSatish Balay sizes[j] = 1; 913bea157c4SSatish Balay i++; 914bea157c4SSatish Balay } 915bea157c4SSatish Balay } 916bea157c4SSatish Balay } 917bea157c4SSatish Balay *bs_max = j; 9183a40ed3dSBarry Smith PetscFunctionReturn(0); 919d9b7c43dSSatish Balay } 920d9b7c43dSSatish Balay 9214a2ae208SSatish Balay #undef __FUNCT__ 9224a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ" 9238f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag) 924d9b7c43dSSatish Balay { 925d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 926b6815fffSBarry Smith int ierr,i,j,k,count,is_n,*is_idx,*rows; 927bea157c4SSatish Balay int bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max; 9283f1db9ecSBarry Smith Scalar zero = 0.0; 9293f1db9ecSBarry Smith MatScalar *aa; 930d9b7c43dSSatish Balay 9313a40ed3dSBarry Smith PetscFunctionBegin; 932d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 933b9b97703SBarry Smith ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr); 934d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 935d9b7c43dSSatish Balay 936bea157c4SSatish Balay /* allocate memory for rows,sizes */ 937b0a32e0cSBarry Smith ierr = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr); 938bea157c4SSatish Balay sizes = rows + is_n; 939bea157c4SSatish Balay 940563b5814SBarry Smith /* copy IS values to rows, and sort them */ 941bea157c4SSatish Balay for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; } 942bea157c4SSatish Balay ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr); 943dffd3267SBarry Smith if (baij->keepzeroedrows) { 944dffd3267SBarry Smith for (i=0; i<is_n; i++) { sizes[i] = 1; } 945dffd3267SBarry Smith bs_max = is_n; 946dffd3267SBarry Smith } else { 947bea157c4SSatish Balay ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr); 948dffd3267SBarry Smith } 949b97a56abSSatish Balay ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr); 950bea157c4SSatish Balay 951bea157c4SSatish Balay for (i=0,j=0; i<bs_max; j+=sizes[i],i++) { 952bea157c4SSatish Balay row = rows[j]; 953273d9f13SBarry Smith if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row); 954bea157c4SSatish Balay count = (baij->i[row/bs +1] - baij->i[row/bs])*bs; 955bea157c4SSatish Balay aa = baij->a + baij->i[row/bs]*bs2 + (row%bs); 956dffd3267SBarry Smith if (sizes[i] == bs && !baij->keepzeroedrows) { 957bea157c4SSatish Balay if (diag) { 958bea157c4SSatish Balay if (baij->ilen[row/bs] > 0) { 959bea157c4SSatish Balay baij->ilen[row/bs] = 1; 960bea157c4SSatish Balay baij->j[baij->i[row/bs]] = row/bs; 961bea157c4SSatish Balay ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr); 962a07cd24cSSatish Balay } 963563b5814SBarry Smith /* Now insert all the diagonal values for this bs */ 964bea157c4SSatish Balay for (k=0; k<bs; k++) { 965bea157c4SSatish Balay ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr); 966bea157c4SSatish Balay } 967bea157c4SSatish Balay } else { /* (!diag) */ 968bea157c4SSatish Balay baij->ilen[row/bs] = 0; 969bea157c4SSatish Balay } /* end (!diag) */ 970bea157c4SSatish Balay } else { /* (sizes[i] != bs) */ 971aa482453SBarry Smith #if defined (PETSC_USE_DEBUG) 97229bbc08cSBarry Smith if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1"); 973bea157c4SSatish Balay #endif 974bea157c4SSatish Balay for (k=0; k<count; k++) { 975d9b7c43dSSatish Balay aa[0] = zero; 976d9b7c43dSSatish Balay aa += bs; 977d9b7c43dSSatish Balay } 978d9b7c43dSSatish Balay if (diag) { 979f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 980d9b7c43dSSatish Balay } 981d9b7c43dSSatish Balay } 982bea157c4SSatish Balay } 983bea157c4SSatish Balay 984606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 9859a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9863a40ed3dSBarry Smith PetscFunctionReturn(0); 987d9b7c43dSSatish Balay } 9881c351548SSatish Balay 9894a2ae208SSatish Balay #undef __FUNCT__ 9904a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ" 9912d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9922d61bbb3SSatish Balay { 9932d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 9942d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 995273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 9962d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 997549d3d68SSatish Balay int ridx,cidx,bs2=a->bs2,ierr; 998273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 9993f1db9ecSBarry Smith MatScalar *ap,value,*aa=a->a,*bap; 10002d61bbb3SSatish Balay 10012d61bbb3SSatish Balay PetscFunctionBegin; 10022d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 10032d61bbb3SSatish Balay row = im[k]; brow = row/bs; 10045ef9f2a5SBarry Smith if (row < 0) continue; 1005aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 1006273d9f13SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m); 10072d61bbb3SSatish Balay #endif 10082d61bbb3SSatish Balay rp = aj + ai[brow]; 10092d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 10102d61bbb3SSatish Balay rmax = imax[brow]; 10112d61bbb3SSatish Balay nrow = ailen[brow]; 10122d61bbb3SSatish Balay low = 0; 10132d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 10145ef9f2a5SBarry Smith if (in[l] < 0) continue; 1015aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 1016273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n); 10172d61bbb3SSatish Balay #endif 10182d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 10192d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 10202d61bbb3SSatish Balay if (roworiented) { 10215ef9f2a5SBarry Smith value = v[l + k*n]; 10222d61bbb3SSatish Balay } else { 10232d61bbb3SSatish Balay value = v[k + l*m]; 10242d61bbb3SSatish Balay } 10252d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 10262d61bbb3SSatish Balay while (high-low > 7) { 10272d61bbb3SSatish Balay t = (low+high)/2; 10282d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 10292d61bbb3SSatish Balay else low = t; 10302d61bbb3SSatish Balay } 10312d61bbb3SSatish Balay for (i=low; i<high; i++) { 10322d61bbb3SSatish Balay if (rp[i] > bcol) break; 10332d61bbb3SSatish Balay if (rp[i] == bcol) { 10342d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 10352d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 10362d61bbb3SSatish Balay else *bap = value; 10372d61bbb3SSatish Balay goto noinsert1; 10382d61bbb3SSatish Balay } 10392d61bbb3SSatish Balay } 10402d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 104129bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10422d61bbb3SSatish Balay if (nrow >= rmax) { 10432d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 10442d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 10453f1db9ecSBarry Smith MatScalar *new_a; 10462d61bbb3SSatish Balay 104729bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10482d61bbb3SSatish Balay 10492d61bbb3SSatish Balay /* Malloc new storage space */ 10503f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 1051b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 10522d61bbb3SSatish Balay new_j = (int*)(new_a + bs2*new_nz); 10532d61bbb3SSatish Balay new_i = new_j + new_nz; 10542d61bbb3SSatish Balay 10552d61bbb3SSatish Balay /* copy over old data into new slots */ 10562d61bbb3SSatish Balay for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];} 10572d61bbb3SSatish Balay for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 1058549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr); 10592d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 1060549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr); 1061549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1062549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 1063549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 10642d61bbb3SSatish Balay /* free up old matrix storage */ 1065606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 1066606d414cSSatish Balay if (!a->singlemalloc) { 1067606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 1068606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 1069606d414cSSatish Balay } 10702d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 1071c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 10722d61bbb3SSatish Balay 10732d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 10742d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 1075b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 10762d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 10772d61bbb3SSatish Balay a->reallocs++; 10782d61bbb3SSatish Balay a->nz++; 10792d61bbb3SSatish Balay } 10802d61bbb3SSatish Balay N = nrow++ - 1; 10812d61bbb3SSatish Balay /* shift up all the later entries in this row */ 10822d61bbb3SSatish Balay for (ii=N; ii>=i; ii--) { 10832d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 1084549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 10852d61bbb3SSatish Balay } 1086549d3d68SSatish Balay if (N>=i) { 1087549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 1088549d3d68SSatish Balay } 10892d61bbb3SSatish Balay rp[i] = bcol; 10902d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10912d61bbb3SSatish Balay noinsert1:; 10922d61bbb3SSatish Balay low = i; 10932d61bbb3SSatish Balay } 10942d61bbb3SSatish Balay ailen[brow] = nrow; 10952d61bbb3SSatish Balay } 10962d61bbb3SSatish Balay PetscFunctionReturn(0); 10972d61bbb3SSatish Balay } 10982d61bbb3SSatish Balay 1099b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,MatLUInfo*,Mat*); 1100b9b97703SBarry Smith EXTERN int MatLUFactor_SeqBAIJ(Mat,IS,IS,MatLUInfo*); 1101ca44d042SBarry Smith EXTERN int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 1102ca44d042SBarry Smith EXTERN int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*); 1103ca44d042SBarry Smith EXTERN int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**); 1104ca44d042SBarry Smith EXTERN int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec); 1105ca44d042SBarry Smith EXTERN int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 1106ca44d042SBarry Smith EXTERN int MatScale_SeqBAIJ(Scalar*,Mat); 1107ca44d042SBarry Smith EXTERN int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *); 1108ca44d042SBarry Smith EXTERN int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*); 1109ca44d042SBarry Smith EXTERN int MatGetDiagonal_SeqBAIJ(Mat,Vec); 1110ca44d042SBarry Smith EXTERN int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 1111ca44d042SBarry Smith EXTERN int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 1112ca44d042SBarry Smith EXTERN int MatZeroEntries_SeqBAIJ(Mat); 11132d61bbb3SSatish Balay 1114ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 1115ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 1116ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 1117ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 1118ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 1119ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 1120ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_6(Mat,Vec,Vec); 1121ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 1122ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec); 1123ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec); 1124ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec); 1125ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec); 1126ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec); 1127ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec); 1128ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec); 11292d61bbb3SSatish Balay 1130ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 1131ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 1132ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 1133ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 1134ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 1135ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 1136ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*); 11372d61bbb3SSatish Balay 1138ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 1139ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 1140ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 1141ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 1142ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 1143ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_6(Mat,Vec,Vec); 1144ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 1145ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 11462d61bbb3SSatish Balay 1147ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 1148ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 1149ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 1150ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 1151ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 1152ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec); 1153ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 1154ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 11552d61bbb3SSatish Balay 11564a2ae208SSatish Balay #undef __FUNCT__ 11574a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ" 11585ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 11592d61bbb3SSatish Balay { 11602d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data; 11612d61bbb3SSatish Balay Mat outA; 11622d61bbb3SSatish Balay int ierr; 1163667159a5SBarry Smith PetscTruth row_identity,col_identity; 11642d61bbb3SSatish Balay 11652d61bbb3SSatish Balay PetscFunctionBegin; 116629bbc08cSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU"); 1167667159a5SBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1168667159a5SBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1169667159a5SBarry Smith if (!row_identity || !col_identity) { 117029bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1171667159a5SBarry Smith } 11722d61bbb3SSatish Balay 11732d61bbb3SSatish Balay outA = inA; 11742d61bbb3SSatish Balay inA->factor = FACTOR_LU; 11752d61bbb3SSatish Balay 11762d61bbb3SSatish Balay if (!a->diag) { 1177c4992f7dSBarry Smith ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr); 11782d61bbb3SSatish Balay } 11792d61bbb3SSatish Balay /* 118015091d37SBarry Smith Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver 118115091d37SBarry Smith for ILU(0) factorization with natural ordering 11822d61bbb3SSatish Balay */ 118315091d37SBarry Smith switch (a->bs) { 1184f1af5d2fSBarry Smith case 1: 1185e37c484bSBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1186e37c484bSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_1_NaturalOrdering; 1187e37c484bSBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_1_NaturalOrdering; 1188b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=1\n"); 118915091d37SBarry Smith case 2: 119015091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering; 119115091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_2_NaturalOrdering; 11927c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering; 1193b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n"); 119415091d37SBarry Smith break; 119515091d37SBarry Smith case 3: 119615091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering; 119715091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_3_NaturalOrdering; 11987c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering; 1199b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n"); 120015091d37SBarry Smith break; 120115091d37SBarry Smith case 4: 1202*35662bc6SKris Buschelman #if defined(PETSC_HAVE_SSE) 1203*35662bc6SKris Buschelman PetscTruth sse_enabled; 1204*35662bc6SKris Buschelman ierr = PetscSSEIsEnabled(&sse_enabled);CHKERRQ(ierr); 1205*35662bc6SKris Buschelman if (sse_enabled) { 1206*35662bc6SKris Buschelman inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering_SSE; 1207*35662bc6SKris Buschelman } else { 1208667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering; 1209*35662bc6SKris Buschelman } 1210*35662bc6SKris Buschelman #else 1211*35662bc6SKris Buschelman inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering; 1212*35662bc6SKris Buschelman #endif 1213f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 12147c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering; 1215b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n"); 121615091d37SBarry Smith break; 121715091d37SBarry Smith case 5: 1218667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering; 1219667159a5SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_5_NaturalOrdering; 12207c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering; 1221b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n"); 122215091d37SBarry Smith break; 122315091d37SBarry Smith case 6: 122415091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering; 122515091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_6_NaturalOrdering; 12267c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering; 1227b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n"); 122815091d37SBarry Smith break; 122915091d37SBarry Smith case 7: 123015091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering; 12317c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering; 123215091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_7_NaturalOrdering; 1233b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n"); 123415091d37SBarry Smith break; 1235c38d4ed2SBarry Smith default: 1236c38d4ed2SBarry Smith a->row = row; 1237c38d4ed2SBarry Smith a->col = col; 1238c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1239c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1240c38d4ed2SBarry Smith 1241c38d4ed2SBarry Smith /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 12424c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1243b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1244c38d4ed2SBarry Smith 1245c38d4ed2SBarry Smith if (!a->solve_work) { 1246b0a32e0cSBarry Smith ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr); 1247b0a32e0cSBarry Smith PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar)); 1248c38d4ed2SBarry Smith } 12492d61bbb3SSatish Balay } 12502d61bbb3SSatish Balay 1251667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr); 1252667159a5SBarry Smith 12532d61bbb3SSatish Balay PetscFunctionReturn(0); 12542d61bbb3SSatish Balay } 12554a2ae208SSatish Balay #undef __FUNCT__ 12564a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ" 1257ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1258ba4ca20aSSatish Balay { 1259c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1260ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1261d132466eSBarry Smith int ierr; 1262ba4ca20aSSatish Balay 12633a40ed3dSBarry Smith PetscFunctionBegin; 1264c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1265d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1266d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n");CHKERRQ(ierr); 12673a40ed3dSBarry Smith PetscFunctionReturn(0); 1268ba4ca20aSSatish Balay } 1269d9b7c43dSSatish Balay 1270fb2e594dSBarry Smith EXTERN_C_BEGIN 12714a2ae208SSatish Balay #undef __FUNCT__ 12724a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 127327a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 127427a8da17SBarry Smith { 127527a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 127627a8da17SBarry Smith int i,nz,n; 127727a8da17SBarry Smith 127827a8da17SBarry Smith PetscFunctionBegin; 127927a8da17SBarry Smith nz = baij->maxnz; 1280273d9f13SBarry Smith n = mat->n; 128127a8da17SBarry Smith for (i=0; i<nz; i++) { 128227a8da17SBarry Smith baij->j[i] = indices[i]; 128327a8da17SBarry Smith } 128427a8da17SBarry Smith baij->nz = nz; 128527a8da17SBarry Smith for (i=0; i<n; i++) { 128627a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 128727a8da17SBarry Smith } 128827a8da17SBarry Smith 128927a8da17SBarry Smith PetscFunctionReturn(0); 129027a8da17SBarry Smith } 1291fb2e594dSBarry Smith EXTERN_C_END 129227a8da17SBarry Smith 12934a2ae208SSatish Balay #undef __FUNCT__ 12944a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices" 129527a8da17SBarry Smith /*@ 129627a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 129727a8da17SBarry Smith in the matrix. 129827a8da17SBarry Smith 129927a8da17SBarry Smith Input Parameters: 130027a8da17SBarry Smith + mat - the SeqBAIJ matrix 130127a8da17SBarry Smith - indices - the column indices 130227a8da17SBarry Smith 130315091d37SBarry Smith Level: advanced 130415091d37SBarry Smith 130527a8da17SBarry Smith Notes: 130627a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 130727a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 130827a8da17SBarry Smith of the MatSetValues() operation. 130927a8da17SBarry Smith 131027a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 131127a8da17SBarry Smith MatCreateSeqBAIJ(). 131227a8da17SBarry Smith 131327a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 131427a8da17SBarry Smith 131527a8da17SBarry Smith @*/ 131627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 131727a8da17SBarry Smith { 131827a8da17SBarry Smith int ierr,(*f)(Mat,int *); 131927a8da17SBarry Smith 132027a8da17SBarry Smith PetscFunctionBegin; 132127a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1322b9617806SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr); 132327a8da17SBarry Smith if (f) { 132427a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 132527a8da17SBarry Smith } else { 132629bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 132727a8da17SBarry Smith } 132827a8da17SBarry Smith PetscFunctionReturn(0); 132927a8da17SBarry Smith } 133027a8da17SBarry Smith 13314a2ae208SSatish Balay #undef __FUNCT__ 13324a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ" 1333273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v) 1334273d9f13SBarry Smith { 1335273d9f13SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1336273d9f13SBarry Smith int ierr,i,j,n,row,bs,*ai,*aj,mbs; 1337273d9f13SBarry Smith PetscReal atmp; 1338273d9f13SBarry Smith Scalar *x,zero = 0.0; 1339273d9f13SBarry Smith MatScalar *aa; 1340273d9f13SBarry Smith int ncols,brow,krow,kcol; 1341273d9f13SBarry Smith 1342273d9f13SBarry Smith PetscFunctionBegin; 1343273d9f13SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1344273d9f13SBarry Smith bs = a->bs; 1345273d9f13SBarry Smith aa = a->a; 1346273d9f13SBarry Smith ai = a->i; 1347273d9f13SBarry Smith aj = a->j; 1348273d9f13SBarry Smith mbs = a->mbs; 1349273d9f13SBarry Smith 1350273d9f13SBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 1351273d9f13SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1352273d9f13SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1353273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1354273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1355273d9f13SBarry Smith ncols = ai[1] - ai[0]; ai++; 1356273d9f13SBarry Smith brow = bs*i; 1357273d9f13SBarry Smith for (j=0; j<ncols; j++){ 1358273d9f13SBarry Smith /* bcol = bs*(*aj); */ 1359273d9f13SBarry Smith for (kcol=0; kcol<bs; kcol++){ 1360273d9f13SBarry Smith for (krow=0; krow<bs; krow++){ 1361273d9f13SBarry Smith atmp = PetscAbsScalar(*aa); aa++; 1362273d9f13SBarry Smith row = brow + krow; /* row index */ 1363273d9f13SBarry Smith /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */ 1364273d9f13SBarry Smith if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp; 1365273d9f13SBarry Smith } 1366273d9f13SBarry Smith } 1367273d9f13SBarry Smith aj++; 1368273d9f13SBarry Smith } 1369273d9f13SBarry Smith } 1370273d9f13SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1371273d9f13SBarry Smith PetscFunctionReturn(0); 1372273d9f13SBarry Smith } 1373273d9f13SBarry Smith 13744a2ae208SSatish Balay #undef __FUNCT__ 13754a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ" 1376273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A) 1377273d9f13SBarry Smith { 1378273d9f13SBarry Smith int ierr; 1379273d9f13SBarry Smith 1380273d9f13SBarry Smith PetscFunctionBegin; 1381273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr); 1382273d9f13SBarry Smith PetscFunctionReturn(0); 1383273d9f13SBarry Smith } 1384273d9f13SBarry Smith 13854a2ae208SSatish Balay #undef __FUNCT__ 13864a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ" 1387f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array) 1388f2a5309cSSatish Balay { 1389f2a5309cSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1390f2a5309cSSatish Balay PetscFunctionBegin; 1391f2a5309cSSatish Balay *array = a->a; 1392f2a5309cSSatish Balay PetscFunctionReturn(0); 1393f2a5309cSSatish Balay } 1394f2a5309cSSatish Balay 13954a2ae208SSatish Balay #undef __FUNCT__ 13964a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ" 1397f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array) 1398f2a5309cSSatish Balay { 1399f2a5309cSSatish Balay PetscFunctionBegin; 1400f2a5309cSSatish Balay PetscFunctionReturn(0); 1401f2a5309cSSatish Balay } 1402f2a5309cSSatish Balay 14032593348eSBarry Smith /* -------------------------------------------------------------------*/ 1404cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1405cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1406cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1407cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1408cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 14097c922b88SBarry Smith MatMultTranspose_SeqBAIJ, 14107c922b88SBarry Smith MatMultTransposeAdd_SeqBAIJ, 1411cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1412cc2dc46cSBarry Smith 0, 1413cc2dc46cSBarry Smith 0, 1414cc2dc46cSBarry Smith 0, 1415cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1416cc2dc46cSBarry Smith 0, 1417b6490206SBarry Smith 0, 1418f2501298SSatish Balay MatTranspose_SeqBAIJ, 1419cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1420cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1421cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1422cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1423cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1424b6490206SBarry Smith 0, 1425cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1426cc2dc46cSBarry Smith 0, 1427cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1428cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1429cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1430cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1431cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1432cc2dc46cSBarry Smith 0, 1433cc2dc46cSBarry Smith 0, 1434273d9f13SBarry Smith MatSetUpPreallocation_SeqBAIJ, 1435273d9f13SBarry Smith 0, 1436cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1437cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1438cc2dc46cSBarry Smith 0, 1439f2a5309cSSatish Balay MatGetArray_SeqBAIJ, 1440f2a5309cSSatish Balay MatRestoreArray_SeqBAIJ, 14412e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1442cc2dc46cSBarry Smith 0, 1443cc2dc46cSBarry Smith 0, 1444cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1445cc2dc46cSBarry Smith 0, 1446cc2dc46cSBarry Smith 0, 1447cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1448cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1449cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1450cc2dc46cSBarry Smith 0, 1451cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1452cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1453cc2dc46cSBarry Smith 0, 1454cc2dc46cSBarry Smith 0, 1455cc2dc46cSBarry Smith 0, 1456cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 14573b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 145892c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1459cc2dc46cSBarry Smith 0, 1460cc2dc46cSBarry Smith 0, 1461cc2dc46cSBarry Smith 0, 1462cc2dc46cSBarry Smith 0, 1463cc2dc46cSBarry Smith 0, 1464cc2dc46cSBarry Smith 0, 1465d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1466cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1467b9b97703SBarry Smith MatDestroy_SeqBAIJ, 1468b9b97703SBarry Smith MatView_SeqBAIJ, 1469273d9f13SBarry Smith MatGetMaps_Petsc, 1470273d9f13SBarry Smith 0, 1471273d9f13SBarry Smith 0, 1472273d9f13SBarry Smith 0, 1473273d9f13SBarry Smith 0, 1474273d9f13SBarry Smith 0, 1475273d9f13SBarry Smith 0, 1476273d9f13SBarry Smith MatGetRowMax_SeqBAIJ, 1477273d9f13SBarry Smith MatConvert_Basic}; 14782593348eSBarry Smith 14793e90b805SBarry Smith EXTERN_C_BEGIN 14804a2ae208SSatish Balay #undef __FUNCT__ 14814a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ" 14823e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat) 14833e90b805SBarry Smith { 14843e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1485273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2; 1486d132466eSBarry Smith int ierr; 14873e90b805SBarry Smith 14883e90b805SBarry Smith PetscFunctionBegin; 14893e90b805SBarry Smith if (aij->nonew != 1) { 149029bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14913e90b805SBarry Smith } 14923e90b805SBarry Smith 14933e90b805SBarry Smith /* allocate space for values if not already there */ 14943e90b805SBarry Smith if (!aij->saved_values) { 1495f2a5309cSSatish Balay ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr); 14963e90b805SBarry Smith } 14973e90b805SBarry Smith 14983e90b805SBarry Smith /* copy values over */ 1499d132466eSBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr); 15003e90b805SBarry Smith PetscFunctionReturn(0); 15013e90b805SBarry Smith } 15023e90b805SBarry Smith EXTERN_C_END 15033e90b805SBarry Smith 15043e90b805SBarry Smith EXTERN_C_BEGIN 15054a2ae208SSatish Balay #undef __FUNCT__ 15064a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ" 150732e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat) 15083e90b805SBarry Smith { 15093e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1510273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr; 15113e90b805SBarry Smith 15123e90b805SBarry Smith PetscFunctionBegin; 15133e90b805SBarry Smith if (aij->nonew != 1) { 151429bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 15153e90b805SBarry Smith } 15163e90b805SBarry Smith if (!aij->saved_values) { 151729bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 15183e90b805SBarry Smith } 15193e90b805SBarry Smith 15203e90b805SBarry Smith /* copy values over */ 1521549d3d68SSatish Balay ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr); 15223e90b805SBarry Smith PetscFunctionReturn(0); 15233e90b805SBarry Smith } 15243e90b805SBarry Smith EXTERN_C_END 15253e90b805SBarry Smith 1526273d9f13SBarry Smith EXTERN_C_BEGIN 1527273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*); 1528273d9f13SBarry Smith EXTERN_C_END 1529273d9f13SBarry Smith 1530273d9f13SBarry Smith EXTERN_C_BEGIN 15314a2ae208SSatish Balay #undef __FUNCT__ 15324a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ" 1533273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B) 15342593348eSBarry Smith { 1535273d9f13SBarry Smith int ierr,size; 1536b6490206SBarry Smith Mat_SeqBAIJ *b; 15373b2fbd54SBarry Smith 15383a40ed3dSBarry Smith PetscFunctionBegin; 1539273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 154029bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1541b6490206SBarry Smith 1542273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 1543273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 1544b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr); 1545b0a32e0cSBarry Smith B->data = (void*)b; 1546549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr); 1547549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 15482593348eSBarry Smith B->factor = 0; 15492593348eSBarry Smith B->lupivotthreshold = 1.0; 155090f02eecSBarry Smith B->mapping = 0; 15512593348eSBarry Smith b->row = 0; 15522593348eSBarry Smith b->col = 0; 1553e51c0b9cSSatish Balay b->icol = 0; 15542593348eSBarry Smith b->reallocs = 0; 15553e90b805SBarry Smith b->saved_values = 0; 1556cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 1557563b5814SBarry Smith b->setvalueslen = 0; 1558563b5814SBarry Smith b->setvaluescopy = PETSC_NULL; 1559563b5814SBarry Smith #endif 15602593348eSBarry Smith 1561273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 1562273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 1563a5ae1ecdSBarry Smith 1564c4992f7dSBarry Smith b->sorted = PETSC_FALSE; 1565c4992f7dSBarry Smith b->roworiented = PETSC_TRUE; 15662593348eSBarry Smith b->nonew = 0; 15672593348eSBarry Smith b->diag = 0; 15682593348eSBarry Smith b->solve_work = 0; 1569de6a44a3SBarry Smith b->mult_work = 0; 15702593348eSBarry Smith b->spptr = 0; 15710e6d2581SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1572883fce79SBarry Smith b->keepzeroedrows = PETSC_FALSE; 15734e220ebcSLois Curfman McInnes 1574f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 15753e90b805SBarry Smith "MatStoreValues_SeqBAIJ", 1576bc4b532fSSatish Balay MatStoreValues_SeqBAIJ);CHKERRQ(ierr); 1577f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 15783e90b805SBarry Smith "MatRetrieveValues_SeqBAIJ", 1579bc4b532fSSatish Balay MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr); 1580f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 158127a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 1582bc4b532fSSatish Balay MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 1583273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C", 1584273d9f13SBarry Smith "MatConvert_SeqBAIJ_SeqAIJ", 1585273d9f13SBarry Smith MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr); 15863a40ed3dSBarry Smith PetscFunctionReturn(0); 15872593348eSBarry Smith } 1588273d9f13SBarry Smith EXTERN_C_END 15892593348eSBarry Smith 15904a2ae208SSatish Balay #undef __FUNCT__ 15914a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ" 15922e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 15932593348eSBarry Smith { 15942593348eSBarry Smith Mat C; 1595b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data; 159627a8da17SBarry Smith int i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1597de6a44a3SBarry Smith 15983a40ed3dSBarry Smith PetscFunctionBegin; 159929bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 16002593348eSBarry Smith 16012593348eSBarry Smith *B = 0; 1602273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 1603273d9f13SBarry Smith ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr); 1604273d9f13SBarry Smith c = (Mat_SeqBAIJ*)C->data; 160544cd7ae7SLois Curfman McInnes 1606b6490206SBarry Smith c->bs = a->bs; 16079df24120SSatish Balay c->bs2 = a->bs2; 1608b6490206SBarry Smith c->mbs = a->mbs; 1609b6490206SBarry Smith c->nbs = a->nbs; 161035d8aa7fSBarry Smith ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 16112593348eSBarry Smith 1612b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 1613b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 1614b6490206SBarry Smith for (i=0; i<mbs; i++) { 16152593348eSBarry Smith c->imax[i] = a->imax[i]; 16162593348eSBarry Smith c->ilen[i] = a->ilen[i]; 16172593348eSBarry Smith } 16182593348eSBarry Smith 16192593348eSBarry Smith /* allocate the matrix space */ 1620c4992f7dSBarry Smith c->singlemalloc = PETSC_TRUE; 16213f1db9ecSBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int)); 1622b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 16237e67e3f9SSatish Balay c->j = (int*)(c->a + nz*bs2); 1624de6a44a3SBarry Smith c->i = c->j + nz; 1625549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr); 1626b6490206SBarry Smith if (mbs > 0) { 1627549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr); 16282e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 1629549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16302e8a6d31SBarry Smith } else { 1631549d3d68SSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16322593348eSBarry Smith } 16332593348eSBarry Smith } 16342593348eSBarry Smith 1635b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 16362593348eSBarry Smith c->sorted = a->sorted; 16372593348eSBarry Smith c->roworiented = a->roworiented; 16382593348eSBarry Smith c->nonew = a->nonew; 16392593348eSBarry Smith 16402593348eSBarry Smith if (a->diag) { 1641b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 1642b0a32e0cSBarry Smith PetscLogObjectMemory(C,(mbs+1)*sizeof(int)); 1643b6490206SBarry Smith for (i=0; i<mbs; i++) { 16442593348eSBarry Smith c->diag[i] = a->diag[i]; 16452593348eSBarry Smith } 164698305bb5SBarry Smith } else c->diag = 0; 16472593348eSBarry Smith c->nz = a->nz; 16482593348eSBarry Smith c->maxnz = a->maxnz; 16492593348eSBarry Smith c->solve_work = 0; 16502593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 16517fc0212eSBarry Smith c->mult_work = 0; 1652273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 1653273d9f13SBarry Smith C->assembled = PETSC_TRUE; 16542593348eSBarry Smith *B = C; 1655b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 16563a40ed3dSBarry Smith PetscFunctionReturn(0); 16572593348eSBarry Smith } 16582593348eSBarry Smith 1659273d9f13SBarry Smith EXTERN_C_BEGIN 16604a2ae208SSatish Balay #undef __FUNCT__ 16614a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ" 1662b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A) 16632593348eSBarry Smith { 1664b6490206SBarry Smith Mat_SeqBAIJ *a; 16652593348eSBarry Smith Mat B; 1666f1af5d2fSBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1; 1667b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 166835aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1669a7c10996SSatish Balay int *masked,nmask,tmp,bs2,ishift; 1670b6490206SBarry Smith Scalar *aa; 167119bcc07fSBarry Smith MPI_Comm comm = ((PetscObject)viewer)->comm; 16722593348eSBarry Smith 16733a40ed3dSBarry Smith PetscFunctionBegin; 1674b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 1675de6a44a3SBarry Smith bs2 = bs*bs; 1676b6490206SBarry Smith 1677d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 167829bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 1679b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 16800752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 168129bbc08cSBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 16822593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 16832593348eSBarry Smith 1684d64ed03dSBarry Smith if (header[3] < 0) { 168529bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ"); 1686d64ed03dSBarry Smith } 1687d64ed03dSBarry Smith 168829bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 168935aab85fSBarry Smith 169035aab85fSBarry Smith /* 169135aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 169235aab85fSBarry Smith divisible by the blocksize 169335aab85fSBarry Smith */ 1694b6490206SBarry Smith mbs = M/bs; 169535aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 169635aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 169735aab85fSBarry Smith else mbs++; 169835aab85fSBarry Smith if (extra_rows) { 1699b0a32e0cSBarry Smith PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 170035aab85fSBarry Smith } 1701b6490206SBarry Smith 17022593348eSBarry Smith /* read in row lengths */ 1703b0a32e0cSBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr); 17040752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 170535aab85fSBarry Smith for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 17062593348eSBarry Smith 1707b6490206SBarry Smith /* read in column indices */ 1708b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr); 17090752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 171035aab85fSBarry Smith for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 1711b6490206SBarry Smith 1712b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1713b0a32e0cSBarry Smith ierr = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr); 1714549d3d68SSatish Balay ierr = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr); 1715b0a32e0cSBarry Smith ierr = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr); 1716549d3d68SSatish Balay ierr = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr); 171735aab85fSBarry Smith masked = mask + mbs; 1718b6490206SBarry Smith rowcount = 0; nzcount = 0; 1719b6490206SBarry Smith for (i=0; i<mbs; i++) { 172035aab85fSBarry Smith nmask = 0; 1721b6490206SBarry Smith for (j=0; j<bs; j++) { 1722b6490206SBarry Smith kmax = rowlengths[rowcount]; 1723b6490206SBarry Smith for (k=0; k<kmax; k++) { 172435aab85fSBarry Smith tmp = jj[nzcount++]/bs; 172535aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1726b6490206SBarry Smith } 1727b6490206SBarry Smith rowcount++; 1728b6490206SBarry Smith } 172935aab85fSBarry Smith browlengths[i] += nmask; 173035aab85fSBarry Smith /* zero out the mask elements we set */ 173135aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1732b6490206SBarry Smith } 1733b6490206SBarry Smith 17342593348eSBarry Smith /* create our matrix */ 17353eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 17362593348eSBarry Smith B = *A; 1737b6490206SBarry Smith a = (Mat_SeqBAIJ*)B->data; 17382593348eSBarry Smith 17392593348eSBarry Smith /* set matrix "i" values */ 1740de6a44a3SBarry Smith a->i[0] = 0; 1741b6490206SBarry Smith for (i=1; i<= mbs; i++) { 1742b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1743b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 17442593348eSBarry Smith } 1745b6490206SBarry Smith a->nz = 0; 1746b6490206SBarry Smith for (i=0; i<mbs; i++) a->nz += browlengths[i]; 17472593348eSBarry Smith 1748b6490206SBarry Smith /* read in nonzero values */ 1749b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr); 17500752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 175135aab85fSBarry Smith for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 1752b6490206SBarry Smith 1753b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1754b6490206SBarry Smith nzcount = 0; jcount = 0; 1755b6490206SBarry Smith for (i=0; i<mbs; i++) { 1756b6490206SBarry Smith nzcountb = nzcount; 175735aab85fSBarry Smith nmask = 0; 1758b6490206SBarry Smith for (j=0; j<bs; j++) { 1759b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1760b6490206SBarry Smith for (k=0; k<kmax; k++) { 176135aab85fSBarry Smith tmp = jj[nzcount++]/bs; 176235aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1763b6490206SBarry Smith } 1764b6490206SBarry Smith } 1765de6a44a3SBarry Smith /* sort the masked values */ 1766433994e6SBarry Smith ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 1767de6a44a3SBarry Smith 1768b6490206SBarry Smith /* set "j" values into matrix */ 1769b6490206SBarry Smith maskcount = 1; 177035aab85fSBarry Smith for (j=0; j<nmask; j++) { 177135aab85fSBarry Smith a->j[jcount++] = masked[j]; 1772de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1773b6490206SBarry Smith } 1774b6490206SBarry Smith /* set "a" values into matrix */ 1775de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1776b6490206SBarry Smith for (j=0; j<bs; j++) { 1777b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1778b6490206SBarry Smith for (k=0; k<kmax; k++) { 1779de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1780de6a44a3SBarry Smith block = mask[tmp] - 1; 1781de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1782de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1783375fe846SBarry Smith a->a[idx] = (MatScalar)aa[nzcountb++]; 1784b6490206SBarry Smith } 1785b6490206SBarry Smith } 178635aab85fSBarry Smith /* zero out the mask elements we set */ 178735aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1788b6490206SBarry Smith } 178929bbc08cSBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 1790b6490206SBarry Smith 1791606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 1792606d414cSSatish Balay ierr = PetscFree(browlengths);CHKERRQ(ierr); 1793606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 1794606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 1795606d414cSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 1796b6490206SBarry Smith 1797b6490206SBarry Smith B->assembled = PETSC_TRUE; 1798de6a44a3SBarry Smith 17999c01be13SBarry Smith ierr = MatView_Private(B);CHKERRQ(ierr); 18003a40ed3dSBarry Smith PetscFunctionReturn(0); 18012593348eSBarry Smith } 1802273d9f13SBarry Smith EXTERN_C_END 18032593348eSBarry Smith 18044a2ae208SSatish Balay #undef __FUNCT__ 18054a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ" 1806273d9f13SBarry Smith /*@C 1807273d9f13SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 1808273d9f13SBarry Smith compressed row) format. For good matrix assembly performance the 1809273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1810273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1811273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 18122593348eSBarry Smith 1813273d9f13SBarry Smith Collective on MPI_Comm 1814273d9f13SBarry Smith 1815273d9f13SBarry Smith Input Parameters: 1816273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 1817273d9f13SBarry Smith . bs - size of block 1818273d9f13SBarry Smith . m - number of rows 1819273d9f13SBarry Smith . n - number of columns 182035d8aa7fSBarry Smith . nz - number of nonzero blocks per block row (same for all rows) 182135d8aa7fSBarry Smith - nnz - array containing the number of nonzero blocks in the various block rows 1822273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1823273d9f13SBarry Smith 1824273d9f13SBarry Smith Output Parameter: 1825273d9f13SBarry Smith . A - the matrix 1826273d9f13SBarry Smith 1827273d9f13SBarry Smith Options Database Keys: 1828273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1829273d9f13SBarry Smith block calculations (much slower) 1830273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1831273d9f13SBarry Smith 1832273d9f13SBarry Smith Level: intermediate 1833273d9f13SBarry Smith 1834273d9f13SBarry Smith Notes: 183535d8aa7fSBarry Smith A nonzero block is any block that as 1 or more nonzeros in it 183635d8aa7fSBarry Smith 1837273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1838273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1839273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1840273d9f13SBarry Smith 1841273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1842273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1843273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1844273d9f13SBarry Smith matrices. 1845273d9f13SBarry Smith 1846273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1847273d9f13SBarry Smith @*/ 1848273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A) 1849273d9f13SBarry Smith { 1850273d9f13SBarry Smith int ierr; 1851273d9f13SBarry Smith 1852273d9f13SBarry Smith PetscFunctionBegin; 1853273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 1854273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr); 1855273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr); 1856273d9f13SBarry Smith PetscFunctionReturn(0); 1857273d9f13SBarry Smith } 1858273d9f13SBarry Smith 18594a2ae208SSatish Balay #undef __FUNCT__ 18604a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation" 1861273d9f13SBarry Smith /*@C 1862273d9f13SBarry Smith MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros 1863273d9f13SBarry Smith per row in the matrix. For good matrix assembly performance the 1864273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1865273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1866273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 1867273d9f13SBarry Smith 1868273d9f13SBarry Smith Collective on MPI_Comm 1869273d9f13SBarry Smith 1870273d9f13SBarry Smith Input Parameters: 1871273d9f13SBarry Smith + A - the matrix 1872273d9f13SBarry Smith . bs - size of block 1873273d9f13SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1874273d9f13SBarry Smith - nnz - array containing the number of block nonzeros in the various block rows 1875273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1876273d9f13SBarry Smith 1877273d9f13SBarry Smith Options Database Keys: 1878273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1879273d9f13SBarry Smith block calculations (much slower) 1880273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1881273d9f13SBarry Smith 1882273d9f13SBarry Smith Level: intermediate 1883273d9f13SBarry Smith 1884273d9f13SBarry Smith Notes: 1885273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1886273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1887273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1888273d9f13SBarry Smith 1889273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1890273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1891273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1892273d9f13SBarry Smith matrices. 1893273d9f13SBarry Smith 1894273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1895273d9f13SBarry Smith @*/ 1896273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz) 1897273d9f13SBarry Smith { 1898273d9f13SBarry Smith Mat_SeqBAIJ *b; 1899273d9f13SBarry Smith int i,len,ierr,mbs,nbs,bs2,newbs = bs; 1900273d9f13SBarry Smith PetscTruth flg; 1901273d9f13SBarry Smith 1902273d9f13SBarry Smith PetscFunctionBegin; 1903273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr); 1904273d9f13SBarry Smith if (!flg) PetscFunctionReturn(0); 1905273d9f13SBarry Smith 1906273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1907b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr); 1908273d9f13SBarry Smith if (nnz && newbs != bs) { 1909273d9f13SBarry Smith SETERRQ(1,"Cannot change blocksize from command line if setting nnz"); 1910273d9f13SBarry Smith } 1911273d9f13SBarry Smith bs = newbs; 1912273d9f13SBarry Smith 1913273d9f13SBarry Smith mbs = B->m/bs; 1914273d9f13SBarry Smith nbs = B->n/bs; 1915273d9f13SBarry Smith bs2 = bs*bs; 1916273d9f13SBarry Smith 1917273d9f13SBarry Smith if (mbs*bs!=B->m || nbs*bs!=B->n) { 191835d8aa7fSBarry Smith SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs); 1919273d9f13SBarry Smith } 1920273d9f13SBarry Smith 1921435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1922435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 1923273d9f13SBarry Smith if (nnz) { 1924273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1925273d9f13SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 19263a7fca6bSBarry Smith if (nnz[i] > nbs) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than block row length: local row %d value %d rowlength %d",i,nnz[i],nbs); 1927273d9f13SBarry Smith } 1928273d9f13SBarry Smith } 1929273d9f13SBarry Smith 1930273d9f13SBarry Smith b = (Mat_SeqBAIJ*)B->data; 1931b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr); 1932273d9f13SBarry Smith if (!flg) { 1933273d9f13SBarry Smith switch (bs) { 1934273d9f13SBarry Smith case 1: 1935273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1936273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1937273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_1; 1938273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1939273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 1940273d9f13SBarry Smith break; 1941273d9f13SBarry Smith case 2: 1942273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1943273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1944273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_2; 1945273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1946273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 1947273d9f13SBarry Smith break; 1948273d9f13SBarry Smith case 3: 1949273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1950273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1951273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_3; 1952273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1953273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 1954273d9f13SBarry Smith break; 1955273d9f13SBarry Smith case 4: 1956273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1957273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1958273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4; 1959273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1960273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 1961273d9f13SBarry Smith break; 1962273d9f13SBarry Smith case 5: 1963273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1964273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1965273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5; 1966273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1967273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 1968273d9f13SBarry Smith break; 1969273d9f13SBarry Smith case 6: 1970273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6; 1971273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_6; 1972273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6; 1973273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_6; 1974273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_6; 1975273d9f13SBarry Smith break; 1976273d9f13SBarry Smith case 7: 1977273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1978273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1979273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7; 1980273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 1981273d9f13SBarry Smith break; 1982273d9f13SBarry Smith default: 1983273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_N; 1984273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_N; 1985273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_N; 1986273d9f13SBarry Smith break; 1987273d9f13SBarry Smith } 1988273d9f13SBarry Smith } 1989273d9f13SBarry Smith b->bs = bs; 1990273d9f13SBarry Smith b->mbs = mbs; 1991273d9f13SBarry Smith b->nbs = nbs; 1992b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 1993273d9f13SBarry Smith if (!nnz) { 1994435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1995273d9f13SBarry Smith else if (nz <= 0) nz = 1; 1996273d9f13SBarry Smith for (i=0; i<mbs; i++) b->imax[i] = nz; 1997273d9f13SBarry Smith nz = nz*mbs; 1998273d9f13SBarry Smith } else { 1999273d9f13SBarry Smith nz = 0; 2000273d9f13SBarry Smith for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2001273d9f13SBarry Smith } 2002273d9f13SBarry Smith 2003273d9f13SBarry Smith /* allocate the matrix space */ 2004273d9f13SBarry Smith len = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int); 2005b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 2006273d9f13SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 2007273d9f13SBarry Smith b->j = (int*)(b->a + nz*bs2); 2008273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2009273d9f13SBarry Smith b->i = b->j + nz; 2010273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2011273d9f13SBarry Smith 2012273d9f13SBarry Smith b->i[0] = 0; 2013273d9f13SBarry Smith for (i=1; i<mbs+1; i++) { 2014273d9f13SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 2015273d9f13SBarry Smith } 2016273d9f13SBarry Smith 2017273d9f13SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 201816d6aa21SSatish Balay ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 2019b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 2020273d9f13SBarry Smith for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 2021273d9f13SBarry Smith 2022273d9f13SBarry Smith b->bs = bs; 2023273d9f13SBarry Smith b->bs2 = bs2; 2024273d9f13SBarry Smith b->mbs = mbs; 2025273d9f13SBarry Smith b->nz = 0; 2026273d9f13SBarry Smith b->maxnz = nz*bs2; 2027273d9f13SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 2028273d9f13SBarry Smith PetscFunctionReturn(0); 2029273d9f13SBarry Smith } 20302593348eSBarry Smith 2031