1*3a7fca6bSBarry Smith /*$Id: baij.c,v 1.226 2001/05/31 22:25:50 balay Exp bsmith $*/ 22593348eSBarry Smith 32593348eSBarry Smith /* 4b6490206SBarry Smith Defines the basic matrix operations for the BAIJ (compressed row) 52593348eSBarry Smith matrix storage format. 62593348eSBarry Smith */ 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; 176c4992f7dSBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = PETSC_TRUE; 177c4992f7dSBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = PETSC_FALSE; 178c4992f7dSBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = PETSC_TRUE; 179c4992f7dSBarry Smith else if (op == MAT_COLUMNS_UNSORTED) a->sorted = PETSC_FALSE; 180c4992f7dSBarry Smith else if (op == MAT_KEEP_ZEROED_ROWS) a->keepzeroedrows = PETSC_TRUE; 1812d61bbb3SSatish Balay else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 1824787f768SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERR) a->nonew = -1; 1834787f768SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR) a->nonew = -2; 1842d61bbb3SSatish Balay else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 1852d61bbb3SSatish Balay else if (op == MAT_ROWS_SORTED || 1862d61bbb3SSatish Balay op == MAT_ROWS_UNSORTED || 1872d61bbb3SSatish Balay op == MAT_YES_NEW_DIAGONALS || 188b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES || 189b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) { 190b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 1912d61bbb3SSatish Balay } else if (op == MAT_NO_NEW_DIAGONALS) { 19229bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 1932d61bbb3SSatish Balay } else { 19429bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"unknown option"); 1952d61bbb3SSatish Balay } 1962d61bbb3SSatish Balay PetscFunctionReturn(0); 1972d61bbb3SSatish Balay } 1982d61bbb3SSatish Balay 1994a2ae208SSatish Balay #undef __FUNCT__ 2004a2ae208SSatish Balay #define __FUNCT__ "MatGetOwnershipRange_SeqBAIJ" 2012d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 2022d61bbb3SSatish Balay { 2032d61bbb3SSatish Balay PetscFunctionBegin; 2044c49b128SBarry Smith if (m) *m = 0; 205273d9f13SBarry Smith if (n) *n = A->m; 2062d61bbb3SSatish Balay PetscFunctionReturn(0); 2072d61bbb3SSatish Balay } 2082d61bbb3SSatish Balay 2094a2ae208SSatish Balay #undef __FUNCT__ 2104a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ" 2112d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2122d61bbb3SSatish Balay { 2132d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 21482502324SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr; 2153f1db9ecSBarry Smith MatScalar *aa,*aa_i; 2163f1db9ecSBarry Smith Scalar *v_i; 2172d61bbb3SSatish Balay 2182d61bbb3SSatish Balay PetscFunctionBegin; 2192d61bbb3SSatish Balay bs = a->bs; 2202d61bbb3SSatish Balay ai = a->i; 2212d61bbb3SSatish Balay aj = a->j; 2222d61bbb3SSatish Balay aa = a->a; 2232d61bbb3SSatish Balay bs2 = a->bs2; 2242d61bbb3SSatish Balay 225273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range"); 2262d61bbb3SSatish Balay 2272d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2282d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2292d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2302d61bbb3SSatish Balay *nz = bs*M; 2312d61bbb3SSatish Balay 2322d61bbb3SSatish Balay if (v) { 2332d61bbb3SSatish Balay *v = 0; 2342d61bbb3SSatish Balay if (*nz) { 235b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr); 2362d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2372d61bbb3SSatish Balay v_i = *v + i*bs; 2382d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2392d61bbb3SSatish Balay for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];} 2402d61bbb3SSatish Balay } 2412d61bbb3SSatish Balay } 2422d61bbb3SSatish Balay } 2432d61bbb3SSatish Balay 2442d61bbb3SSatish Balay if (idx) { 2452d61bbb3SSatish Balay *idx = 0; 2462d61bbb3SSatish Balay if (*nz) { 247b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr); 2482d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2492d61bbb3SSatish Balay idx_i = *idx + i*bs; 2502d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2512d61bbb3SSatish Balay for (j=0; j<bs; j++) {idx_i[j] = itmp++;} 2522d61bbb3SSatish Balay } 2532d61bbb3SSatish Balay } 2542d61bbb3SSatish Balay } 2552d61bbb3SSatish Balay PetscFunctionReturn(0); 2562d61bbb3SSatish Balay } 2572d61bbb3SSatish Balay 2584a2ae208SSatish Balay #undef __FUNCT__ 2594a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ" 2602d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 2612d61bbb3SSatish Balay { 262606d414cSSatish Balay int ierr; 263606d414cSSatish Balay 2642d61bbb3SSatish Balay PetscFunctionBegin; 265606d414cSSatish Balay if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 266606d414cSSatish Balay if (v) {if (*v) {ierr = PetscFree(*v);CHKERRQ(ierr);}} 2672d61bbb3SSatish Balay PetscFunctionReturn(0); 2682d61bbb3SSatish Balay } 2692d61bbb3SSatish Balay 2704a2ae208SSatish Balay #undef __FUNCT__ 2714a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ" 2722d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 2732d61bbb3SSatish Balay { 2742d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 2752d61bbb3SSatish Balay Mat C; 2762d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 277273d9f13SBarry Smith int *rows,*cols,bs2=a->bs2; 278375fe846SBarry Smith Scalar *array; 2792d61bbb3SSatish Balay 2802d61bbb3SSatish Balay PetscFunctionBegin; 28129bbc08cSBarry Smith if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place"); 282b0a32e0cSBarry Smith ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr); 283549d3d68SSatish Balay ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr); 2842d61bbb3SSatish Balay 285375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 286b0a32e0cSBarry Smith ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr); 287375fe846SBarry Smith for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i]; 288375fe846SBarry Smith #else 2893eda8832SBarry Smith array = a->a; 290375fe846SBarry Smith #endif 291375fe846SBarry Smith 2922d61bbb3SSatish Balay for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1; 293273d9f13SBarry Smith ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr); 294606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 295b0a32e0cSBarry Smith ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr); 2962d61bbb3SSatish Balay cols = rows + bs; 2972d61bbb3SSatish Balay for (i=0; i<mbs; i++) { 2982d61bbb3SSatish Balay cols[0] = i*bs; 2992d61bbb3SSatish Balay for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1; 3002d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 3012d61bbb3SSatish Balay for (j=0; j<len; j++) { 3022d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 3032d61bbb3SSatish Balay for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1; 3042d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr); 3052d61bbb3SSatish Balay array += bs2; 3062d61bbb3SSatish Balay } 3072d61bbb3SSatish Balay } 308606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 309375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 310375fe846SBarry Smith ierr = PetscFree(array); 311375fe846SBarry Smith #endif 3122d61bbb3SSatish Balay 3132d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3142d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3152d61bbb3SSatish Balay 316c4992f7dSBarry Smith if (B) { 3172d61bbb3SSatish Balay *B = C; 3182d61bbb3SSatish Balay } else { 319273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 3202d61bbb3SSatish Balay } 3212d61bbb3SSatish Balay PetscFunctionReturn(0); 3222d61bbb3SSatish Balay } 3232d61bbb3SSatish Balay 3244a2ae208SSatish Balay #undef __FUNCT__ 3254a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary" 326b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer) 3272593348eSBarry Smith { 328b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 3299df24120SSatish Balay int i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 330b6490206SBarry Smith Scalar *aa; 331ce6f0cecSBarry Smith FILE *file; 3322593348eSBarry Smith 3333a40ed3dSBarry Smith PetscFunctionBegin; 334b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 335b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 3362593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3373b2fbd54SBarry Smith 338273d9f13SBarry Smith col_lens[1] = A->m; 339273d9f13SBarry Smith col_lens[2] = A->n; 3407e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3412593348eSBarry Smith 3422593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 343b6490206SBarry Smith count = 0; 344b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 345b6490206SBarry Smith for (j=0; j<bs; j++) { 346b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 347b6490206SBarry Smith } 3482593348eSBarry Smith } 349273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 350606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 3512593348eSBarry Smith 3522593348eSBarry Smith /* store column indices (zero start index) */ 353b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr); 354b6490206SBarry Smith count = 0; 355b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 356b6490206SBarry Smith for (j=0; j<bs; j++) { 357b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 358b6490206SBarry Smith for (l=0; l<bs; l++) { 359b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3602593348eSBarry Smith } 3612593348eSBarry Smith } 362b6490206SBarry Smith } 363b6490206SBarry Smith } 3640752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr); 365606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 3662593348eSBarry Smith 3672593348eSBarry Smith /* store nonzero values */ 368b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr); 369b6490206SBarry Smith count = 0; 370b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 371b6490206SBarry Smith for (j=0; j<bs; j++) { 372b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 373b6490206SBarry Smith for (l=0; l<bs; l++) { 3747e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 375b6490206SBarry Smith } 376b6490206SBarry Smith } 377b6490206SBarry Smith } 378b6490206SBarry Smith } 3790752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 380606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 381ce6f0cecSBarry Smith 382b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 383ce6f0cecSBarry Smith if (file) { 384ce6f0cecSBarry Smith fprintf(file,"-matload_block_size %d\n",a->bs); 385ce6f0cecSBarry Smith } 3863a40ed3dSBarry Smith PetscFunctionReturn(0); 3872593348eSBarry Smith } 3882593348eSBarry Smith 3894a2ae208SSatish Balay #undef __FUNCT__ 3904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII" 391b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer) 3922593348eSBarry Smith { 393b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 394fb9695e5SSatish Balay int ierr,i,j,bs = a->bs,k,l,bs2=a->bs2; 395f3ef73ceSBarry Smith PetscViewerFormat format; 3962593348eSBarry Smith 3973a40ed3dSBarry Smith PetscFunctionBegin; 398b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 399fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) { 400b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %d\n",bs);CHKERRQ(ierr); 401fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 40229bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Matlab format not supported"); 403fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 404b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 40544cd7ae7SLois Curfman McInnes for (i=0; i<a->mbs; i++) { 40644cd7ae7SLois Curfman McInnes for (j=0; j<bs; j++) { 407b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 40844cd7ae7SLois Curfman McInnes for (k=a->i[i]; k<a->i[i+1]; k++) { 40944cd7ae7SLois Curfman McInnes for (l=0; l<bs; l++) { 410aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4110e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 412b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l, 4130e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4140e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 415b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l, 4160e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4170e6d2581SBarry Smith } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 418b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4190ef38995SBarry Smith } 42044cd7ae7SLois Curfman McInnes #else 4210ef38995SBarry Smith if (a->a[bs2*k + l*bs + j] != 0.0) { 422b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 4230ef38995SBarry Smith } 42444cd7ae7SLois Curfman McInnes #endif 42544cd7ae7SLois Curfman McInnes } 42644cd7ae7SLois Curfman McInnes } 427b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 42844cd7ae7SLois Curfman McInnes } 42944cd7ae7SLois Curfman McInnes } 430b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4310ef38995SBarry Smith } else { 432b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 433b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 434b6490206SBarry Smith for (j=0; j<bs; j++) { 435b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 436b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 437b6490206SBarry Smith for (l=0; l<bs; l++) { 438aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4390e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 440b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l, 4410e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4420e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 443b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l, 4440e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4450ef38995SBarry Smith } else { 446b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 44788685aaeSLois Curfman McInnes } 44888685aaeSLois Curfman McInnes #else 449b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 45088685aaeSLois Curfman McInnes #endif 4512593348eSBarry Smith } 4522593348eSBarry Smith } 453b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 4542593348eSBarry Smith } 4552593348eSBarry Smith } 456b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 457b6490206SBarry Smith } 458b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4593a40ed3dSBarry Smith PetscFunctionReturn(0); 4602593348eSBarry Smith } 4612593348eSBarry Smith 4624a2ae208SSatish Balay #undef __FUNCT__ 4634a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom" 464b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 4653270192aSSatish Balay { 46677ed5343SBarry Smith Mat A = (Mat) Aa; 4673270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ*)A->data; 468b65db4caSBarry Smith int row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2; 4690e6d2581SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 4703f1db9ecSBarry Smith MatScalar *aa; 471b0a32e0cSBarry Smith PetscViewer viewer; 4723270192aSSatish Balay 4733a40ed3dSBarry Smith PetscFunctionBegin; 4743270192aSSatish Balay 475b65db4caSBarry Smith /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/ 47677ed5343SBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 47777ed5343SBarry Smith 478b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 47977ed5343SBarry Smith 4803270192aSSatish Balay /* loop over matrix elements drawing boxes */ 481b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 4823270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 4833270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 484273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 4853270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 4863270192aSSatish Balay aa = a->a + j*bs2; 4873270192aSSatish Balay for (k=0; k<bs; k++) { 4883270192aSSatish Balay for (l=0; l<bs; l++) { 4890e6d2581SBarry Smith if (PetscRealPart(*aa++) >= 0.) continue; 490b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 4913270192aSSatish Balay } 4923270192aSSatish Balay } 4933270192aSSatish Balay } 4943270192aSSatish Balay } 495b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 4963270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 4973270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 498273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 4993270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5003270192aSSatish Balay aa = a->a + j*bs2; 5013270192aSSatish Balay for (k=0; k<bs; k++) { 5023270192aSSatish Balay for (l=0; l<bs; l++) { 5030e6d2581SBarry Smith if (PetscRealPart(*aa++) != 0.) continue; 504b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5053270192aSSatish Balay } 5063270192aSSatish Balay } 5073270192aSSatish Balay } 5083270192aSSatish Balay } 5093270192aSSatish Balay 510b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 5113270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5123270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 513273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5143270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5153270192aSSatish Balay aa = a->a + j*bs2; 5163270192aSSatish Balay for (k=0; k<bs; k++) { 5173270192aSSatish Balay for (l=0; l<bs; l++) { 5180e6d2581SBarry Smith if (PetscRealPart(*aa++) <= 0.) continue; 519b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5203270192aSSatish Balay } 5213270192aSSatish Balay } 5223270192aSSatish Balay } 5233270192aSSatish Balay } 52477ed5343SBarry Smith PetscFunctionReturn(0); 52577ed5343SBarry Smith } 5263270192aSSatish Balay 5274a2ae208SSatish Balay #undef __FUNCT__ 5284a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw" 529b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer) 53077ed5343SBarry Smith { 5317dce120fSSatish Balay int ierr; 5320e6d2581SBarry Smith PetscReal xl,yl,xr,yr,w,h; 533b0a32e0cSBarry Smith PetscDraw draw; 53477ed5343SBarry Smith PetscTruth isnull; 5353270192aSSatish Balay 53677ed5343SBarry Smith PetscFunctionBegin; 53777ed5343SBarry Smith 538b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 539b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 54077ed5343SBarry Smith 54177ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 542273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 54377ed5343SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 544b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 545b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 54677ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5473a40ed3dSBarry Smith PetscFunctionReturn(0); 5483270192aSSatish Balay } 5493270192aSSatish Balay 5504a2ae208SSatish Balay #undef __FUNCT__ 5514a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ" 552b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer) 5532593348eSBarry Smith { 55419bcc07fSBarry Smith int ierr; 5556831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 5562593348eSBarry Smith 5573a40ed3dSBarry Smith PetscFunctionBegin; 558b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 559b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 560fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 561fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 5620f5bd95cSBarry Smith if (issocket) { 56329bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported"); 5640f5bd95cSBarry Smith } else if (isascii){ 5653a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5660f5bd95cSBarry Smith } else if (isbinary) { 5673a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 5680f5bd95cSBarry Smith } else if (isdraw) { 5693a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 5705cd90555SBarry Smith } else { 57129bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name); 5722593348eSBarry Smith } 5733a40ed3dSBarry Smith PetscFunctionReturn(0); 5742593348eSBarry Smith } 575b6490206SBarry Smith 576cd0e1443SSatish Balay 5774a2ae208SSatish Balay #undef __FUNCT__ 5784a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ" 5792d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 580cd0e1443SSatish Balay { 581cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 5822d61bbb3SSatish Balay int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 5832d61bbb3SSatish Balay int *ai = a->i,*ailen = a->ilen; 5842d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 5853f1db9ecSBarry Smith MatScalar *ap,*aa = a->a,zero = 0.0; 586cd0e1443SSatish Balay 5873a40ed3dSBarry Smith PetscFunctionBegin; 5882d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over rows */ 589cd0e1443SSatish Balay row = im[k]; brow = row/bs; 59029bbc08cSBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row"); 591273d9f13SBarry Smith if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 5922d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 5932c3acbe9SBarry Smith nrow = ailen[brow]; 5942d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over columns */ 59529bbc08cSBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column"); 596273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 5972d61bbb3SSatish Balay col = in[l] ; 5982d61bbb3SSatish Balay bcol = col/bs; 5992d61bbb3SSatish Balay cidx = col%bs; 6002d61bbb3SSatish Balay ridx = row%bs; 6012d61bbb3SSatish Balay high = nrow; 6022d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6032d61bbb3SSatish Balay while (high-low > 5) { 604cd0e1443SSatish Balay t = (low+high)/2; 605cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 606cd0e1443SSatish Balay else low = t; 607cd0e1443SSatish Balay } 608cd0e1443SSatish Balay for (i=low; i<high; i++) { 609cd0e1443SSatish Balay if (rp[i] > bcol) break; 610cd0e1443SSatish Balay if (rp[i] == bcol) { 6112d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6122d61bbb3SSatish Balay goto finished; 613cd0e1443SSatish Balay } 614cd0e1443SSatish Balay } 6152d61bbb3SSatish Balay *v++ = zero; 6162d61bbb3SSatish Balay finished:; 617cd0e1443SSatish Balay } 618cd0e1443SSatish Balay } 6193a40ed3dSBarry Smith PetscFunctionReturn(0); 620cd0e1443SSatish Balay } 621cd0e1443SSatish Balay 62295d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 6234a2ae208SSatish Balay #undef __FUNCT__ 6244a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ" 62595d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv) 62695d5f7c2SBarry Smith { 627563b5814SBarry Smith Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data; 628563b5814SBarry Smith int ierr,i,N = m*n*b->bs2; 629563b5814SBarry Smith MatScalar *vsingle; 63095d5f7c2SBarry Smith 63195d5f7c2SBarry Smith PetscFunctionBegin; 632563b5814SBarry Smith if (N > b->setvalueslen) { 633563b5814SBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 634b0a32e0cSBarry Smith ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 635563b5814SBarry Smith b->setvalueslen = N; 636563b5814SBarry Smith } 637563b5814SBarry Smith vsingle = b->setvaluescopy; 63895d5f7c2SBarry Smith for (i=0; i<N; i++) { 63995d5f7c2SBarry Smith vsingle[i] = v[i]; 64095d5f7c2SBarry Smith } 64195d5f7c2SBarry Smith ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 64295d5f7c2SBarry Smith PetscFunctionReturn(0); 64395d5f7c2SBarry Smith } 64495d5f7c2SBarry Smith #endif 64595d5f7c2SBarry Smith 6462d61bbb3SSatish Balay 6474a2ae208SSatish Balay #undef __FUNCT__ 6484a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ" 64995d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is) 65092c4ed94SBarry Smith { 65192c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 6528a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 653273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 654549d3d68SSatish Balay int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr; 655273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 65695d5f7c2SBarry Smith MatScalar *value = v,*ap,*aa = a->a,*bap; 65792c4ed94SBarry Smith 6583a40ed3dSBarry Smith PetscFunctionBegin; 6590e324ae4SSatish Balay if (roworiented) { 6600e324ae4SSatish Balay stepval = (n-1)*bs; 6610e324ae4SSatish Balay } else { 6620e324ae4SSatish Balay stepval = (m-1)*bs; 6630e324ae4SSatish Balay } 66492c4ed94SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 66592c4ed94SBarry Smith row = im[k]; 6665ef9f2a5SBarry Smith if (row < 0) continue; 667aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 66829bbc08cSBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 66992c4ed94SBarry Smith #endif 67092c4ed94SBarry Smith rp = aj + ai[row]; 67192c4ed94SBarry Smith ap = aa + bs2*ai[row]; 67292c4ed94SBarry Smith rmax = imax[row]; 67392c4ed94SBarry Smith nrow = ailen[row]; 67492c4ed94SBarry Smith low = 0; 67592c4ed94SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 6765ef9f2a5SBarry Smith if (in[l] < 0) continue; 677aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 67829bbc08cSBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 67992c4ed94SBarry Smith #endif 68092c4ed94SBarry Smith col = in[l]; 68192c4ed94SBarry Smith if (roworiented) { 6820e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 6830e324ae4SSatish Balay } else { 6840e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 68592c4ed94SBarry Smith } 68692c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 68792c4ed94SBarry Smith while (high-low > 7) { 68892c4ed94SBarry Smith t = (low+high)/2; 68992c4ed94SBarry Smith if (rp[t] > col) high = t; 69092c4ed94SBarry Smith else low = t; 69192c4ed94SBarry Smith } 69292c4ed94SBarry Smith for (i=low; i<high; i++) { 69392c4ed94SBarry Smith if (rp[i] > col) break; 69492c4ed94SBarry Smith if (rp[i] == col) { 6958a84c255SSatish Balay bap = ap + bs2*i; 6960e324ae4SSatish Balay if (roworiented) { 6978a84c255SSatish Balay if (is == ADD_VALUES) { 698dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 699dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7008a84c255SSatish Balay bap[jj] += *value++; 701dd9472c6SBarry Smith } 702dd9472c6SBarry Smith } 7030e324ae4SSatish Balay } else { 704dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 705dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7060e324ae4SSatish Balay bap[jj] = *value++; 7078a84c255SSatish Balay } 708dd9472c6SBarry Smith } 709dd9472c6SBarry Smith } 7100e324ae4SSatish Balay } else { 7110e324ae4SSatish Balay if (is == ADD_VALUES) { 712dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 713dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7140e324ae4SSatish Balay *bap++ += *value++; 715dd9472c6SBarry Smith } 716dd9472c6SBarry Smith } 7170e324ae4SSatish Balay } else { 718dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 719dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7200e324ae4SSatish Balay *bap++ = *value++; 7210e324ae4SSatish Balay } 7228a84c255SSatish Balay } 723dd9472c6SBarry Smith } 724dd9472c6SBarry Smith } 725f1241b54SBarry Smith goto noinsert2; 72692c4ed94SBarry Smith } 72792c4ed94SBarry Smith } 72889280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 72929bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 73092c4ed94SBarry Smith if (nrow >= rmax) { 73192c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 73292c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 7333f1db9ecSBarry Smith MatScalar *new_a; 73492c4ed94SBarry Smith 73529bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 73689280ab3SLois Curfman McInnes 73792c4ed94SBarry Smith /* malloc new storage space */ 7383f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 739b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 74092c4ed94SBarry Smith new_j = (int*)(new_a + bs2*new_nz); 74192c4ed94SBarry Smith new_i = new_j + new_nz; 74292c4ed94SBarry Smith 74392c4ed94SBarry Smith /* copy over old data into new slots */ 74492c4ed94SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 74592c4ed94SBarry Smith for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 746549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr); 74792c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 748549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr); 749549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 750549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 751549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 75292c4ed94SBarry Smith /* free up old matrix storage */ 753606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 754606d414cSSatish Balay if (!a->singlemalloc) { 755606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 756606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 757606d414cSSatish Balay } 75892c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 759c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 76092c4ed94SBarry Smith 76192c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 76292c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 763b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 76492c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 76592c4ed94SBarry Smith a->reallocs++; 76692c4ed94SBarry Smith a->nz++; 76792c4ed94SBarry Smith } 76892c4ed94SBarry Smith N = nrow++ - 1; 76992c4ed94SBarry Smith /* shift up all the later entries in this row */ 77092c4ed94SBarry Smith for (ii=N; ii>=i; ii--) { 77192c4ed94SBarry Smith rp[ii+1] = rp[ii]; 772549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 77392c4ed94SBarry Smith } 774549d3d68SSatish Balay if (N >= i) { 775549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 776549d3d68SSatish Balay } 77792c4ed94SBarry Smith rp[i] = col; 7788a84c255SSatish Balay bap = ap + bs2*i; 7790e324ae4SSatish Balay if (roworiented) { 780dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 781dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7820e324ae4SSatish Balay bap[jj] = *value++; 783dd9472c6SBarry Smith } 784dd9472c6SBarry Smith } 7850e324ae4SSatish Balay } else { 786dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 787dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7880e324ae4SSatish Balay *bap++ = *value++; 7890e324ae4SSatish Balay } 790dd9472c6SBarry Smith } 791dd9472c6SBarry Smith } 792f1241b54SBarry Smith noinsert2:; 79392c4ed94SBarry Smith low = i; 79492c4ed94SBarry Smith } 79592c4ed94SBarry Smith ailen[row] = nrow; 79692c4ed94SBarry Smith } 7973a40ed3dSBarry Smith PetscFunctionReturn(0); 79892c4ed94SBarry Smith } 79992c4ed94SBarry Smith 800f2501298SSatish Balay 8014a2ae208SSatish Balay #undef __FUNCT__ 8024a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ" 8038f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 804584200bdSSatish Balay { 805584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 806584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 807273d9f13SBarry Smith int m = A->m,*ip,N,*ailen = a->ilen; 808549d3d68SSatish Balay int mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr; 8093f1db9ecSBarry Smith MatScalar *aa = a->a,*ap; 810584200bdSSatish Balay 8113a40ed3dSBarry Smith PetscFunctionBegin; 8123a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 813584200bdSSatish Balay 81443ee02c3SBarry Smith if (m) rmax = ailen[0]; 815584200bdSSatish Balay for (i=1; i<mbs; i++) { 816584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 817584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 818d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 819584200bdSSatish Balay if (fshift) { 820a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 821584200bdSSatish Balay N = ailen[i]; 822584200bdSSatish Balay for (j=0; j<N; j++) { 823584200bdSSatish Balay ip[j-fshift] = ip[j]; 824549d3d68SSatish Balay ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr); 825584200bdSSatish Balay } 826584200bdSSatish Balay } 827584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 828584200bdSSatish Balay } 829584200bdSSatish Balay if (mbs) { 830584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 831584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 832584200bdSSatish Balay } 833584200bdSSatish Balay /* reset ilen and imax for each row */ 834584200bdSSatish Balay for (i=0; i<mbs; i++) { 835584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 836584200bdSSatish Balay } 837a7c10996SSatish Balay a->nz = ai[mbs]; 838584200bdSSatish Balay 839584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 840584200bdSSatish Balay if (fshift && a->diag) { 841606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 842b0a32e0cSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(int)); 843584200bdSSatish Balay a->diag = 0; 844584200bdSSatish Balay } 845b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 846273d9f13SBarry Smith m,A->n,a->bs,fshift*bs2,a->nz*bs2); 847b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 848584200bdSSatish Balay a->reallocs); 849b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 850e2f3b5e9SSatish Balay a->reallocs = 0; 8510e6d2581SBarry Smith A->info.nz_unneeded = (PetscReal)fshift*bs2; 8524e220ebcSLois Curfman McInnes 8533a40ed3dSBarry Smith PetscFunctionReturn(0); 854584200bdSSatish Balay } 855584200bdSSatish Balay 8565a838052SSatish Balay 857bea157c4SSatish Balay 858bea157c4SSatish Balay /* 859bea157c4SSatish Balay This function returns an array of flags which indicate the locations of contiguous 860bea157c4SSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 861bea157c4SSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 862bea157c4SSatish Balay Assume: sizes should be long enough to hold all the values. 863bea157c4SSatish Balay */ 8644a2ae208SSatish Balay #undef __FUNCT__ 8654a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks" 866bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max) 867d9b7c43dSSatish Balay { 868bea157c4SSatish Balay int i,j,k,row; 869bea157c4SSatish Balay PetscTruth flg; 8703a40ed3dSBarry Smith 871433994e6SBarry Smith PetscFunctionBegin; 872bea157c4SSatish Balay for (i=0,j=0; i<n; j++) { 873bea157c4SSatish Balay row = idx[i]; 874bea157c4SSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 875bea157c4SSatish Balay sizes[j] = 1; 876bea157c4SSatish Balay i++; 877e4fda26cSSatish Balay } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */ 878bea157c4SSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 879bea157c4SSatish Balay i++; 880bea157c4SSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 881bea157c4SSatish Balay flg = PETSC_TRUE; 882bea157c4SSatish Balay for (k=1; k<bs; k++) { 883bea157c4SSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 884bea157c4SSatish Balay flg = PETSC_FALSE; 885bea157c4SSatish Balay break; 886d9b7c43dSSatish Balay } 887bea157c4SSatish Balay } 888bea157c4SSatish Balay if (flg == PETSC_TRUE) { /* No break in the bs */ 889bea157c4SSatish Balay sizes[j] = bs; 890bea157c4SSatish Balay i+= bs; 891bea157c4SSatish Balay } else { 892bea157c4SSatish Balay sizes[j] = 1; 893bea157c4SSatish Balay i++; 894bea157c4SSatish Balay } 895bea157c4SSatish Balay } 896bea157c4SSatish Balay } 897bea157c4SSatish Balay *bs_max = j; 8983a40ed3dSBarry Smith PetscFunctionReturn(0); 899d9b7c43dSSatish Balay } 900d9b7c43dSSatish Balay 9014a2ae208SSatish Balay #undef __FUNCT__ 9024a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ" 9038f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag) 904d9b7c43dSSatish Balay { 905d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 906b6815fffSBarry Smith int ierr,i,j,k,count,is_n,*is_idx,*rows; 907bea157c4SSatish Balay int bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max; 9083f1db9ecSBarry Smith Scalar zero = 0.0; 9093f1db9ecSBarry Smith MatScalar *aa; 910d9b7c43dSSatish Balay 9113a40ed3dSBarry Smith PetscFunctionBegin; 912d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 913b9b97703SBarry Smith ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr); 914d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 915d9b7c43dSSatish Balay 916bea157c4SSatish Balay /* allocate memory for rows,sizes */ 917b0a32e0cSBarry Smith ierr = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr); 918bea157c4SSatish Balay sizes = rows + is_n; 919bea157c4SSatish Balay 920563b5814SBarry Smith /* copy IS values to rows, and sort them */ 921bea157c4SSatish Balay for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; } 922bea157c4SSatish Balay ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr); 923dffd3267SBarry Smith if (baij->keepzeroedrows) { 924dffd3267SBarry Smith for (i=0; i<is_n; i++) { sizes[i] = 1; } 925dffd3267SBarry Smith bs_max = is_n; 926dffd3267SBarry Smith } else { 927bea157c4SSatish Balay ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr); 928dffd3267SBarry Smith } 929b97a56abSSatish Balay ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr); 930bea157c4SSatish Balay 931bea157c4SSatish Balay for (i=0,j=0; i<bs_max; j+=sizes[i],i++) { 932bea157c4SSatish Balay row = rows[j]; 933273d9f13SBarry Smith if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row); 934bea157c4SSatish Balay count = (baij->i[row/bs +1] - baij->i[row/bs])*bs; 935bea157c4SSatish Balay aa = baij->a + baij->i[row/bs]*bs2 + (row%bs); 936dffd3267SBarry Smith if (sizes[i] == bs && !baij->keepzeroedrows) { 937bea157c4SSatish Balay if (diag) { 938bea157c4SSatish Balay if (baij->ilen[row/bs] > 0) { 939bea157c4SSatish Balay baij->ilen[row/bs] = 1; 940bea157c4SSatish Balay baij->j[baij->i[row/bs]] = row/bs; 941bea157c4SSatish Balay ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr); 942a07cd24cSSatish Balay } 943563b5814SBarry Smith /* Now insert all the diagonal values for this bs */ 944bea157c4SSatish Balay for (k=0; k<bs; k++) { 945bea157c4SSatish Balay ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr); 946bea157c4SSatish Balay } 947bea157c4SSatish Balay } else { /* (!diag) */ 948bea157c4SSatish Balay baij->ilen[row/bs] = 0; 949bea157c4SSatish Balay } /* end (!diag) */ 950bea157c4SSatish Balay } else { /* (sizes[i] != bs) */ 951aa482453SBarry Smith #if defined (PETSC_USE_DEBUG) 95229bbc08cSBarry Smith if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1"); 953bea157c4SSatish Balay #endif 954bea157c4SSatish Balay for (k=0; k<count; k++) { 955d9b7c43dSSatish Balay aa[0] = zero; 956d9b7c43dSSatish Balay aa += bs; 957d9b7c43dSSatish Balay } 958d9b7c43dSSatish Balay if (diag) { 959f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 960d9b7c43dSSatish Balay } 961d9b7c43dSSatish Balay } 962bea157c4SSatish Balay } 963bea157c4SSatish Balay 964606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 9659a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9663a40ed3dSBarry Smith PetscFunctionReturn(0); 967d9b7c43dSSatish Balay } 9681c351548SSatish Balay 9694a2ae208SSatish Balay #undef __FUNCT__ 9704a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ" 9712d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 9722d61bbb3SSatish Balay { 9732d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 9742d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 975273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 9762d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 977549d3d68SSatish Balay int ridx,cidx,bs2=a->bs2,ierr; 978273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 9793f1db9ecSBarry Smith MatScalar *ap,value,*aa=a->a,*bap; 9802d61bbb3SSatish Balay 9812d61bbb3SSatish Balay PetscFunctionBegin; 9822d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 9832d61bbb3SSatish Balay row = im[k]; brow = row/bs; 9845ef9f2a5SBarry Smith if (row < 0) continue; 985aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 986273d9f13SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m); 9872d61bbb3SSatish Balay #endif 9882d61bbb3SSatish Balay rp = aj + ai[brow]; 9892d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 9902d61bbb3SSatish Balay rmax = imax[brow]; 9912d61bbb3SSatish Balay nrow = ailen[brow]; 9922d61bbb3SSatish Balay low = 0; 9932d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 9945ef9f2a5SBarry Smith if (in[l] < 0) continue; 995aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 996273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n); 9972d61bbb3SSatish Balay #endif 9982d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 9992d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 10002d61bbb3SSatish Balay if (roworiented) { 10015ef9f2a5SBarry Smith value = v[l + k*n]; 10022d61bbb3SSatish Balay } else { 10032d61bbb3SSatish Balay value = v[k + l*m]; 10042d61bbb3SSatish Balay } 10052d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 10062d61bbb3SSatish Balay while (high-low > 7) { 10072d61bbb3SSatish Balay t = (low+high)/2; 10082d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 10092d61bbb3SSatish Balay else low = t; 10102d61bbb3SSatish Balay } 10112d61bbb3SSatish Balay for (i=low; i<high; i++) { 10122d61bbb3SSatish Balay if (rp[i] > bcol) break; 10132d61bbb3SSatish Balay if (rp[i] == bcol) { 10142d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 10152d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 10162d61bbb3SSatish Balay else *bap = value; 10172d61bbb3SSatish Balay goto noinsert1; 10182d61bbb3SSatish Balay } 10192d61bbb3SSatish Balay } 10202d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 102129bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10222d61bbb3SSatish Balay if (nrow >= rmax) { 10232d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 10242d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 10253f1db9ecSBarry Smith MatScalar *new_a; 10262d61bbb3SSatish Balay 102729bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10282d61bbb3SSatish Balay 10292d61bbb3SSatish Balay /* Malloc new storage space */ 10303f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 1031b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 10322d61bbb3SSatish Balay new_j = (int*)(new_a + bs2*new_nz); 10332d61bbb3SSatish Balay new_i = new_j + new_nz; 10342d61bbb3SSatish Balay 10352d61bbb3SSatish Balay /* copy over old data into new slots */ 10362d61bbb3SSatish Balay for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];} 10372d61bbb3SSatish Balay for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 1038549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr); 10392d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 1040549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr); 1041549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1042549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 1043549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 10442d61bbb3SSatish Balay /* free up old matrix storage */ 1045606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 1046606d414cSSatish Balay if (!a->singlemalloc) { 1047606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 1048606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 1049606d414cSSatish Balay } 10502d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 1051c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 10522d61bbb3SSatish Balay 10532d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 10542d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 1055b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 10562d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 10572d61bbb3SSatish Balay a->reallocs++; 10582d61bbb3SSatish Balay a->nz++; 10592d61bbb3SSatish Balay } 10602d61bbb3SSatish Balay N = nrow++ - 1; 10612d61bbb3SSatish Balay /* shift up all the later entries in this row */ 10622d61bbb3SSatish Balay for (ii=N; ii>=i; ii--) { 10632d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 1064549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 10652d61bbb3SSatish Balay } 1066549d3d68SSatish Balay if (N>=i) { 1067549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 1068549d3d68SSatish Balay } 10692d61bbb3SSatish Balay rp[i] = bcol; 10702d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10712d61bbb3SSatish Balay noinsert1:; 10722d61bbb3SSatish Balay low = i; 10732d61bbb3SSatish Balay } 10742d61bbb3SSatish Balay ailen[brow] = nrow; 10752d61bbb3SSatish Balay } 10762d61bbb3SSatish Balay PetscFunctionReturn(0); 10772d61bbb3SSatish Balay } 10782d61bbb3SSatish Balay 1079b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,MatLUInfo*,Mat*); 1080b9b97703SBarry Smith EXTERN int MatLUFactor_SeqBAIJ(Mat,IS,IS,MatLUInfo*); 1081ca44d042SBarry Smith EXTERN int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int); 1082ca44d042SBarry Smith EXTERN int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*); 1083ca44d042SBarry Smith EXTERN int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**); 1084ca44d042SBarry Smith EXTERN int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec); 1085ca44d042SBarry Smith EXTERN int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec); 1086ca44d042SBarry Smith EXTERN int MatScale_SeqBAIJ(Scalar*,Mat); 1087ca44d042SBarry Smith EXTERN int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *); 1088ca44d042SBarry Smith EXTERN int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*); 1089ca44d042SBarry Smith EXTERN int MatGetDiagonal_SeqBAIJ(Mat,Vec); 1090ca44d042SBarry Smith EXTERN int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec); 1091ca44d042SBarry Smith EXTERN int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *); 1092ca44d042SBarry Smith EXTERN int MatZeroEntries_SeqBAIJ(Mat); 10932d61bbb3SSatish Balay 1094ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_N(Mat,Vec,Vec); 1095ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_1(Mat,Vec,Vec); 1096ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_2(Mat,Vec,Vec); 1097ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_3(Mat,Vec,Vec); 1098ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_4(Mat,Vec,Vec); 1099ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_5(Mat,Vec,Vec); 1100ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_6(Mat,Vec,Vec); 1101ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_7(Mat,Vec,Vec); 1102ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec); 1103ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec); 1104ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec); 1105ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec); 1106ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec); 1107ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec); 1108ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec); 11092d61bbb3SSatish Balay 1110ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*); 1111ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*); 1112ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*); 1113ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*); 1114ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*); 1115ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*); 1116ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*); 11172d61bbb3SSatish Balay 1118ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_1(Mat,Vec,Vec); 1119ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_2(Mat,Vec,Vec); 1120ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_3(Mat,Vec,Vec); 1121ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_4(Mat,Vec,Vec); 1122ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_5(Mat,Vec,Vec); 1123ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_6(Mat,Vec,Vec); 1124ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_7(Mat,Vec,Vec); 1125ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_N(Mat,Vec,Vec); 11262d61bbb3SSatish Balay 1127ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec); 1128ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec); 1129ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec); 1130ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec); 1131ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec); 1132ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec); 1133ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec); 1134ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec); 11352d61bbb3SSatish Balay 11364a2ae208SSatish Balay #undef __FUNCT__ 11374a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ" 11385ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 11392d61bbb3SSatish Balay { 11402d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data; 11412d61bbb3SSatish Balay Mat outA; 11422d61bbb3SSatish Balay int ierr; 1143667159a5SBarry Smith PetscTruth row_identity,col_identity; 11442d61bbb3SSatish Balay 11452d61bbb3SSatish Balay PetscFunctionBegin; 114629bbc08cSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU"); 1147667159a5SBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1148667159a5SBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1149667159a5SBarry Smith if (!row_identity || !col_identity) { 115029bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1151667159a5SBarry Smith } 11522d61bbb3SSatish Balay 11532d61bbb3SSatish Balay outA = inA; 11542d61bbb3SSatish Balay inA->factor = FACTOR_LU; 11552d61bbb3SSatish Balay 11562d61bbb3SSatish Balay if (!a->diag) { 1157c4992f7dSBarry Smith ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr); 11582d61bbb3SSatish Balay } 11592d61bbb3SSatish Balay /* 116015091d37SBarry Smith Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver 116115091d37SBarry Smith for ILU(0) factorization with natural ordering 11622d61bbb3SSatish Balay */ 116315091d37SBarry Smith switch (a->bs) { 1164f1af5d2fSBarry Smith case 1: 1165e37c484bSBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1166e37c484bSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_1_NaturalOrdering; 1167e37c484bSBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_1_NaturalOrdering; 1168b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=1\n"); 116915091d37SBarry Smith case 2: 117015091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering; 117115091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_2_NaturalOrdering; 11727c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering; 1173b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n"); 117415091d37SBarry Smith break; 117515091d37SBarry Smith case 3: 117615091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering; 117715091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_3_NaturalOrdering; 11787c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering; 1179b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n"); 118015091d37SBarry Smith break; 118115091d37SBarry Smith case 4: 1182667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering; 1183f830108cSBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering; 11847c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering; 1185b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n"); 118615091d37SBarry Smith break; 118715091d37SBarry Smith case 5: 1188667159a5SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering; 1189667159a5SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_5_NaturalOrdering; 11907c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering; 1191b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n"); 119215091d37SBarry Smith break; 119315091d37SBarry Smith case 6: 119415091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering; 119515091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_6_NaturalOrdering; 11967c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering; 1197b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n"); 119815091d37SBarry Smith break; 119915091d37SBarry Smith case 7: 120015091d37SBarry Smith inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering; 12017c922b88SBarry Smith inA->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering; 120215091d37SBarry Smith inA->ops->solve = MatSolve_SeqBAIJ_7_NaturalOrdering; 1203b0a32e0cSBarry Smith PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n"); 120415091d37SBarry Smith break; 1205c38d4ed2SBarry Smith default: 1206c38d4ed2SBarry Smith a->row = row; 1207c38d4ed2SBarry Smith a->col = col; 1208c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1209c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1210c38d4ed2SBarry Smith 1211c38d4ed2SBarry Smith /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 12124c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1213b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1214c38d4ed2SBarry Smith 1215c38d4ed2SBarry Smith if (!a->solve_work) { 1216b0a32e0cSBarry Smith ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr); 1217b0a32e0cSBarry Smith PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar)); 1218c38d4ed2SBarry Smith } 12192d61bbb3SSatish Balay } 12202d61bbb3SSatish Balay 1221667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr); 1222667159a5SBarry Smith 12232d61bbb3SSatish Balay PetscFunctionReturn(0); 12242d61bbb3SSatish Balay } 12254a2ae208SSatish Balay #undef __FUNCT__ 12264a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ" 1227ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1228ba4ca20aSSatish Balay { 1229c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1230ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1231d132466eSBarry Smith int ierr; 1232ba4ca20aSSatish Balay 12333a40ed3dSBarry Smith PetscFunctionBegin; 1234c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1235d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1236d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n");CHKERRQ(ierr); 12373a40ed3dSBarry Smith PetscFunctionReturn(0); 1238ba4ca20aSSatish Balay } 1239d9b7c43dSSatish Balay 1240fb2e594dSBarry Smith EXTERN_C_BEGIN 12414a2ae208SSatish Balay #undef __FUNCT__ 12424a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 124327a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 124427a8da17SBarry Smith { 124527a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 124627a8da17SBarry Smith int i,nz,n; 124727a8da17SBarry Smith 124827a8da17SBarry Smith PetscFunctionBegin; 124927a8da17SBarry Smith nz = baij->maxnz; 1250273d9f13SBarry Smith n = mat->n; 125127a8da17SBarry Smith for (i=0; i<nz; i++) { 125227a8da17SBarry Smith baij->j[i] = indices[i]; 125327a8da17SBarry Smith } 125427a8da17SBarry Smith baij->nz = nz; 125527a8da17SBarry Smith for (i=0; i<n; i++) { 125627a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 125727a8da17SBarry Smith } 125827a8da17SBarry Smith 125927a8da17SBarry Smith PetscFunctionReturn(0); 126027a8da17SBarry Smith } 1261fb2e594dSBarry Smith EXTERN_C_END 126227a8da17SBarry Smith 12634a2ae208SSatish Balay #undef __FUNCT__ 12644a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices" 126527a8da17SBarry Smith /*@ 126627a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 126727a8da17SBarry Smith in the matrix. 126827a8da17SBarry Smith 126927a8da17SBarry Smith Input Parameters: 127027a8da17SBarry Smith + mat - the SeqBAIJ matrix 127127a8da17SBarry Smith - indices - the column indices 127227a8da17SBarry Smith 127315091d37SBarry Smith Level: advanced 127415091d37SBarry Smith 127527a8da17SBarry Smith Notes: 127627a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 127727a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 127827a8da17SBarry Smith of the MatSetValues() operation. 127927a8da17SBarry Smith 128027a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 128127a8da17SBarry Smith MatCreateSeqBAIJ(). 128227a8da17SBarry Smith 128327a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 128427a8da17SBarry Smith 128527a8da17SBarry Smith @*/ 128627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 128727a8da17SBarry Smith { 128827a8da17SBarry Smith int ierr,(*f)(Mat,int *); 128927a8da17SBarry Smith 129027a8da17SBarry Smith PetscFunctionBegin; 129127a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1292b9617806SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr); 129327a8da17SBarry Smith if (f) { 129427a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 129527a8da17SBarry Smith } else { 129629bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 129727a8da17SBarry Smith } 129827a8da17SBarry Smith PetscFunctionReturn(0); 129927a8da17SBarry Smith } 130027a8da17SBarry Smith 13014a2ae208SSatish Balay #undef __FUNCT__ 13024a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ" 1303273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v) 1304273d9f13SBarry Smith { 1305273d9f13SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1306273d9f13SBarry Smith int ierr,i,j,n,row,bs,*ai,*aj,mbs; 1307273d9f13SBarry Smith PetscReal atmp; 1308273d9f13SBarry Smith Scalar *x,zero = 0.0; 1309273d9f13SBarry Smith MatScalar *aa; 1310273d9f13SBarry Smith int ncols,brow,krow,kcol; 1311273d9f13SBarry Smith 1312273d9f13SBarry Smith PetscFunctionBegin; 1313273d9f13SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1314273d9f13SBarry Smith bs = a->bs; 1315273d9f13SBarry Smith aa = a->a; 1316273d9f13SBarry Smith ai = a->i; 1317273d9f13SBarry Smith aj = a->j; 1318273d9f13SBarry Smith mbs = a->mbs; 1319273d9f13SBarry Smith 1320273d9f13SBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 1321273d9f13SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1322273d9f13SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1323273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1324273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1325273d9f13SBarry Smith ncols = ai[1] - ai[0]; ai++; 1326273d9f13SBarry Smith brow = bs*i; 1327273d9f13SBarry Smith for (j=0; j<ncols; j++){ 1328273d9f13SBarry Smith /* bcol = bs*(*aj); */ 1329273d9f13SBarry Smith for (kcol=0; kcol<bs; kcol++){ 1330273d9f13SBarry Smith for (krow=0; krow<bs; krow++){ 1331273d9f13SBarry Smith atmp = PetscAbsScalar(*aa); aa++; 1332273d9f13SBarry Smith row = brow + krow; /* row index */ 1333273d9f13SBarry Smith /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */ 1334273d9f13SBarry Smith if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp; 1335273d9f13SBarry Smith } 1336273d9f13SBarry Smith } 1337273d9f13SBarry Smith aj++; 1338273d9f13SBarry Smith } 1339273d9f13SBarry Smith } 1340273d9f13SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1341273d9f13SBarry Smith PetscFunctionReturn(0); 1342273d9f13SBarry Smith } 1343273d9f13SBarry Smith 13444a2ae208SSatish Balay #undef __FUNCT__ 13454a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ" 1346273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A) 1347273d9f13SBarry Smith { 1348273d9f13SBarry Smith int ierr; 1349273d9f13SBarry Smith 1350273d9f13SBarry Smith PetscFunctionBegin; 1351273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr); 1352273d9f13SBarry Smith PetscFunctionReturn(0); 1353273d9f13SBarry Smith } 1354273d9f13SBarry Smith 13554a2ae208SSatish Balay #undef __FUNCT__ 13564a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ" 1357f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array) 1358f2a5309cSSatish Balay { 1359f2a5309cSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1360f2a5309cSSatish Balay PetscFunctionBegin; 1361f2a5309cSSatish Balay *array = a->a; 1362f2a5309cSSatish Balay PetscFunctionReturn(0); 1363f2a5309cSSatish Balay } 1364f2a5309cSSatish Balay 13654a2ae208SSatish Balay #undef __FUNCT__ 13664a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ" 1367f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array) 1368f2a5309cSSatish Balay { 1369f2a5309cSSatish Balay PetscFunctionBegin; 1370f2a5309cSSatish Balay PetscFunctionReturn(0); 1371f2a5309cSSatish Balay } 1372f2a5309cSSatish Balay 13732593348eSBarry Smith /* -------------------------------------------------------------------*/ 1374cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1375cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1376cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1377cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1378cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 13797c922b88SBarry Smith MatMultTranspose_SeqBAIJ, 13807c922b88SBarry Smith MatMultTransposeAdd_SeqBAIJ, 1381cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1382cc2dc46cSBarry Smith 0, 1383cc2dc46cSBarry Smith 0, 1384cc2dc46cSBarry Smith 0, 1385cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1386cc2dc46cSBarry Smith 0, 1387b6490206SBarry Smith 0, 1388f2501298SSatish Balay MatTranspose_SeqBAIJ, 1389cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1390cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1391cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1392cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1393cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1394b6490206SBarry Smith 0, 1395cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1396cc2dc46cSBarry Smith 0, 1397cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1398cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1399cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1400cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1401cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1402cc2dc46cSBarry Smith 0, 1403cc2dc46cSBarry Smith 0, 1404273d9f13SBarry Smith MatSetUpPreallocation_SeqBAIJ, 1405273d9f13SBarry Smith 0, 1406cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1407cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1408cc2dc46cSBarry Smith 0, 1409f2a5309cSSatish Balay MatGetArray_SeqBAIJ, 1410f2a5309cSSatish Balay MatRestoreArray_SeqBAIJ, 14112e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1412cc2dc46cSBarry Smith 0, 1413cc2dc46cSBarry Smith 0, 1414cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1415cc2dc46cSBarry Smith 0, 1416cc2dc46cSBarry Smith 0, 1417cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1418cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1419cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1420cc2dc46cSBarry Smith 0, 1421cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1422cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1423cc2dc46cSBarry Smith 0, 1424cc2dc46cSBarry Smith 0, 1425cc2dc46cSBarry Smith 0, 1426cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 14273b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 142892c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1429cc2dc46cSBarry Smith 0, 1430cc2dc46cSBarry Smith 0, 1431cc2dc46cSBarry Smith 0, 1432cc2dc46cSBarry Smith 0, 1433cc2dc46cSBarry Smith 0, 1434cc2dc46cSBarry Smith 0, 1435d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1436cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1437b9b97703SBarry Smith MatDestroy_SeqBAIJ, 1438b9b97703SBarry Smith MatView_SeqBAIJ, 1439273d9f13SBarry Smith MatGetMaps_Petsc, 1440273d9f13SBarry Smith 0, 1441273d9f13SBarry Smith 0, 1442273d9f13SBarry Smith 0, 1443273d9f13SBarry Smith 0, 1444273d9f13SBarry Smith 0, 1445273d9f13SBarry Smith 0, 1446273d9f13SBarry Smith MatGetRowMax_SeqBAIJ, 1447273d9f13SBarry Smith MatConvert_Basic}; 14482593348eSBarry Smith 14493e90b805SBarry Smith EXTERN_C_BEGIN 14504a2ae208SSatish Balay #undef __FUNCT__ 14514a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ" 14523e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat) 14533e90b805SBarry Smith { 14543e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1455273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2; 1456d132466eSBarry Smith int ierr; 14573e90b805SBarry Smith 14583e90b805SBarry Smith PetscFunctionBegin; 14593e90b805SBarry Smith if (aij->nonew != 1) { 146029bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14613e90b805SBarry Smith } 14623e90b805SBarry Smith 14633e90b805SBarry Smith /* allocate space for values if not already there */ 14643e90b805SBarry Smith if (!aij->saved_values) { 1465f2a5309cSSatish Balay ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr); 14663e90b805SBarry Smith } 14673e90b805SBarry Smith 14683e90b805SBarry Smith /* copy values over */ 1469d132466eSBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr); 14703e90b805SBarry Smith PetscFunctionReturn(0); 14713e90b805SBarry Smith } 14723e90b805SBarry Smith EXTERN_C_END 14733e90b805SBarry Smith 14743e90b805SBarry Smith EXTERN_C_BEGIN 14754a2ae208SSatish Balay #undef __FUNCT__ 14764a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ" 147732e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat) 14783e90b805SBarry Smith { 14793e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1480273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr; 14813e90b805SBarry Smith 14823e90b805SBarry Smith PetscFunctionBegin; 14833e90b805SBarry Smith if (aij->nonew != 1) { 148429bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14853e90b805SBarry Smith } 14863e90b805SBarry Smith if (!aij->saved_values) { 148729bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 14883e90b805SBarry Smith } 14893e90b805SBarry Smith 14903e90b805SBarry Smith /* copy values over */ 1491549d3d68SSatish Balay ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr); 14923e90b805SBarry Smith PetscFunctionReturn(0); 14933e90b805SBarry Smith } 14943e90b805SBarry Smith EXTERN_C_END 14953e90b805SBarry Smith 1496273d9f13SBarry Smith EXTERN_C_BEGIN 1497273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*); 1498273d9f13SBarry Smith EXTERN_C_END 1499273d9f13SBarry Smith 1500273d9f13SBarry Smith EXTERN_C_BEGIN 15014a2ae208SSatish Balay #undef __FUNCT__ 15024a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ" 1503273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B) 15042593348eSBarry Smith { 1505273d9f13SBarry Smith int ierr,size; 1506b6490206SBarry Smith Mat_SeqBAIJ *b; 15073b2fbd54SBarry Smith 15083a40ed3dSBarry Smith PetscFunctionBegin; 1509273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 151029bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1511b6490206SBarry Smith 1512273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 1513273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 1514b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr); 1515b0a32e0cSBarry Smith B->data = (void*)b; 1516549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr); 1517549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 15182593348eSBarry Smith B->factor = 0; 15192593348eSBarry Smith B->lupivotthreshold = 1.0; 152090f02eecSBarry Smith B->mapping = 0; 15212593348eSBarry Smith b->row = 0; 15222593348eSBarry Smith b->col = 0; 1523e51c0b9cSSatish Balay b->icol = 0; 15242593348eSBarry Smith b->reallocs = 0; 15253e90b805SBarry Smith b->saved_values = 0; 1526cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 1527563b5814SBarry Smith b->setvalueslen = 0; 1528563b5814SBarry Smith b->setvaluescopy = PETSC_NULL; 1529563b5814SBarry Smith #endif 15302593348eSBarry Smith 1531273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 1532273d9f13SBarry Smith ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 1533a5ae1ecdSBarry Smith 1534c4992f7dSBarry Smith b->sorted = PETSC_FALSE; 1535c4992f7dSBarry Smith b->roworiented = PETSC_TRUE; 15362593348eSBarry Smith b->nonew = 0; 15372593348eSBarry Smith b->diag = 0; 15382593348eSBarry Smith b->solve_work = 0; 1539de6a44a3SBarry Smith b->mult_work = 0; 15402593348eSBarry Smith b->spptr = 0; 15410e6d2581SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1542883fce79SBarry Smith b->keepzeroedrows = PETSC_FALSE; 15434e220ebcSLois Curfman McInnes 1544f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 15453e90b805SBarry Smith "MatStoreValues_SeqBAIJ", 1546bc4b532fSSatish Balay MatStoreValues_SeqBAIJ);CHKERRQ(ierr); 1547f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 15483e90b805SBarry Smith "MatRetrieveValues_SeqBAIJ", 1549bc4b532fSSatish Balay MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr); 1550f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 155127a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 1552bc4b532fSSatish Balay MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 1553273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C", 1554273d9f13SBarry Smith "MatConvert_SeqBAIJ_SeqAIJ", 1555273d9f13SBarry Smith MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr); 15563a40ed3dSBarry Smith PetscFunctionReturn(0); 15572593348eSBarry Smith } 1558273d9f13SBarry Smith EXTERN_C_END 15592593348eSBarry Smith 15604a2ae208SSatish Balay #undef __FUNCT__ 15614a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ" 15622e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 15632593348eSBarry Smith { 15642593348eSBarry Smith Mat C; 1565b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data; 156627a8da17SBarry Smith int i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1567de6a44a3SBarry Smith 15683a40ed3dSBarry Smith PetscFunctionBegin; 156929bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 15702593348eSBarry Smith 15712593348eSBarry Smith *B = 0; 1572273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 1573273d9f13SBarry Smith ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr); 1574273d9f13SBarry Smith c = (Mat_SeqBAIJ*)C->data; 157544cd7ae7SLois Curfman McInnes 1576b6490206SBarry Smith c->bs = a->bs; 15779df24120SSatish Balay c->bs2 = a->bs2; 1578b6490206SBarry Smith c->mbs = a->mbs; 1579b6490206SBarry Smith c->nbs = a->nbs; 158035d8aa7fSBarry Smith ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 15812593348eSBarry Smith 1582b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 1583b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 1584b6490206SBarry Smith for (i=0; i<mbs; i++) { 15852593348eSBarry Smith c->imax[i] = a->imax[i]; 15862593348eSBarry Smith c->ilen[i] = a->ilen[i]; 15872593348eSBarry Smith } 15882593348eSBarry Smith 15892593348eSBarry Smith /* allocate the matrix space */ 1590c4992f7dSBarry Smith c->singlemalloc = PETSC_TRUE; 15913f1db9ecSBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int)); 1592b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 15937e67e3f9SSatish Balay c->j = (int*)(c->a + nz*bs2); 1594de6a44a3SBarry Smith c->i = c->j + nz; 1595549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr); 1596b6490206SBarry Smith if (mbs > 0) { 1597549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr); 15982e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 1599549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16002e8a6d31SBarry Smith } else { 1601549d3d68SSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 16022593348eSBarry Smith } 16032593348eSBarry Smith } 16042593348eSBarry Smith 1605b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 16062593348eSBarry Smith c->sorted = a->sorted; 16072593348eSBarry Smith c->roworiented = a->roworiented; 16082593348eSBarry Smith c->nonew = a->nonew; 16092593348eSBarry Smith 16102593348eSBarry Smith if (a->diag) { 1611b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 1612b0a32e0cSBarry Smith PetscLogObjectMemory(C,(mbs+1)*sizeof(int)); 1613b6490206SBarry Smith for (i=0; i<mbs; i++) { 16142593348eSBarry Smith c->diag[i] = a->diag[i]; 16152593348eSBarry Smith } 161698305bb5SBarry Smith } else c->diag = 0; 16172593348eSBarry Smith c->nz = a->nz; 16182593348eSBarry Smith c->maxnz = a->maxnz; 16192593348eSBarry Smith c->solve_work = 0; 16202593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 16217fc0212eSBarry Smith c->mult_work = 0; 1622273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 1623273d9f13SBarry Smith C->assembled = PETSC_TRUE; 16242593348eSBarry Smith *B = C; 1625b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 16263a40ed3dSBarry Smith PetscFunctionReturn(0); 16272593348eSBarry Smith } 16282593348eSBarry Smith 1629273d9f13SBarry Smith EXTERN_C_BEGIN 16304a2ae208SSatish Balay #undef __FUNCT__ 16314a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ" 1632b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A) 16332593348eSBarry Smith { 1634b6490206SBarry Smith Mat_SeqBAIJ *a; 16352593348eSBarry Smith Mat B; 1636f1af5d2fSBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1; 1637b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 163835aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1639a7c10996SSatish Balay int *masked,nmask,tmp,bs2,ishift; 1640b6490206SBarry Smith Scalar *aa; 164119bcc07fSBarry Smith MPI_Comm comm = ((PetscObject)viewer)->comm; 16422593348eSBarry Smith 16433a40ed3dSBarry Smith PetscFunctionBegin; 1644b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 1645de6a44a3SBarry Smith bs2 = bs*bs; 1646b6490206SBarry Smith 1647d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 164829bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 1649b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 16500752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 165129bbc08cSBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 16522593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 16532593348eSBarry Smith 1654d64ed03dSBarry Smith if (header[3] < 0) { 165529bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ"); 1656d64ed03dSBarry Smith } 1657d64ed03dSBarry Smith 165829bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 165935aab85fSBarry Smith 166035aab85fSBarry Smith /* 166135aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 166235aab85fSBarry Smith divisible by the blocksize 166335aab85fSBarry Smith */ 1664b6490206SBarry Smith mbs = M/bs; 166535aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 166635aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 166735aab85fSBarry Smith else mbs++; 166835aab85fSBarry Smith if (extra_rows) { 1669b0a32e0cSBarry Smith PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 167035aab85fSBarry Smith } 1671b6490206SBarry Smith 16722593348eSBarry Smith /* read in row lengths */ 1673b0a32e0cSBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr); 16740752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 167535aab85fSBarry Smith for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 16762593348eSBarry Smith 1677b6490206SBarry Smith /* read in column indices */ 1678b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr); 16790752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 168035aab85fSBarry Smith for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 1681b6490206SBarry Smith 1682b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1683b0a32e0cSBarry Smith ierr = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr); 1684549d3d68SSatish Balay ierr = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr); 1685b0a32e0cSBarry Smith ierr = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr); 1686549d3d68SSatish Balay ierr = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr); 168735aab85fSBarry Smith masked = mask + mbs; 1688b6490206SBarry Smith rowcount = 0; nzcount = 0; 1689b6490206SBarry Smith for (i=0; i<mbs; i++) { 169035aab85fSBarry Smith nmask = 0; 1691b6490206SBarry Smith for (j=0; j<bs; j++) { 1692b6490206SBarry Smith kmax = rowlengths[rowcount]; 1693b6490206SBarry Smith for (k=0; k<kmax; k++) { 169435aab85fSBarry Smith tmp = jj[nzcount++]/bs; 169535aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1696b6490206SBarry Smith } 1697b6490206SBarry Smith rowcount++; 1698b6490206SBarry Smith } 169935aab85fSBarry Smith browlengths[i] += nmask; 170035aab85fSBarry Smith /* zero out the mask elements we set */ 170135aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1702b6490206SBarry Smith } 1703b6490206SBarry Smith 17042593348eSBarry Smith /* create our matrix */ 17053eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 17062593348eSBarry Smith B = *A; 1707b6490206SBarry Smith a = (Mat_SeqBAIJ*)B->data; 17082593348eSBarry Smith 17092593348eSBarry Smith /* set matrix "i" values */ 1710de6a44a3SBarry Smith a->i[0] = 0; 1711b6490206SBarry Smith for (i=1; i<= mbs; i++) { 1712b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1713b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 17142593348eSBarry Smith } 1715b6490206SBarry Smith a->nz = 0; 1716b6490206SBarry Smith for (i=0; i<mbs; i++) a->nz += browlengths[i]; 17172593348eSBarry Smith 1718b6490206SBarry Smith /* read in nonzero values */ 1719b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr); 17200752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 172135aab85fSBarry Smith for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 1722b6490206SBarry Smith 1723b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1724b6490206SBarry Smith nzcount = 0; jcount = 0; 1725b6490206SBarry Smith for (i=0; i<mbs; i++) { 1726b6490206SBarry Smith nzcountb = nzcount; 172735aab85fSBarry Smith nmask = 0; 1728b6490206SBarry Smith for (j=0; j<bs; j++) { 1729b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1730b6490206SBarry Smith for (k=0; k<kmax; k++) { 173135aab85fSBarry Smith tmp = jj[nzcount++]/bs; 173235aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1733b6490206SBarry Smith } 1734b6490206SBarry Smith } 1735de6a44a3SBarry Smith /* sort the masked values */ 1736433994e6SBarry Smith ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 1737de6a44a3SBarry Smith 1738b6490206SBarry Smith /* set "j" values into matrix */ 1739b6490206SBarry Smith maskcount = 1; 174035aab85fSBarry Smith for (j=0; j<nmask; j++) { 174135aab85fSBarry Smith a->j[jcount++] = masked[j]; 1742de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1743b6490206SBarry Smith } 1744b6490206SBarry Smith /* set "a" values into matrix */ 1745de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1746b6490206SBarry Smith for (j=0; j<bs; j++) { 1747b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1748b6490206SBarry Smith for (k=0; k<kmax; k++) { 1749de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1750de6a44a3SBarry Smith block = mask[tmp] - 1; 1751de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1752de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1753375fe846SBarry Smith a->a[idx] = (MatScalar)aa[nzcountb++]; 1754b6490206SBarry Smith } 1755b6490206SBarry Smith } 175635aab85fSBarry Smith /* zero out the mask elements we set */ 175735aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1758b6490206SBarry Smith } 175929bbc08cSBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 1760b6490206SBarry Smith 1761606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 1762606d414cSSatish Balay ierr = PetscFree(browlengths);CHKERRQ(ierr); 1763606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 1764606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 1765606d414cSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 1766b6490206SBarry Smith 1767b6490206SBarry Smith B->assembled = PETSC_TRUE; 1768de6a44a3SBarry Smith 17699c01be13SBarry Smith ierr = MatView_Private(B);CHKERRQ(ierr); 17703a40ed3dSBarry Smith PetscFunctionReturn(0); 17712593348eSBarry Smith } 1772273d9f13SBarry Smith EXTERN_C_END 17732593348eSBarry Smith 17744a2ae208SSatish Balay #undef __FUNCT__ 17754a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ" 1776273d9f13SBarry Smith /*@C 1777273d9f13SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 1778273d9f13SBarry Smith compressed row) format. For good matrix assembly performance the 1779273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1780273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1781273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 17822593348eSBarry Smith 1783273d9f13SBarry Smith Collective on MPI_Comm 1784273d9f13SBarry Smith 1785273d9f13SBarry Smith Input Parameters: 1786273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 1787273d9f13SBarry Smith . bs - size of block 1788273d9f13SBarry Smith . m - number of rows 1789273d9f13SBarry Smith . n - number of columns 179035d8aa7fSBarry Smith . nz - number of nonzero blocks per block row (same for all rows) 179135d8aa7fSBarry Smith - nnz - array containing the number of nonzero blocks in the various block rows 1792273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1793273d9f13SBarry Smith 1794273d9f13SBarry Smith Output Parameter: 1795273d9f13SBarry Smith . A - the matrix 1796273d9f13SBarry Smith 1797273d9f13SBarry Smith Options Database Keys: 1798273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1799273d9f13SBarry Smith block calculations (much slower) 1800273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1801273d9f13SBarry Smith 1802273d9f13SBarry Smith Level: intermediate 1803273d9f13SBarry Smith 1804273d9f13SBarry Smith Notes: 180535d8aa7fSBarry Smith A nonzero block is any block that as 1 or more nonzeros in it 180635d8aa7fSBarry Smith 1807273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1808273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1809273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1810273d9f13SBarry Smith 1811273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1812273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1813273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1814273d9f13SBarry Smith matrices. 1815273d9f13SBarry Smith 1816273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1817273d9f13SBarry Smith @*/ 1818273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A) 1819273d9f13SBarry Smith { 1820273d9f13SBarry Smith int ierr; 1821273d9f13SBarry Smith 1822273d9f13SBarry Smith PetscFunctionBegin; 1823273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 1824273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr); 1825273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr); 1826273d9f13SBarry Smith PetscFunctionReturn(0); 1827273d9f13SBarry Smith } 1828273d9f13SBarry Smith 18294a2ae208SSatish Balay #undef __FUNCT__ 18304a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation" 1831273d9f13SBarry Smith /*@C 1832273d9f13SBarry Smith MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros 1833273d9f13SBarry Smith per row in the matrix. For good matrix assembly performance the 1834273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1835273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1836273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 1837273d9f13SBarry Smith 1838273d9f13SBarry Smith Collective on MPI_Comm 1839273d9f13SBarry Smith 1840273d9f13SBarry Smith Input Parameters: 1841273d9f13SBarry Smith + A - the matrix 1842273d9f13SBarry Smith . bs - size of block 1843273d9f13SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1844273d9f13SBarry Smith - nnz - array containing the number of block nonzeros in the various block rows 1845273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1846273d9f13SBarry Smith 1847273d9f13SBarry Smith Options Database Keys: 1848273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1849273d9f13SBarry Smith block calculations (much slower) 1850273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1851273d9f13SBarry Smith 1852273d9f13SBarry Smith Level: intermediate 1853273d9f13SBarry Smith 1854273d9f13SBarry Smith Notes: 1855273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1856273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1857273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1858273d9f13SBarry Smith 1859273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1860273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1861273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1862273d9f13SBarry Smith matrices. 1863273d9f13SBarry Smith 1864273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1865273d9f13SBarry Smith @*/ 1866273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz) 1867273d9f13SBarry Smith { 1868273d9f13SBarry Smith Mat_SeqBAIJ *b; 1869273d9f13SBarry Smith int i,len,ierr,mbs,nbs,bs2,newbs = bs; 1870273d9f13SBarry Smith PetscTruth flg; 1871273d9f13SBarry Smith 1872273d9f13SBarry Smith PetscFunctionBegin; 1873273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr); 1874273d9f13SBarry Smith if (!flg) PetscFunctionReturn(0); 1875273d9f13SBarry Smith 1876273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1877b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr); 1878273d9f13SBarry Smith if (nnz && newbs != bs) { 1879273d9f13SBarry Smith SETERRQ(1,"Cannot change blocksize from command line if setting nnz"); 1880273d9f13SBarry Smith } 1881273d9f13SBarry Smith bs = newbs; 1882273d9f13SBarry Smith 1883273d9f13SBarry Smith mbs = B->m/bs; 1884273d9f13SBarry Smith nbs = B->n/bs; 1885273d9f13SBarry Smith bs2 = bs*bs; 1886273d9f13SBarry Smith 1887273d9f13SBarry Smith if (mbs*bs!=B->m || nbs*bs!=B->n) { 188835d8aa7fSBarry Smith SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs); 1889273d9f13SBarry Smith } 1890273d9f13SBarry Smith 1891435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1892435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 1893273d9f13SBarry Smith if (nnz) { 1894273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1895273d9f13SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 1896*3a7fca6bSBarry 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); 1897273d9f13SBarry Smith } 1898273d9f13SBarry Smith } 1899273d9f13SBarry Smith 1900273d9f13SBarry Smith b = (Mat_SeqBAIJ*)B->data; 1901b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr); 1902273d9f13SBarry Smith if (!flg) { 1903273d9f13SBarry Smith switch (bs) { 1904273d9f13SBarry Smith case 1: 1905273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1906273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_1; 1907273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_1; 1908273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1909273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 1910273d9f13SBarry Smith break; 1911273d9f13SBarry Smith case 2: 1912273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1913273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_2; 1914273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_2; 1915273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1916273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 1917273d9f13SBarry Smith break; 1918273d9f13SBarry Smith case 3: 1919273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1920273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_3; 1921273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_3; 1922273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1923273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 1924273d9f13SBarry Smith break; 1925273d9f13SBarry Smith case 4: 1926273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1927273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_4; 1928273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_4; 1929273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1930273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 1931273d9f13SBarry Smith break; 1932273d9f13SBarry Smith case 5: 1933273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1934273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_5; 1935273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_5; 1936273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1937273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 1938273d9f13SBarry Smith break; 1939273d9f13SBarry Smith case 6: 1940273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6; 1941273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_6; 1942273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_6; 1943273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_6; 1944273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_6; 1945273d9f13SBarry Smith break; 1946273d9f13SBarry Smith case 7: 1947273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1948273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_7; 1949273d9f13SBarry Smith B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_7; 1950273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 1951273d9f13SBarry Smith break; 1952273d9f13SBarry Smith default: 1953273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_N; 1954273d9f13SBarry Smith B->ops->solve = MatSolve_SeqBAIJ_N; 1955273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_N; 1956273d9f13SBarry Smith break; 1957273d9f13SBarry Smith } 1958273d9f13SBarry Smith } 1959273d9f13SBarry Smith b->bs = bs; 1960273d9f13SBarry Smith b->mbs = mbs; 1961273d9f13SBarry Smith b->nbs = nbs; 1962b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 1963273d9f13SBarry Smith if (!nnz) { 1964435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1965273d9f13SBarry Smith else if (nz <= 0) nz = 1; 1966273d9f13SBarry Smith for (i=0; i<mbs; i++) b->imax[i] = nz; 1967273d9f13SBarry Smith nz = nz*mbs; 1968273d9f13SBarry Smith } else { 1969273d9f13SBarry Smith nz = 0; 1970273d9f13SBarry Smith for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 1971273d9f13SBarry Smith } 1972273d9f13SBarry Smith 1973273d9f13SBarry Smith /* allocate the matrix space */ 1974273d9f13SBarry Smith len = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int); 1975b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 1976273d9f13SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1977273d9f13SBarry Smith b->j = (int*)(b->a + nz*bs2); 1978273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 1979273d9f13SBarry Smith b->i = b->j + nz; 1980273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 1981273d9f13SBarry Smith 1982273d9f13SBarry Smith b->i[0] = 0; 1983273d9f13SBarry Smith for (i=1; i<mbs+1; i++) { 1984273d9f13SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 1985273d9f13SBarry Smith } 1986273d9f13SBarry Smith 1987273d9f13SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 198816d6aa21SSatish Balay ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 1989b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1990273d9f13SBarry Smith for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 1991273d9f13SBarry Smith 1992273d9f13SBarry Smith b->bs = bs; 1993273d9f13SBarry Smith b->bs2 = bs2; 1994273d9f13SBarry Smith b->mbs = mbs; 1995273d9f13SBarry Smith b->nz = 0; 1996273d9f13SBarry Smith b->maxnz = nz*bs2; 1997273d9f13SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1998273d9f13SBarry Smith PetscFunctionReturn(0); 1999273d9f13SBarry Smith } 20002593348eSBarry Smith 2001