1*aa275fccSKris Buschelman /*$Id: baij.c,v 1.227 2001/06/21 21:16:41 bsmith 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; 176*aa275fccSKris Buschelman switch (op) { 177*aa275fccSKris Buschelman case MAT_ROW_ORIENTED: 178*aa275fccSKris Buschelman a->roworiented = PETSC_TRUE; 179*aa275fccSKris Buschelman break; 180*aa275fccSKris Buschelman case MAT_COLUMN_ORIENTED: 181*aa275fccSKris Buschelman a->roworiented = PETSC_FALSE; 182*aa275fccSKris Buschelman break; 183*aa275fccSKris Buschelman case MAT_COLUMNS_SORTED: 184*aa275fccSKris Buschelman a->sorted = PETSC_TRUE; 185*aa275fccSKris Buschelman break; 186*aa275fccSKris Buschelman case MAT_COLUMNS_UNSORTED: 187*aa275fccSKris Buschelman a->sorted = PETSC_FALSE; 188*aa275fccSKris Buschelman break; 189*aa275fccSKris Buschelman case MAT_KEEP_ZEROED_ROWS: 190*aa275fccSKris Buschelman a->keepzeroedrows = PETSC_TRUE; 191*aa275fccSKris Buschelman break; 192*aa275fccSKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 193*aa275fccSKris Buschelman a->nonew = 1; 194*aa275fccSKris Buschelman break; 195*aa275fccSKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 196*aa275fccSKris Buschelman a->nonew = -1; 197*aa275fccSKris Buschelman break; 198*aa275fccSKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 199*aa275fccSKris Buschelman a->nonew = -2; 200*aa275fccSKris Buschelman break; 201*aa275fccSKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 202*aa275fccSKris Buschelman a->nonew = 0; 203*aa275fccSKris Buschelman break; 204*aa275fccSKris Buschelman case MAT_ROWS_SORTED: 205*aa275fccSKris Buschelman case MAT_ROWS_UNSORTED: 206*aa275fccSKris Buschelman case MAT_YES_NEW_DIAGONALS: 207*aa275fccSKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 208*aa275fccSKris Buschelman case MAT_USE_HASH_TABLE: 209b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 210*aa275fccSKris Buschelman break; 211*aa275fccSKris Buschelman case MAT_NO_NEW_DIAGONALS: 21229bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 213*aa275fccSKris 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: 1202667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering; 1203f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 12047c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering; 1205b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n"); 120615091d37SBarry Smith break; 120715091d37SBarry Smith case 5: 1208667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering; 1209667159a5SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_5_NaturalOrdering; 12107c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering; 1211b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n"); 121215091d37SBarry Smith break; 121315091d37SBarry Smith case 6: 121415091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering; 121515091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_6_NaturalOrdering; 12167c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering; 1217b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n"); 121815091d37SBarry Smith break; 121915091d37SBarry Smith case 7: 122015091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering; 12217c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering; 122215091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_7_NaturalOrdering; 1223b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n"); 122415091d37SBarry Smith break; 1225c38d4ed2SBarry Smith default: 1226c38d4ed2SBarry Smith a->row = row; 1227c38d4ed2SBarry Smith a->col = col; 1228c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1229c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1230c38d4ed2SBarry Smith 1231c38d4ed2SBarry Smith /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 12324c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1233b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1234c38d4ed2SBarry Smith 1235c38d4ed2SBarry Smith if (!a->solve_work) { 1236b0a32e0cSBarry Smith ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr); 1237b0a32e0cSBarry Smith PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar)); 1238c38d4ed2SBarry Smith } 12392d61bbb3SSatish Balay } 12402d61bbb3SSatish Balay 1241667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr); 1242667159a5SBarry Smith 12432d61bbb3SSatish Balay PetscFunctionReturn(0); 12442d61bbb3SSatish Balay } 12454a2ae208SSatish Balay #undef __FUNCT__ 12464a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ" 1247ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1248ba4ca20aSSatish Balay { 1249c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1250ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1251d132466eSBarry Smith int ierr; 1252ba4ca20aSSatish Balay 12533a40ed3dSBarry Smith PetscFunctionBegin; 1254c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1255d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1256d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n");CHKERRQ(ierr); 12573a40ed3dSBarry Smith PetscFunctionReturn(0); 1258ba4ca20aSSatish Balay } 1259d9b7c43dSSatish Balay 1260fb2e594dSBarry Smith EXTERN_C_BEGIN 12614a2ae208SSatish Balay #undef __FUNCT__ 12624a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 126327a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 126427a8da17SBarry Smith { 126527a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 126627a8da17SBarry Smith int i,nz,n; 126727a8da17SBarry Smith 126827a8da17SBarry Smith PetscFunctionBegin; 126927a8da17SBarry Smith nz = baij->maxnz; 1270273d9f13SBarry Smith n = mat->n; 127127a8da17SBarry Smith for (i=0; i<nz; i++) { 127227a8da17SBarry Smith baij->j[i] = indices[i]; 127327a8da17SBarry Smith } 127427a8da17SBarry Smith baij->nz = nz; 127527a8da17SBarry Smith for (i=0; i<n; i++) { 127627a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 127727a8da17SBarry Smith } 127827a8da17SBarry Smith 127927a8da17SBarry Smith PetscFunctionReturn(0); 128027a8da17SBarry Smith } 1281fb2e594dSBarry Smith EXTERN_C_END 128227a8da17SBarry Smith 12834a2ae208SSatish Balay #undef __FUNCT__ 12844a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices" 128527a8da17SBarry Smith /*@ 128627a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 128727a8da17SBarry Smith in the matrix. 128827a8da17SBarry Smith 128927a8da17SBarry Smith Input Parameters: 129027a8da17SBarry Smith + mat - the SeqBAIJ matrix 129127a8da17SBarry Smith - indices - the column indices 129227a8da17SBarry Smith 129315091d37SBarry Smith Level: advanced 129415091d37SBarry Smith 129527a8da17SBarry Smith Notes: 129627a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 129727a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 129827a8da17SBarry Smith of the MatSetValues() operation. 129927a8da17SBarry Smith 130027a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 130127a8da17SBarry Smith MatCreateSeqBAIJ(). 130227a8da17SBarry Smith 130327a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 130427a8da17SBarry Smith 130527a8da17SBarry Smith @*/ 130627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 130727a8da17SBarry Smith { 130827a8da17SBarry Smith int ierr,(*f)(Mat,int *); 130927a8da17SBarry Smith 131027a8da17SBarry Smith PetscFunctionBegin; 131127a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1312b9617806SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr); 131327a8da17SBarry Smith if (f) { 131427a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 131527a8da17SBarry Smith } else { 131629bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 131727a8da17SBarry Smith } 131827a8da17SBarry Smith PetscFunctionReturn(0); 131927a8da17SBarry Smith } 132027a8da17SBarry Smith 13214a2ae208SSatish Balay #undef __FUNCT__ 13224a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ" 1323273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v) 1324273d9f13SBarry Smith { 1325273d9f13SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1326273d9f13SBarry Smith int ierr,i,j,n,row,bs,*ai,*aj,mbs; 1327273d9f13SBarry Smith PetscReal atmp; 1328273d9f13SBarry Smith Scalar *x,zero = 0.0; 1329273d9f13SBarry Smith MatScalar *aa; 1330273d9f13SBarry Smith int ncols,brow,krow,kcol; 1331273d9f13SBarry Smith 1332273d9f13SBarry Smith PetscFunctionBegin; 1333273d9f13SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1334273d9f13SBarry Smith bs = a->bs; 1335273d9f13SBarry Smith aa = a->a; 1336273d9f13SBarry Smith ai = a->i; 1337273d9f13SBarry Smith aj = a->j; 1338273d9f13SBarry Smith mbs = a->mbs; 1339273d9f13SBarry Smith 1340273d9f13SBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 1341273d9f13SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1342273d9f13SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1343273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1344273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1345273d9f13SBarry Smith ncols = ai[1] - ai[0]; ai++; 1346273d9f13SBarry Smith brow = bs*i; 1347273d9f13SBarry Smith for (j=0; j<ncols; j++){ 1348273d9f13SBarry Smith /* bcol = bs*(*aj); */ 1349273d9f13SBarry Smith for (kcol=0; kcol<bs; kcol++){ 1350273d9f13SBarry Smith for (krow=0; krow<bs; krow++){ 1351273d9f13SBarry Smith atmp = PetscAbsScalar(*aa); aa++; 1352273d9f13SBarry Smith row = brow + krow; /* row index */ 1353273d9f13SBarry Smith /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */ 1354273d9f13SBarry Smith if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp; 1355273d9f13SBarry Smith } 1356273d9f13SBarry Smith } 1357273d9f13SBarry Smith aj++; 1358273d9f13SBarry Smith } 1359273d9f13SBarry Smith } 1360273d9f13SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1361273d9f13SBarry Smith PetscFunctionReturn(0); 1362273d9f13SBarry Smith } 1363273d9f13SBarry Smith 13644a2ae208SSatish Balay #undef __FUNCT__ 13654a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ" 1366273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A) 1367273d9f13SBarry Smith { 1368273d9f13SBarry Smith int ierr; 1369273d9f13SBarry Smith 1370273d9f13SBarry Smith PetscFunctionBegin; 1371273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr); 1372273d9f13SBarry Smith PetscFunctionReturn(0); 1373273d9f13SBarry Smith } 1374273d9f13SBarry Smith 13754a2ae208SSatish Balay #undef __FUNCT__ 13764a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ" 1377f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array) 1378f2a5309cSSatish Balay { 1379f2a5309cSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1380f2a5309cSSatish Balay PetscFunctionBegin; 1381f2a5309cSSatish Balay *array = a->a; 1382f2a5309cSSatish Balay PetscFunctionReturn(0); 1383f2a5309cSSatish Balay } 1384f2a5309cSSatish Balay 13854a2ae208SSatish Balay #undef __FUNCT__ 13864a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ" 1387f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array) 1388f2a5309cSSatish Balay { 1389f2a5309cSSatish Balay PetscFunctionBegin; 1390f2a5309cSSatish Balay PetscFunctionReturn(0); 1391f2a5309cSSatish Balay } 1392f2a5309cSSatish Balay 13932593348eSBarry Smith /* -------------------------------------------------------------------*/ 1394cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1395cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1396cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1397cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1398cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 13997c922b88SBarry Smith MatMultTranspose_SeqBAIJ, 14007c922b88SBarry Smith MatMultTransposeAdd_SeqBAIJ, 1401cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1402cc2dc46cSBarry Smith 0, 1403cc2dc46cSBarry Smith 0, 1404cc2dc46cSBarry Smith 0, 1405cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1406cc2dc46cSBarry Smith 0, 1407b6490206SBarry Smith 0, 1408f2501298SSatish Balay MatTranspose_SeqBAIJ, 1409cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1410cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1411cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1412cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1413cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1414b6490206SBarry Smith 0, 1415cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1416cc2dc46cSBarry Smith 0, 1417cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1418cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1419cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1420cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1421cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1422cc2dc46cSBarry Smith 0, 1423cc2dc46cSBarry Smith 0, 1424273d9f13SBarry Smith MatSetUpPreallocation_SeqBAIJ, 1425273d9f13SBarry Smith 0, 1426cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1427cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1428cc2dc46cSBarry Smith 0, 1429f2a5309cSSatish Balay MatGetArray_SeqBAIJ, 1430f2a5309cSSatish Balay MatRestoreArray_SeqBAIJ, 14312e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1432cc2dc46cSBarry Smith 0, 1433cc2dc46cSBarry Smith 0, 1434cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1435cc2dc46cSBarry Smith 0, 1436cc2dc46cSBarry Smith 0, 1437cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1438cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1439cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1440cc2dc46cSBarry Smith 0, 1441cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1442cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1443cc2dc46cSBarry Smith 0, 1444cc2dc46cSBarry Smith 0, 1445cc2dc46cSBarry Smith 0, 1446cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 14473b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 144892c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1449cc2dc46cSBarry Smith 0, 1450cc2dc46cSBarry Smith 0, 1451cc2dc46cSBarry Smith 0, 1452cc2dc46cSBarry Smith 0, 1453cc2dc46cSBarry Smith 0, 1454cc2dc46cSBarry Smith 0, 1455d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1456cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1457b9b97703SBarry Smith MatDestroy_SeqBAIJ, 1458b9b97703SBarry Smith MatView_SeqBAIJ, 1459273d9f13SBarry Smith MatGetMaps_Petsc, 1460273d9f13SBarry Smith 0, 1461273d9f13SBarry Smith 0, 1462273d9f13SBarry Smith 0, 1463273d9f13SBarry Smith 0, 1464273d9f13SBarry Smith 0, 1465273d9f13SBarry Smith 0, 1466273d9f13SBarry Smith MatGetRowMax_SeqBAIJ, 1467273d9f13SBarry Smith MatConvert_Basic}; 14682593348eSBarry Smith 14693e90b805SBarry Smith EXTERN_C_BEGIN 14704a2ae208SSatish Balay #undef __FUNCT__ 14714a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ" 14723e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat) 14733e90b805SBarry Smith { 14743e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1475273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2; 1476d132466eSBarry Smith int ierr; 14773e90b805SBarry Smith 14783e90b805SBarry Smith PetscFunctionBegin; 14793e90b805SBarry Smith if (aij->nonew != 1) { 148029bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14813e90b805SBarry Smith } 14823e90b805SBarry Smith 14833e90b805SBarry Smith /* allocate space for values if not already there */ 14843e90b805SBarry Smith if (!aij->saved_values) { 1485f2a5309cSSatish Balay ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr); 14863e90b805SBarry Smith } 14873e90b805SBarry Smith 14883e90b805SBarry Smith /* copy values over */ 1489d132466eSBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr); 14903e90b805SBarry Smith PetscFunctionReturn(0); 14913e90b805SBarry Smith } 14923e90b805SBarry Smith EXTERN_C_END 14933e90b805SBarry Smith 14943e90b805SBarry Smith EXTERN_C_BEGIN 14954a2ae208SSatish Balay #undef __FUNCT__ 14964a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ" 149732e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat) 14983e90b805SBarry Smith { 14993e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1500273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr; 15013e90b805SBarry Smith 15023e90b805SBarry Smith PetscFunctionBegin; 15033e90b805SBarry Smith if (aij->nonew != 1) { 150429bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 15053e90b805SBarry Smith } 15063e90b805SBarry Smith if (!aij->saved_values) { 150729bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 15083e90b805SBarry Smith } 15093e90b805SBarry Smith 15103e90b805SBarry Smith /* copy values over */ 1511549d3d68SSatish Balay ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr); 15123e90b805SBarry Smith PetscFunctionReturn(0); 15133e90b805SBarry Smith } 15143e90b805SBarry Smith EXTERN_C_END 15153e90b805SBarry Smith 1516273d9f13SBarry Smith EXTERN_C_BEGIN 1517273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*); 1518273d9f13SBarry Smith EXTERN_C_END 1519273d9f13SBarry Smith 1520273d9f13SBarry Smith EXTERN_C_BEGIN 15214a2ae208SSatish Balay #undef __FUNCT__ 15224a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ" 1523273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B) 15242593348eSBarry Smith { 1525273d9f13SBarry Smith int ierr,size; 1526b6490206SBarry Smith Mat_SeqBAIJ *b; 15273b2fbd54SBarry Smith 15283a40ed3dSBarry Smith PetscFunctionBegin; 1529273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 153029bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1531b6490206SBarry Smith 1532273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 1533273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 1534b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr); 1535b0a32e0cSBarry Smith B->data = (void*)b; 1536549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr); 1537549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 15382593348eSBarry Smith B->factor = 0; 15392593348eSBarry Smith B->lupivotthreshold = 1.0; 154090f02eecSBarry Smith B->mapping = 0; 15412593348eSBarry Smith b->row = 0; 15422593348eSBarry Smith b->col = 0; 1543e51c0b9cSSatish Balay b->icol = 0; 15442593348eSBarry Smith b->reallocs = 0; 15453e90b805SBarry Smith b->saved_values = 0; 1546cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 1547563b5814SBarry Smith b->setvalueslen = 0; 1548563b5814SBarry Smith b->setvaluescopy = PETSC_NULL; 1549563b5814SBarry Smith #endif 15502593348eSBarry Smith 1551273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 1552273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 1553a5ae1ecdSBarry Smith 1554c4992f7dSBarry Smith b->sorted = PETSC_FALSE; 1555c4992f7dSBarry Smith b->roworiented = PETSC_TRUE; 15562593348eSBarry Smith b->nonew = 0; 15572593348eSBarry Smith b->diag = 0; 15582593348eSBarry Smith b->solve_work = 0; 1559de6a44a3SBarry Smith b->mult_work = 0; 15602593348eSBarry Smith b->spptr = 0; 15610e6d2581SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1562883fce79SBarry Smith b->keepzeroedrows = PETSC_FALSE; 15634e220ebcSLois Curfman McInnes 1564f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 15653e90b805SBarry Smith "MatStoreValues_SeqBAIJ", 1566bc4b532fSSatish Balay MatStoreValues_SeqBAIJ);CHKERRQ(ierr); 1567f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 15683e90b805SBarry Smith "MatRetrieveValues_SeqBAIJ", 1569bc4b532fSSatish Balay MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr); 1570f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 157127a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 1572bc4b532fSSatish Balay MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 1573273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C", 1574273d9f13SBarry Smith "MatConvert_SeqBAIJ_SeqAIJ", 1575273d9f13SBarry Smith MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr); 15763a40ed3dSBarry Smith PetscFunctionReturn(0); 15772593348eSBarry Smith } 1578273d9f13SBarry Smith EXTERN_C_END 15792593348eSBarry Smith 15804a2ae208SSatish Balay #undef __FUNCT__ 15814a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ" 15822e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 15832593348eSBarry Smith { 15842593348eSBarry Smith Mat C; 1585b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data; 158627a8da17SBarry Smith int i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1587de6a44a3SBarry Smith 15883a40ed3dSBarry Smith PetscFunctionBegin; 158929bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 15902593348eSBarry Smith 15912593348eSBarry Smith *B = 0; 1592273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 1593273d9f13SBarry Smith ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr); 1594273d9f13SBarry Smith c = (Mat_SeqBAIJ*)C->data; 159544cd7ae7SLois Curfman McInnes 1596b6490206SBarry Smith c->bs = a->bs; 15979df24120SSatish Balay c->bs2 = a->bs2; 1598b6490206SBarry Smith c->mbs = a->mbs; 1599b6490206SBarry Smith c->nbs = a->nbs; 160035d8aa7fSBarry Smith ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 16012593348eSBarry Smith 1602b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 1603b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 1604b6490206SBarry Smith for (i=0; i<mbs; i++) { 16052593348eSBarry Smith c->imax[i] = a->imax[i]; 16062593348eSBarry Smith c->ilen[i] = a->ilen[i]; 16072593348eSBarry Smith } 16082593348eSBarry Smith 16092593348eSBarry Smith /* allocate the matrix space */ 1610c4992f7dSBarry Smith c->singlemalloc = PETSC_TRUE; 16113f1db9ecSBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int)); 1612b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 16137e67e3f9SSatish Balay c->j = (int*)(c->a + nz*bs2); 1614de6a44a3SBarry Smith c->i = c->j + nz; 1615549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr); 1616b6490206SBarry Smith if (mbs > 0) { 1617549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr); 16182e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 1619549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16202e8a6d31SBarry Smith } else { 1621549d3d68SSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16222593348eSBarry Smith } 16232593348eSBarry Smith } 16242593348eSBarry Smith 1625b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 16262593348eSBarry Smith c->sorted = a->sorted; 16272593348eSBarry Smith c->roworiented = a->roworiented; 16282593348eSBarry Smith c->nonew = a->nonew; 16292593348eSBarry Smith 16302593348eSBarry Smith if (a->diag) { 1631b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 1632b0a32e0cSBarry Smith PetscLogObjectMemory(C,(mbs+1)*sizeof(int)); 1633b6490206SBarry Smith for (i=0; i<mbs; i++) { 16342593348eSBarry Smith c->diag[i] = a->diag[i]; 16352593348eSBarry Smith } 163698305bb5SBarry Smith } else c->diag = 0; 16372593348eSBarry Smith c->nz = a->nz; 16382593348eSBarry Smith c->maxnz = a->maxnz; 16392593348eSBarry Smith c->solve_work = 0; 16402593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 16417fc0212eSBarry Smith c->mult_work = 0; 1642273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 1643273d9f13SBarry Smith C->assembled = PETSC_TRUE; 16442593348eSBarry Smith *B = C; 1645b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 16463a40ed3dSBarry Smith PetscFunctionReturn(0); 16472593348eSBarry Smith } 16482593348eSBarry Smith 1649273d9f13SBarry Smith EXTERN_C_BEGIN 16504a2ae208SSatish Balay #undef __FUNCT__ 16514a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ" 1652b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A) 16532593348eSBarry Smith { 1654b6490206SBarry Smith Mat_SeqBAIJ *a; 16552593348eSBarry Smith Mat B; 1656f1af5d2fSBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1; 1657b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 165835aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1659a7c10996SSatish Balay int *masked,nmask,tmp,bs2,ishift; 1660b6490206SBarry Smith Scalar *aa; 166119bcc07fSBarry Smith MPI_Comm comm = ((PetscObject)viewer)->comm; 16622593348eSBarry Smith 16633a40ed3dSBarry Smith PetscFunctionBegin; 1664b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 1665de6a44a3SBarry Smith bs2 = bs*bs; 1666b6490206SBarry Smith 1667d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 166829bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 1669b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 16700752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 167129bbc08cSBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 16722593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 16732593348eSBarry Smith 1674d64ed03dSBarry Smith if (header[3] < 0) { 167529bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ"); 1676d64ed03dSBarry Smith } 1677d64ed03dSBarry Smith 167829bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 167935aab85fSBarry Smith 168035aab85fSBarry Smith /* 168135aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 168235aab85fSBarry Smith divisible by the blocksize 168335aab85fSBarry Smith */ 1684b6490206SBarry Smith mbs = M/bs; 168535aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 168635aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 168735aab85fSBarry Smith else mbs++; 168835aab85fSBarry Smith if (extra_rows) { 1689b0a32e0cSBarry Smith PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 169035aab85fSBarry Smith } 1691b6490206SBarry Smith 16922593348eSBarry Smith /* read in row lengths */ 1693b0a32e0cSBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr); 16940752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 169535aab85fSBarry Smith for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 16962593348eSBarry Smith 1697b6490206SBarry Smith /* read in column indices */ 1698b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr); 16990752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 170035aab85fSBarry Smith for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 1701b6490206SBarry Smith 1702b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1703b0a32e0cSBarry Smith ierr = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr); 1704549d3d68SSatish Balay ierr = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr); 1705b0a32e0cSBarry Smith ierr = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr); 1706549d3d68SSatish Balay ierr = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr); 170735aab85fSBarry Smith masked = mask + mbs; 1708b6490206SBarry Smith rowcount = 0; nzcount = 0; 1709b6490206SBarry Smith for (i=0; i<mbs; i++) { 171035aab85fSBarry Smith nmask = 0; 1711b6490206SBarry Smith for (j=0; j<bs; j++) { 1712b6490206SBarry Smith kmax = rowlengths[rowcount]; 1713b6490206SBarry Smith for (k=0; k<kmax; k++) { 171435aab85fSBarry Smith tmp = jj[nzcount++]/bs; 171535aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1716b6490206SBarry Smith } 1717b6490206SBarry Smith rowcount++; 1718b6490206SBarry Smith } 171935aab85fSBarry Smith browlengths[i] += nmask; 172035aab85fSBarry Smith /* zero out the mask elements we set */ 172135aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1722b6490206SBarry Smith } 1723b6490206SBarry Smith 17242593348eSBarry Smith /* create our matrix */ 17253eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 17262593348eSBarry Smith B = *A; 1727b6490206SBarry Smith a = (Mat_SeqBAIJ*)B->data; 17282593348eSBarry Smith 17292593348eSBarry Smith /* set matrix "i" values */ 1730de6a44a3SBarry Smith a->i[0] = 0; 1731b6490206SBarry Smith for (i=1; i<= mbs; i++) { 1732b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1733b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 17342593348eSBarry Smith } 1735b6490206SBarry Smith a->nz = 0; 1736b6490206SBarry Smith for (i=0; i<mbs; i++) a->nz += browlengths[i]; 17372593348eSBarry Smith 1738b6490206SBarry Smith /* read in nonzero values */ 1739b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr); 17400752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 174135aab85fSBarry Smith for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 1742b6490206SBarry Smith 1743b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1744b6490206SBarry Smith nzcount = 0; jcount = 0; 1745b6490206SBarry Smith for (i=0; i<mbs; i++) { 1746b6490206SBarry Smith nzcountb = nzcount; 174735aab85fSBarry Smith nmask = 0; 1748b6490206SBarry Smith for (j=0; j<bs; j++) { 1749b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1750b6490206SBarry Smith for (k=0; k<kmax; k++) { 175135aab85fSBarry Smith tmp = jj[nzcount++]/bs; 175235aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1753b6490206SBarry Smith } 1754b6490206SBarry Smith } 1755de6a44a3SBarry Smith /* sort the masked values */ 1756433994e6SBarry Smith ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 1757de6a44a3SBarry Smith 1758b6490206SBarry Smith /* set "j" values into matrix */ 1759b6490206SBarry Smith maskcount = 1; 176035aab85fSBarry Smith for (j=0; j<nmask; j++) { 176135aab85fSBarry Smith a->j[jcount++] = masked[j]; 1762de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1763b6490206SBarry Smith } 1764b6490206SBarry Smith /* set "a" values into matrix */ 1765de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1766b6490206SBarry Smith for (j=0; j<bs; j++) { 1767b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1768b6490206SBarry Smith for (k=0; k<kmax; k++) { 1769de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1770de6a44a3SBarry Smith block = mask[tmp] - 1; 1771de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1772de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1773375fe846SBarry Smith a->a[idx] = (MatScalar)aa[nzcountb++]; 1774b6490206SBarry Smith } 1775b6490206SBarry Smith } 177635aab85fSBarry Smith /* zero out the mask elements we set */ 177735aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1778b6490206SBarry Smith } 177929bbc08cSBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 1780b6490206SBarry Smith 1781606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 1782606d414cSSatish Balay ierr = PetscFree(browlengths);CHKERRQ(ierr); 1783606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 1784606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 1785606d414cSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 1786b6490206SBarry Smith 1787b6490206SBarry Smith B->assembled = PETSC_TRUE; 1788de6a44a3SBarry Smith 17899c01be13SBarry Smith ierr = MatView_Private(B);CHKERRQ(ierr); 17903a40ed3dSBarry Smith PetscFunctionReturn(0); 17912593348eSBarry Smith } 1792273d9f13SBarry Smith EXTERN_C_END 17932593348eSBarry Smith 17944a2ae208SSatish Balay #undef __FUNCT__ 17954a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ" 1796273d9f13SBarry Smith /*@C 1797273d9f13SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 1798273d9f13SBarry Smith compressed row) format. For good matrix assembly performance the 1799273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1800273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1801273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 18022593348eSBarry Smith 1803273d9f13SBarry Smith Collective on MPI_Comm 1804273d9f13SBarry Smith 1805273d9f13SBarry Smith Input Parameters: 1806273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 1807273d9f13SBarry Smith . bs - size of block 1808273d9f13SBarry Smith . m - number of rows 1809273d9f13SBarry Smith . n - number of columns 181035d8aa7fSBarry Smith . nz - number of nonzero blocks per block row (same for all rows) 181135d8aa7fSBarry Smith - nnz - array containing the number of nonzero blocks in the various block rows 1812273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1813273d9f13SBarry Smith 1814273d9f13SBarry Smith Output Parameter: 1815273d9f13SBarry Smith . A - the matrix 1816273d9f13SBarry Smith 1817273d9f13SBarry Smith Options Database Keys: 1818273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1819273d9f13SBarry Smith block calculations (much slower) 1820273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1821273d9f13SBarry Smith 1822273d9f13SBarry Smith Level: intermediate 1823273d9f13SBarry Smith 1824273d9f13SBarry Smith Notes: 182535d8aa7fSBarry Smith A nonzero block is any block that as 1 or more nonzeros in it 182635d8aa7fSBarry Smith 1827273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1828273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1829273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1830273d9f13SBarry Smith 1831273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1832273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1833273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1834273d9f13SBarry Smith matrices. 1835273d9f13SBarry Smith 1836273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1837273d9f13SBarry Smith @*/ 1838273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A) 1839273d9f13SBarry Smith { 1840273d9f13SBarry Smith int ierr; 1841273d9f13SBarry Smith 1842273d9f13SBarry Smith PetscFunctionBegin; 1843273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 1844273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr); 1845273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr); 1846273d9f13SBarry Smith PetscFunctionReturn(0); 1847273d9f13SBarry Smith } 1848273d9f13SBarry Smith 18494a2ae208SSatish Balay #undef __FUNCT__ 18504a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation" 1851273d9f13SBarry Smith /*@C 1852273d9f13SBarry Smith MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros 1853273d9f13SBarry Smith per row in the matrix. For good matrix assembly performance the 1854273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1855273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1856273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 1857273d9f13SBarry Smith 1858273d9f13SBarry Smith Collective on MPI_Comm 1859273d9f13SBarry Smith 1860273d9f13SBarry Smith Input Parameters: 1861273d9f13SBarry Smith + A - the matrix 1862273d9f13SBarry Smith . bs - size of block 1863273d9f13SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1864273d9f13SBarry Smith - nnz - array containing the number of block nonzeros in the various block rows 1865273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1866273d9f13SBarry Smith 1867273d9f13SBarry Smith Options Database Keys: 1868273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1869273d9f13SBarry Smith block calculations (much slower) 1870273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1871273d9f13SBarry Smith 1872273d9f13SBarry Smith Level: intermediate 1873273d9f13SBarry Smith 1874273d9f13SBarry Smith Notes: 1875273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1876273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1877273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1878273d9f13SBarry Smith 1879273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1880273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1881273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1882273d9f13SBarry Smith matrices. 1883273d9f13SBarry Smith 1884273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1885273d9f13SBarry Smith @*/ 1886273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz) 1887273d9f13SBarry Smith { 1888273d9f13SBarry Smith Mat_SeqBAIJ *b; 1889273d9f13SBarry Smith int i,len,ierr,mbs,nbs,bs2,newbs = bs; 1890273d9f13SBarry Smith PetscTruth flg; 1891273d9f13SBarry Smith 1892273d9f13SBarry Smith PetscFunctionBegin; 1893273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr); 1894273d9f13SBarry Smith if (!flg) PetscFunctionReturn(0); 1895273d9f13SBarry Smith 1896273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1897b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr); 1898273d9f13SBarry Smith if (nnz && newbs != bs) { 1899273d9f13SBarry Smith SETERRQ(1,"Cannot change blocksize from command line if setting nnz"); 1900273d9f13SBarry Smith } 1901273d9f13SBarry Smith bs = newbs; 1902273d9f13SBarry Smith 1903273d9f13SBarry Smith mbs = B->m/bs; 1904273d9f13SBarry Smith nbs = B->n/bs; 1905273d9f13SBarry Smith bs2 = bs*bs; 1906273d9f13SBarry Smith 1907273d9f13SBarry Smith if (mbs*bs!=B->m || nbs*bs!=B->n) { 190835d8aa7fSBarry Smith SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs); 1909273d9f13SBarry Smith } 1910273d9f13SBarry Smith 1911435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1912435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 1913273d9f13SBarry Smith if (nnz) { 1914273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1915273d9f13SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 19163a7fca6bSBarry 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); 1917273d9f13SBarry Smith } 1918273d9f13SBarry Smith } 1919273d9f13SBarry Smith 1920273d9f13SBarry Smith b = (Mat_SeqBAIJ*)B->data; 1921b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr); 1922273d9f13SBarry Smith if (!flg) { 1923273d9f13SBarry Smith switch (bs) { 1924273d9f13SBarry Smith case 1: 1925273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1926273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1927273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_1; 1928273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1929273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 1930273d9f13SBarry Smith break; 1931273d9f13SBarry Smith case 2: 1932273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1933273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1934273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_2; 1935273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1936273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 1937273d9f13SBarry Smith break; 1938273d9f13SBarry Smith case 3: 1939273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1940273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1941273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_3; 1942273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1943273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 1944273d9f13SBarry Smith break; 1945273d9f13SBarry Smith case 4: 1946273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1947273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1948273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4; 1949273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1950273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 1951273d9f13SBarry Smith break; 1952273d9f13SBarry Smith case 5: 1953273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1954273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1955273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5; 1956273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1957273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 1958273d9f13SBarry Smith break; 1959273d9f13SBarry Smith case 6: 1960273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6; 1961273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_6; 1962273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6; 1963273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_6; 1964273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_6; 1965273d9f13SBarry Smith break; 1966273d9f13SBarry Smith case 7: 1967273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1968273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1969273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7; 1970273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 1971273d9f13SBarry Smith break; 1972273d9f13SBarry Smith default: 1973273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_N; 1974273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_N; 1975273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_N; 1976273d9f13SBarry Smith break; 1977273d9f13SBarry Smith } 1978273d9f13SBarry Smith } 1979273d9f13SBarry Smith b->bs = bs; 1980273d9f13SBarry Smith b->mbs = mbs; 1981273d9f13SBarry Smith b->nbs = nbs; 1982b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 1983273d9f13SBarry Smith if (!nnz) { 1984435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1985273d9f13SBarry Smith else if (nz <= 0) nz = 1; 1986273d9f13SBarry Smith for (i=0; i<mbs; i++) b->imax[i] = nz; 1987273d9f13SBarry Smith nz = nz*mbs; 1988273d9f13SBarry Smith } else { 1989273d9f13SBarry Smith nz = 0; 1990273d9f13SBarry Smith for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 1991273d9f13SBarry Smith } 1992273d9f13SBarry Smith 1993273d9f13SBarry Smith /* allocate the matrix space */ 1994273d9f13SBarry Smith len = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int); 1995b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 1996273d9f13SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1997273d9f13SBarry Smith b->j = (int*)(b->a + nz*bs2); 1998273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 1999273d9f13SBarry Smith b->i = b->j + nz; 2000273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2001273d9f13SBarry Smith 2002273d9f13SBarry Smith b->i[0] = 0; 2003273d9f13SBarry Smith for (i=1; i<mbs+1; i++) { 2004273d9f13SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 2005273d9f13SBarry Smith } 2006273d9f13SBarry Smith 2007273d9f13SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 200816d6aa21SSatish Balay ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 2009b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 2010273d9f13SBarry Smith for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 2011273d9f13SBarry Smith 2012273d9f13SBarry Smith b->bs = bs; 2013273d9f13SBarry Smith b->bs2 = bs2; 2014273d9f13SBarry Smith b->mbs = mbs; 2015273d9f13SBarry Smith b->nz = 0; 2016273d9f13SBarry Smith b->maxnz = nz*bs2; 2017273d9f13SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 2018273d9f13SBarry Smith PetscFunctionReturn(0); 2019273d9f13SBarry Smith } 20202593348eSBarry Smith 2021