1bba1ac68SSatish Balay /*$Id: baij.c,v 1.245 2001/08/07 03:02:55 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 */ 770f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h" 81a6a6d98SBarry Smith #include "src/vec/vecimpl.h" 91a6a6d98SBarry Smith #include "src/inline/spops.h" 10325e03aeSBarry Smith #include "petscsys.h" /*I "petscmat.h" I*/ 113b547af2SSatish Balay 1295d5f7c2SBarry Smith /* UGLY, ugly, ugly 1387828ca2SBarry Smith When MatScalar == PetscScalar the function MatSetValuesBlocked_SeqBAIJ_MatScalar() does 143477af42SKris Buschelman not exist. Otherwise ..._MatScalar() takes matrix dlements 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 2404929863SHong Zhang #if defined(PETSC_HAVE_DSCPACK) 2504929863SHong Zhang EXTERN int MatUseDSCPACK_MPIBAIJ(Mat); 2604929863SHong Zhang #endif 2795d5f7c2SBarry Smith 282d61bbb3SSatish Balay #define CHUNKSIZE 10 29de6a44a3SBarry Smith 30be5855fcSBarry Smith /* 31be5855fcSBarry Smith Checks for missing diagonals 32be5855fcSBarry Smith */ 334a2ae208SSatish Balay #undef __FUNCT__ 344a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqBAIJ" 35c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A) 36be5855fcSBarry Smith { 37be5855fcSBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 38883fce79SBarry Smith int *diag,*jj = a->j,i,ierr; 39be5855fcSBarry Smith 40be5855fcSBarry Smith PetscFunctionBegin; 41c4992f7dSBarry Smith ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr); 42883fce79SBarry Smith diag = a->diag; 430e8e8aceSBarry Smith for (i=0; i<a->mbs; i++) { 44be5855fcSBarry Smith if (jj[diag[i]] != i) { 4529bbc08cSBarry Smith SETERRQ1(1,"Matrix is missing diagonal number %d",i); 46be5855fcSBarry Smith } 47be5855fcSBarry Smith } 48be5855fcSBarry Smith PetscFunctionReturn(0); 49be5855fcSBarry Smith } 50be5855fcSBarry Smith 514a2ae208SSatish Balay #undef __FUNCT__ 524a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqBAIJ" 53c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A) 54de6a44a3SBarry Smith { 55de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 5682502324SSatish Balay int i,j,*diag,m = a->mbs,ierr; 57de6a44a3SBarry Smith 583a40ed3dSBarry Smith PetscFunctionBegin; 59883fce79SBarry Smith if (a->diag) PetscFunctionReturn(0); 60883fce79SBarry Smith 61b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr); 62b0a32e0cSBarry Smith PetscLogObjectMemory(A,(m+1)*sizeof(int)); 637fc0212eSBarry Smith for (i=0; i<m; i++) { 64ecc615b2SBarry Smith diag[i] = a->i[i+1]; 65de6a44a3SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 66de6a44a3SBarry Smith if (a->j[j] == i) { 67de6a44a3SBarry Smith diag[i] = j; 68de6a44a3SBarry Smith break; 69de6a44a3SBarry Smith } 70de6a44a3SBarry Smith } 71de6a44a3SBarry Smith } 72de6a44a3SBarry Smith a->diag = diag; 733a40ed3dSBarry Smith PetscFunctionReturn(0); 74de6a44a3SBarry Smith } 752593348eSBarry Smith 762593348eSBarry Smith 77ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 783b2fbd54SBarry Smith 794a2ae208SSatish Balay #undef __FUNCT__ 804a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqBAIJ" 810e6d2581SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 823b2fbd54SBarry Smith { 833b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 843b2fbd54SBarry Smith int ierr,n = a->mbs,i; 853b2fbd54SBarry Smith 863a40ed3dSBarry Smith PetscFunctionBegin; 873b2fbd54SBarry Smith *nn = n; 883a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 893b2fbd54SBarry Smith if (symmetric) { 903b2fbd54SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 913b2fbd54SBarry Smith } else if (oshift == 1) { 923b2fbd54SBarry Smith /* temporarily add 1 to i and j indices */ 93435da068SBarry Smith int nz = a->i[n]; 943b2fbd54SBarry Smith for (i=0; i<nz; i++) a->j[i]++; 953b2fbd54SBarry Smith for (i=0; i<n+1; i++) a->i[i]++; 963b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 973b2fbd54SBarry Smith } else { 983b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 993b2fbd54SBarry Smith } 1003b2fbd54SBarry Smith 1013a40ed3dSBarry Smith PetscFunctionReturn(0); 1023b2fbd54SBarry Smith } 1033b2fbd54SBarry Smith 1044a2ae208SSatish Balay #undef __FUNCT__ 1054a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqBAIJ" 106435da068SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 1073b2fbd54SBarry Smith { 1083b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 109606d414cSSatish Balay int i,n = a->mbs,ierr; 1103b2fbd54SBarry Smith 1113a40ed3dSBarry Smith PetscFunctionBegin; 1123a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1133b2fbd54SBarry Smith if (symmetric) { 114606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 115606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 116af5da2bfSBarry Smith } else if (oshift == 1) { 117435da068SBarry Smith int nz = a->i[n]-1; 1183b2fbd54SBarry Smith for (i=0; i<nz; i++) a->j[i]--; 1193b2fbd54SBarry Smith for (i=0; i<n+1; i++) a->i[i]--; 1203b2fbd54SBarry Smith } 1213a40ed3dSBarry Smith PetscFunctionReturn(0); 1223b2fbd54SBarry Smith } 1233b2fbd54SBarry Smith 1244a2ae208SSatish Balay #undef __FUNCT__ 1254a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqBAIJ" 1262d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs) 1272d61bbb3SSatish Balay { 1282d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data; 1292d61bbb3SSatish Balay 1302d61bbb3SSatish Balay PetscFunctionBegin; 1312d61bbb3SSatish Balay *bs = baij->bs; 1322d61bbb3SSatish Balay PetscFunctionReturn(0); 1332d61bbb3SSatish Balay } 1342d61bbb3SSatish Balay 1352d61bbb3SSatish Balay 1364a2ae208SSatish Balay #undef __FUNCT__ 1374a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqBAIJ" 138e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A) 1392d61bbb3SSatish Balay { 1402d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 141e51c0b9cSSatish Balay int ierr; 1422d61bbb3SSatish Balay 143433994e6SBarry Smith PetscFunctionBegin; 144aa482453SBarry Smith #if defined(PETSC_USE_LOG) 145b0a32e0cSBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 1462d61bbb3SSatish Balay #endif 147606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 148606d414cSSatish Balay if (!a->singlemalloc) { 149606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 150606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 151606d414cSSatish Balay } 152c38d4ed2SBarry Smith if (a->row) { 153c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 154c38d4ed2SBarry Smith } 155c38d4ed2SBarry Smith if (a->col) { 156c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 157c38d4ed2SBarry Smith } 158606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 159606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 160606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 161606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 162606d414cSSatish Balay if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);} 163e51c0b9cSSatish Balay if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 164606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 165563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 166563b5814SBarry Smith if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);} 167563b5814SBarry Smith #endif 168606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 1692d61bbb3SSatish Balay PetscFunctionReturn(0); 1702d61bbb3SSatish Balay } 1712d61bbb3SSatish Balay 1724a2ae208SSatish Balay #undef __FUNCT__ 1734a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqBAIJ" 1742d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1752d61bbb3SSatish Balay { 1762d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1772d61bbb3SSatish Balay 1782d61bbb3SSatish Balay PetscFunctionBegin; 179aa275fccSKris Buschelman switch (op) { 180aa275fccSKris Buschelman case MAT_ROW_ORIENTED: 181aa275fccSKris Buschelman a->roworiented = PETSC_TRUE; 182aa275fccSKris Buschelman break; 183aa275fccSKris Buschelman case MAT_COLUMN_ORIENTED: 184aa275fccSKris Buschelman a->roworiented = PETSC_FALSE; 185aa275fccSKris Buschelman break; 186aa275fccSKris Buschelman case MAT_COLUMNS_SORTED: 187aa275fccSKris Buschelman a->sorted = PETSC_TRUE; 188aa275fccSKris Buschelman break; 189aa275fccSKris Buschelman case MAT_COLUMNS_UNSORTED: 190aa275fccSKris Buschelman a->sorted = PETSC_FALSE; 191aa275fccSKris Buschelman break; 192aa275fccSKris Buschelman case MAT_KEEP_ZEROED_ROWS: 193aa275fccSKris Buschelman a->keepzeroedrows = PETSC_TRUE; 194aa275fccSKris Buschelman break; 195aa275fccSKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 196aa275fccSKris Buschelman a->nonew = 1; 197aa275fccSKris Buschelman break; 198aa275fccSKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 199aa275fccSKris Buschelman a->nonew = -1; 200aa275fccSKris Buschelman break; 201aa275fccSKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 202aa275fccSKris Buschelman a->nonew = -2; 203aa275fccSKris Buschelman break; 204aa275fccSKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 205aa275fccSKris Buschelman a->nonew = 0; 206aa275fccSKris Buschelman break; 207aa275fccSKris Buschelman case MAT_ROWS_SORTED: 208aa275fccSKris Buschelman case MAT_ROWS_UNSORTED: 209aa275fccSKris Buschelman case MAT_YES_NEW_DIAGONALS: 210aa275fccSKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 211aa275fccSKris Buschelman case MAT_USE_HASH_TABLE: 212b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 213aa275fccSKris Buschelman break; 214aa275fccSKris Buschelman case MAT_NO_NEW_DIAGONALS: 21529bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 216bd648c37SKris Buschelman case MAT_USE_SINGLE_PRECISION_SOLVES: 217bd648c37SKris Buschelman if (a->bs==4) { 21894ee7fc8SKris Buschelman PetscTruth sse_enabled_local,sse_enabled_global; 219bd648c37SKris Buschelman int ierr; 22094ee7fc8SKris Buschelman 22194ee7fc8SKris Buschelman sse_enabled_local = PETSC_FALSE; 22294ee7fc8SKris Buschelman sse_enabled_global = PETSC_FALSE; 22394ee7fc8SKris Buschelman 22494ee7fc8SKris Buschelman ierr = PetscSSEIsEnabled(A->comm,&sse_enabled_local,&sse_enabled_global);CHKERRQ(ierr); 225e64df4b9SKris Buschelman #if defined(PETSC_HAVE_SSE) 22694ee7fc8SKris Buschelman if (sse_enabled_local) { 22754138f6bSKris Buschelman a->single_precision_solves = PETSC_TRUE; 22854138f6bSKris Buschelman A->ops->solve = MatSolve_SeqBAIJ_Update; 22954138f6bSKris Buschelman A->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_Update; 230cf242676SKris Buschelman PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES set\n"); 23154138f6bSKris Buschelman break; 23294ee7fc8SKris Buschelman } else { 23394ee7fc8SKris Buschelman PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n"); 2348661488fSKris Buschelman } 235e64df4b9SKris Buschelman #else 236bd648c37SKris Buschelman PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n"); 237e64df4b9SKris Buschelman #endif 238bd648c37SKris Buschelman } 239bd648c37SKris Buschelman break; 240aa275fccSKris Buschelman default: 24129bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"unknown option"); 2422d61bbb3SSatish Balay } 2432d61bbb3SSatish Balay PetscFunctionReturn(0); 2442d61bbb3SSatish Balay } 2452d61bbb3SSatish Balay 2464a2ae208SSatish Balay #undef __FUNCT__ 2474a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ" 24887828ca2SBarry Smith int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 2492d61bbb3SSatish Balay { 2502d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 25182502324SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr; 2523f1db9ecSBarry Smith MatScalar *aa,*aa_i; 25387828ca2SBarry Smith PetscScalar *v_i; 2542d61bbb3SSatish Balay 2552d61bbb3SSatish Balay PetscFunctionBegin; 2562d61bbb3SSatish Balay bs = a->bs; 2572d61bbb3SSatish Balay ai = a->i; 2582d61bbb3SSatish Balay aj = a->j; 2592d61bbb3SSatish Balay aa = a->a; 2602d61bbb3SSatish Balay bs2 = a->bs2; 2612d61bbb3SSatish Balay 262273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range"); 2632d61bbb3SSatish Balay 2642d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2652d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2662d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2672d61bbb3SSatish Balay *nz = bs*M; 2682d61bbb3SSatish Balay 2692d61bbb3SSatish Balay if (v) { 2702d61bbb3SSatish Balay *v = 0; 2712d61bbb3SSatish Balay if (*nz) { 27287828ca2SBarry Smith ierr = PetscMalloc((*nz)*sizeof(PetscScalar),v);CHKERRQ(ierr); 2732d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2742d61bbb3SSatish Balay v_i = *v + i*bs; 2752d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2762d61bbb3SSatish Balay for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];} 2772d61bbb3SSatish Balay } 2782d61bbb3SSatish Balay } 2792d61bbb3SSatish Balay } 2802d61bbb3SSatish Balay 2812d61bbb3SSatish Balay if (idx) { 2822d61bbb3SSatish Balay *idx = 0; 2832d61bbb3SSatish Balay if (*nz) { 284b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr); 2852d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2862d61bbb3SSatish Balay idx_i = *idx + i*bs; 2872d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2882d61bbb3SSatish Balay for (j=0; j<bs; j++) {idx_i[j] = itmp++;} 2892d61bbb3SSatish Balay } 2902d61bbb3SSatish Balay } 2912d61bbb3SSatish Balay } 2922d61bbb3SSatish Balay PetscFunctionReturn(0); 2932d61bbb3SSatish Balay } 2942d61bbb3SSatish Balay 2954a2ae208SSatish Balay #undef __FUNCT__ 2964a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ" 29787828ca2SBarry Smith int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 2982d61bbb3SSatish Balay { 299606d414cSSatish Balay int ierr; 300606d414cSSatish Balay 3012d61bbb3SSatish Balay PetscFunctionBegin; 302606d414cSSatish Balay if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 303606d414cSSatish Balay if (v) {if (*v) {ierr = PetscFree(*v);CHKERRQ(ierr);}} 3042d61bbb3SSatish Balay PetscFunctionReturn(0); 3052d61bbb3SSatish Balay } 3062d61bbb3SSatish Balay 3074a2ae208SSatish Balay #undef __FUNCT__ 3084a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ" 3092d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 3102d61bbb3SSatish Balay { 3112d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 3122d61bbb3SSatish Balay Mat C; 3132d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 314273d9f13SBarry Smith int *rows,*cols,bs2=a->bs2; 31587828ca2SBarry Smith PetscScalar *array; 3162d61bbb3SSatish Balay 3172d61bbb3SSatish Balay PetscFunctionBegin; 31829bbc08cSBarry Smith if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place"); 319b0a32e0cSBarry Smith ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr); 320549d3d68SSatish Balay ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr); 3212d61bbb3SSatish Balay 322375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 32387828ca2SBarry Smith ierr = PetscMalloc(a->bs2*a->nz*sizeof(PetscScalar),&array);CHKERRQ(ierr); 32487828ca2SBarry Smith for (i=0; i<a->bs2*a->nz; i++) array[i] = (PetscScalar)a->a[i]; 325375fe846SBarry Smith #else 3263eda8832SBarry Smith array = a->a; 327375fe846SBarry Smith #endif 328375fe846SBarry Smith 3292d61bbb3SSatish Balay for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1; 330273d9f13SBarry Smith ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr); 331606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 332b0a32e0cSBarry Smith ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr); 3332d61bbb3SSatish Balay cols = rows + bs; 3342d61bbb3SSatish Balay for (i=0; i<mbs; i++) { 3352d61bbb3SSatish Balay cols[0] = i*bs; 3362d61bbb3SSatish Balay for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1; 3372d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 3382d61bbb3SSatish Balay for (j=0; j<len; j++) { 3392d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 3402d61bbb3SSatish Balay for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1; 3412d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr); 3422d61bbb3SSatish Balay array += bs2; 3432d61bbb3SSatish Balay } 3442d61bbb3SSatish Balay } 345606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 346375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 347375fe846SBarry Smith ierr = PetscFree(array); 348375fe846SBarry Smith #endif 3492d61bbb3SSatish Balay 3502d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3512d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3522d61bbb3SSatish Balay 353c4992f7dSBarry Smith if (B) { 3542d61bbb3SSatish Balay *B = C; 3552d61bbb3SSatish Balay } else { 356273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 3572d61bbb3SSatish Balay } 3582d61bbb3SSatish Balay PetscFunctionReturn(0); 3592d61bbb3SSatish Balay } 3602d61bbb3SSatish Balay 3614a2ae208SSatish Balay #undef __FUNCT__ 3624a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary" 363b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer) 3642593348eSBarry Smith { 365b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 3669df24120SSatish Balay int i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 36787828ca2SBarry Smith PetscScalar *aa; 368ce6f0cecSBarry Smith FILE *file; 3692593348eSBarry Smith 3703a40ed3dSBarry Smith PetscFunctionBegin; 371b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 372b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 373552e946dSBarry Smith col_lens[0] = MAT_FILE_COOKIE; 3743b2fbd54SBarry Smith 375273d9f13SBarry Smith col_lens[1] = A->m; 376273d9f13SBarry Smith col_lens[2] = A->n; 3777e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3782593348eSBarry Smith 3792593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 380b6490206SBarry Smith count = 0; 381b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 382b6490206SBarry Smith for (j=0; j<bs; j++) { 383b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 384b6490206SBarry Smith } 3852593348eSBarry Smith } 386273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 387606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 3882593348eSBarry Smith 3892593348eSBarry Smith /* store column indices (zero start index) */ 390b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr); 391b6490206SBarry Smith count = 0; 392b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 393b6490206SBarry Smith for (j=0; j<bs; j++) { 394b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 395b6490206SBarry Smith for (l=0; l<bs; l++) { 396b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 3972593348eSBarry Smith } 3982593348eSBarry Smith } 399b6490206SBarry Smith } 400b6490206SBarry Smith } 4010752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr); 402606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 4032593348eSBarry Smith 4042593348eSBarry Smith /* store nonzero values */ 40587828ca2SBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(PetscScalar),&aa);CHKERRQ(ierr); 406b6490206SBarry Smith count = 0; 407b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 408b6490206SBarry Smith for (j=0; j<bs; j++) { 409b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 410b6490206SBarry Smith for (l=0; l<bs; l++) { 4117e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 412b6490206SBarry Smith } 413b6490206SBarry Smith } 414b6490206SBarry Smith } 415b6490206SBarry Smith } 4160752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 417606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 418ce6f0cecSBarry Smith 419b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 420ce6f0cecSBarry Smith if (file) { 421ce6f0cecSBarry Smith fprintf(file,"-matload_block_size %d\n",a->bs); 422ce6f0cecSBarry Smith } 4233a40ed3dSBarry Smith PetscFunctionReturn(0); 4242593348eSBarry Smith } 4252593348eSBarry Smith 42604929863SHong Zhang extern int MatMPIBAIJFactorInfo_DSCPACK(Mat,PetscViewer); 42704929863SHong Zhang 4284a2ae208SSatish Balay #undef __FUNCT__ 4294a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII" 430b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer) 4312593348eSBarry Smith { 432b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 433fb9695e5SSatish Balay int ierr,i,j,bs = a->bs,k,l,bs2=a->bs2; 434f3ef73ceSBarry Smith PetscViewerFormat format; 4352593348eSBarry Smith 4363a40ed3dSBarry Smith PetscFunctionBegin; 437b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 438fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) { 439b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %d\n",bs);CHKERRQ(ierr); 440fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 441bcd9e38bSBarry Smith Mat aij; 442bcd9e38bSBarry Smith ierr = MatConvert(A,MATSEQAIJ,&aij);CHKERRQ(ierr); 443bcd9e38bSBarry Smith ierr = MatView(aij,viewer);CHKERRQ(ierr); 444bcd9e38bSBarry Smith ierr = MatDestroy(aij);CHKERRQ(ierr); 44504929863SHong Zhang } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 44604929863SHong Zhang #if defined(PETSC_HAVE_DSCPACK) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX) 44704929863SHong Zhang ierr = MatMPIBAIJFactorInfo_DSCPACK(A,viewer);CHKERRQ(ierr); 44804929863SHong Zhang #endif 44904929863SHong Zhang PetscFunctionReturn(0); 450fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 451b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 45244cd7ae7SLois Curfman McInnes for (i=0; i<a->mbs; i++) { 45344cd7ae7SLois Curfman McInnes for (j=0; j<bs; j++) { 454b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 45544cd7ae7SLois Curfman McInnes for (k=a->i[i]; k<a->i[i+1]; k++) { 45644cd7ae7SLois Curfman McInnes for (l=0; l<bs; l++) { 457aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4580e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 45962b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %gi) ",bs*a->j[k]+l, 4600e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4610e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 46262b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %gi) ",bs*a->j[k]+l, 4630e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4640e6d2581SBarry Smith } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 46562b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4660ef38995SBarry Smith } 46744cd7ae7SLois Curfman McInnes #else 4680ef38995SBarry Smith if (a->a[bs2*k + l*bs + j] != 0.0) { 46962b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 4700ef38995SBarry Smith } 47144cd7ae7SLois Curfman McInnes #endif 47244cd7ae7SLois Curfman McInnes } 47344cd7ae7SLois Curfman McInnes } 474b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 47544cd7ae7SLois Curfman McInnes } 47644cd7ae7SLois Curfman McInnes } 477b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4780ef38995SBarry Smith } else { 479b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 480b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 481b6490206SBarry Smith for (j=0; j<bs; j++) { 482b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 483b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 484b6490206SBarry Smith for (l=0; l<bs; l++) { 485aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4860e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 48762b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i) ",bs*a->j[k]+l, 4880e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4890e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 49062b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i) ",bs*a->j[k]+l, 4910e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4920ef38995SBarry Smith } else { 49362b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 49488685aaeSLois Curfman McInnes } 49588685aaeSLois Curfman McInnes #else 49662b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 49788685aaeSLois Curfman McInnes #endif 4982593348eSBarry Smith } 4992593348eSBarry Smith } 500b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 5012593348eSBarry Smith } 5022593348eSBarry Smith } 503b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 504b6490206SBarry Smith } 505b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 5063a40ed3dSBarry Smith PetscFunctionReturn(0); 5072593348eSBarry Smith } 5082593348eSBarry Smith 5094a2ae208SSatish Balay #undef __FUNCT__ 5104a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom" 511b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 5123270192aSSatish Balay { 51377ed5343SBarry Smith Mat A = (Mat) Aa; 5143270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ*)A->data; 515b65db4caSBarry Smith int row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2; 5160e6d2581SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 5173f1db9ecSBarry Smith MatScalar *aa; 518b0a32e0cSBarry Smith PetscViewer viewer; 5193270192aSSatish Balay 5203a40ed3dSBarry Smith PetscFunctionBegin; 5213270192aSSatish Balay 522b65db4caSBarry Smith /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/ 52377ed5343SBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 52477ed5343SBarry Smith 525b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 52677ed5343SBarry Smith 5273270192aSSatish Balay /* loop over matrix elements drawing boxes */ 528b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 5293270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5303270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 531273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5323270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5333270192aSSatish Balay aa = a->a + j*bs2; 5343270192aSSatish Balay for (k=0; k<bs; k++) { 5353270192aSSatish Balay for (l=0; l<bs; l++) { 5360e6d2581SBarry Smith if (PetscRealPart(*aa++) >= 0.) continue; 537b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5383270192aSSatish Balay } 5393270192aSSatish Balay } 5403270192aSSatish Balay } 5413270192aSSatish Balay } 542b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 5433270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5443270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 545273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5463270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5473270192aSSatish Balay aa = a->a + j*bs2; 5483270192aSSatish Balay for (k=0; k<bs; k++) { 5493270192aSSatish Balay for (l=0; l<bs; l++) { 5500e6d2581SBarry Smith if (PetscRealPart(*aa++) != 0.) continue; 551b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5523270192aSSatish Balay } 5533270192aSSatish Balay } 5543270192aSSatish Balay } 5553270192aSSatish Balay } 5563270192aSSatish Balay 557b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 5583270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5593270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 560273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5613270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5623270192aSSatish Balay aa = a->a + j*bs2; 5633270192aSSatish Balay for (k=0; k<bs; k++) { 5643270192aSSatish Balay for (l=0; l<bs; l++) { 5650e6d2581SBarry Smith if (PetscRealPart(*aa++) <= 0.) continue; 566b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5673270192aSSatish Balay } 5683270192aSSatish Balay } 5693270192aSSatish Balay } 5703270192aSSatish Balay } 57177ed5343SBarry Smith PetscFunctionReturn(0); 57277ed5343SBarry Smith } 5733270192aSSatish Balay 5744a2ae208SSatish Balay #undef __FUNCT__ 5754a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw" 576b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer) 57777ed5343SBarry Smith { 5787dce120fSSatish Balay int ierr; 5790e6d2581SBarry Smith PetscReal xl,yl,xr,yr,w,h; 580b0a32e0cSBarry Smith PetscDraw draw; 58177ed5343SBarry Smith PetscTruth isnull; 5823270192aSSatish Balay 58377ed5343SBarry Smith PetscFunctionBegin; 58477ed5343SBarry Smith 585b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 586b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 58777ed5343SBarry Smith 58877ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 589273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 59077ed5343SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 591b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 592b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 59377ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5943a40ed3dSBarry Smith PetscFunctionReturn(0); 5953270192aSSatish Balay } 5963270192aSSatish Balay 5974a2ae208SSatish Balay #undef __FUNCT__ 5984a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ" 599b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer) 6002593348eSBarry Smith { 60119bcc07fSBarry Smith int ierr; 6026831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 6032593348eSBarry Smith 6043a40ed3dSBarry Smith PetscFunctionBegin; 605b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 606b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 607fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 608fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 6090f5bd95cSBarry Smith if (issocket) { 61029bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported"); 6110f5bd95cSBarry Smith } else if (isascii){ 6123a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 6130f5bd95cSBarry Smith } else if (isbinary) { 6143a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 6150f5bd95cSBarry Smith } else if (isdraw) { 6163a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 6175cd90555SBarry Smith } else { 61829bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name); 6192593348eSBarry Smith } 6203a40ed3dSBarry Smith PetscFunctionReturn(0); 6212593348eSBarry Smith } 622b6490206SBarry Smith 623cd0e1443SSatish Balay 6244a2ae208SSatish Balay #undef __FUNCT__ 6254a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ" 62687828ca2SBarry Smith int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v) 627cd0e1443SSatish Balay { 628cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 6292d61bbb3SSatish Balay int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 6302d61bbb3SSatish Balay int *ai = a->i,*ailen = a->ilen; 6312d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 6323f1db9ecSBarry Smith MatScalar *ap,*aa = a->a,zero = 0.0; 633cd0e1443SSatish Balay 6343a40ed3dSBarry Smith PetscFunctionBegin; 6352d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over rows */ 636cd0e1443SSatish Balay row = im[k]; brow = row/bs; 63729bbc08cSBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row"); 638273d9f13SBarry Smith if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 6392d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 6402c3acbe9SBarry Smith nrow = ailen[brow]; 6412d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over columns */ 64229bbc08cSBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column"); 643273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 6442d61bbb3SSatish Balay col = in[l] ; 6452d61bbb3SSatish Balay bcol = col/bs; 6462d61bbb3SSatish Balay cidx = col%bs; 6472d61bbb3SSatish Balay ridx = row%bs; 6482d61bbb3SSatish Balay high = nrow; 6492d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6502d61bbb3SSatish Balay while (high-low > 5) { 651cd0e1443SSatish Balay t = (low+high)/2; 652cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 653cd0e1443SSatish Balay else low = t; 654cd0e1443SSatish Balay } 655cd0e1443SSatish Balay for (i=low; i<high; i++) { 656cd0e1443SSatish Balay if (rp[i] > bcol) break; 657cd0e1443SSatish Balay if (rp[i] == bcol) { 6582d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6592d61bbb3SSatish Balay goto finished; 660cd0e1443SSatish Balay } 661cd0e1443SSatish Balay } 6622d61bbb3SSatish Balay *v++ = zero; 6632d61bbb3SSatish Balay finished:; 664cd0e1443SSatish Balay } 665cd0e1443SSatish Balay } 6663a40ed3dSBarry Smith PetscFunctionReturn(0); 667cd0e1443SSatish Balay } 668cd0e1443SSatish Balay 66995d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 6704a2ae208SSatish Balay #undef __FUNCT__ 6714a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ" 67287828ca2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,PetscScalar *v,InsertMode addv) 67395d5f7c2SBarry Smith { 674563b5814SBarry Smith Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data; 675563b5814SBarry Smith int ierr,i,N = m*n*b->bs2; 676563b5814SBarry Smith MatScalar *vsingle; 67795d5f7c2SBarry Smith 67895d5f7c2SBarry Smith PetscFunctionBegin; 679563b5814SBarry Smith if (N > b->setvalueslen) { 680563b5814SBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 681b0a32e0cSBarry Smith ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 682563b5814SBarry Smith b->setvalueslen = N; 683563b5814SBarry Smith } 684563b5814SBarry Smith vsingle = b->setvaluescopy; 68595d5f7c2SBarry Smith for (i=0; i<N; i++) { 68695d5f7c2SBarry Smith vsingle[i] = v[i]; 68795d5f7c2SBarry Smith } 68895d5f7c2SBarry Smith ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 68995d5f7c2SBarry Smith PetscFunctionReturn(0); 69095d5f7c2SBarry Smith } 69195d5f7c2SBarry Smith #endif 69295d5f7c2SBarry Smith 6932d61bbb3SSatish Balay 6944a2ae208SSatish Balay #undef __FUNCT__ 6954a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ" 69695d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is) 69792c4ed94SBarry Smith { 69892c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 6998a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 700273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 701549d3d68SSatish Balay int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr; 702273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 70395d5f7c2SBarry Smith MatScalar *value = v,*ap,*aa = a->a,*bap; 70492c4ed94SBarry Smith 7053a40ed3dSBarry Smith PetscFunctionBegin; 7060e324ae4SSatish Balay if (roworiented) { 7070e324ae4SSatish Balay stepval = (n-1)*bs; 7080e324ae4SSatish Balay } else { 7090e324ae4SSatish Balay stepval = (m-1)*bs; 7100e324ae4SSatish Balay } 71192c4ed94SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 71292c4ed94SBarry Smith row = im[k]; 7135ef9f2a5SBarry Smith if (row < 0) continue; 714aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 71529bbc08cSBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 71692c4ed94SBarry Smith #endif 71792c4ed94SBarry Smith rp = aj + ai[row]; 71892c4ed94SBarry Smith ap = aa + bs2*ai[row]; 71992c4ed94SBarry Smith rmax = imax[row]; 72092c4ed94SBarry Smith nrow = ailen[row]; 72192c4ed94SBarry Smith low = 0; 72292c4ed94SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 7235ef9f2a5SBarry Smith if (in[l] < 0) continue; 724aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 72529bbc08cSBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 72692c4ed94SBarry Smith #endif 72792c4ed94SBarry Smith col = in[l]; 72892c4ed94SBarry Smith if (roworiented) { 7290e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 7300e324ae4SSatish Balay } else { 7310e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 73292c4ed94SBarry Smith } 73392c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 73492c4ed94SBarry Smith while (high-low > 7) { 73592c4ed94SBarry Smith t = (low+high)/2; 73692c4ed94SBarry Smith if (rp[t] > col) high = t; 73792c4ed94SBarry Smith else low = t; 73892c4ed94SBarry Smith } 73992c4ed94SBarry Smith for (i=low; i<high; i++) { 74092c4ed94SBarry Smith if (rp[i] > col) break; 74192c4ed94SBarry Smith if (rp[i] == col) { 7428a84c255SSatish Balay bap = ap + bs2*i; 7430e324ae4SSatish Balay if (roworiented) { 7448a84c255SSatish Balay if (is == ADD_VALUES) { 745dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 746dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7478a84c255SSatish Balay bap[jj] += *value++; 748dd9472c6SBarry Smith } 749dd9472c6SBarry Smith } 7500e324ae4SSatish Balay } else { 751dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 752dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7530e324ae4SSatish Balay bap[jj] = *value++; 7548a84c255SSatish Balay } 755dd9472c6SBarry Smith } 756dd9472c6SBarry Smith } 7570e324ae4SSatish Balay } else { 7580e324ae4SSatish Balay if (is == ADD_VALUES) { 759dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 760dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7610e324ae4SSatish Balay *bap++ += *value++; 762dd9472c6SBarry Smith } 763dd9472c6SBarry Smith } 7640e324ae4SSatish Balay } else { 765dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 766dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7670e324ae4SSatish Balay *bap++ = *value++; 7680e324ae4SSatish Balay } 7698a84c255SSatish Balay } 770dd9472c6SBarry Smith } 771dd9472c6SBarry Smith } 772f1241b54SBarry Smith goto noinsert2; 77392c4ed94SBarry Smith } 77492c4ed94SBarry Smith } 77589280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 77629bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 77792c4ed94SBarry Smith if (nrow >= rmax) { 77892c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 77992c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 7803f1db9ecSBarry Smith MatScalar *new_a; 78192c4ed94SBarry Smith 78229bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 78389280ab3SLois Curfman McInnes 78492c4ed94SBarry Smith /* malloc new storage space */ 7853f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 786b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 78792c4ed94SBarry Smith new_j = (int*)(new_a + bs2*new_nz); 78892c4ed94SBarry Smith new_i = new_j + new_nz; 78992c4ed94SBarry Smith 79092c4ed94SBarry Smith /* copy over old data into new slots */ 79192c4ed94SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 79292c4ed94SBarry Smith for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 793549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr); 79492c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 795549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr); 796549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 797549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 798549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 79992c4ed94SBarry Smith /* free up old matrix storage */ 800606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 801606d414cSSatish Balay if (!a->singlemalloc) { 802606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 803606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 804606d414cSSatish Balay } 80592c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 806c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 80792c4ed94SBarry Smith 80892c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 80992c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 810b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 81192c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 81292c4ed94SBarry Smith a->reallocs++; 81392c4ed94SBarry Smith a->nz++; 81492c4ed94SBarry Smith } 81592c4ed94SBarry Smith N = nrow++ - 1; 81692c4ed94SBarry Smith /* shift up all the later entries in this row */ 81792c4ed94SBarry Smith for (ii=N; ii>=i; ii--) { 81892c4ed94SBarry Smith rp[ii+1] = rp[ii]; 819549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 82092c4ed94SBarry Smith } 821549d3d68SSatish Balay if (N >= i) { 822549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 823549d3d68SSatish Balay } 82492c4ed94SBarry Smith rp[i] = col; 8258a84c255SSatish Balay bap = ap + bs2*i; 8260e324ae4SSatish Balay if (roworiented) { 827dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 828dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 8290e324ae4SSatish Balay bap[jj] = *value++; 830dd9472c6SBarry Smith } 831dd9472c6SBarry Smith } 8320e324ae4SSatish Balay } else { 833dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 834dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 8350e324ae4SSatish Balay *bap++ = *value++; 8360e324ae4SSatish Balay } 837dd9472c6SBarry Smith } 838dd9472c6SBarry Smith } 839f1241b54SBarry Smith noinsert2:; 84092c4ed94SBarry Smith low = i; 84192c4ed94SBarry Smith } 84292c4ed94SBarry Smith ailen[row] = nrow; 84392c4ed94SBarry Smith } 8443a40ed3dSBarry Smith PetscFunctionReturn(0); 84592c4ed94SBarry Smith } 84692c4ed94SBarry Smith 8474a2ae208SSatish Balay #undef __FUNCT__ 8484a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ" 8498f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 850584200bdSSatish Balay { 851584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 852584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 853273d9f13SBarry Smith int m = A->m,*ip,N,*ailen = a->ilen; 854549d3d68SSatish Balay int mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr; 8553f1db9ecSBarry Smith MatScalar *aa = a->a,*ap; 856a56a16c8SHong Zhang #if defined(PETSC_HAVE_DSCPACK) 857a56a16c8SHong Zhang PetscTruth flag; 858a56a16c8SHong Zhang #endif 859584200bdSSatish Balay 8603a40ed3dSBarry Smith PetscFunctionBegin; 8613a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 862584200bdSSatish Balay 86343ee02c3SBarry Smith if (m) rmax = ailen[0]; 864584200bdSSatish Balay for (i=1; i<mbs; i++) { 865584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 866584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 867d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 868584200bdSSatish Balay if (fshift) { 869a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 870584200bdSSatish Balay N = ailen[i]; 871584200bdSSatish Balay for (j=0; j<N; j++) { 872584200bdSSatish Balay ip[j-fshift] = ip[j]; 873549d3d68SSatish Balay ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr); 874584200bdSSatish Balay } 875584200bdSSatish Balay } 876584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 877584200bdSSatish Balay } 878584200bdSSatish Balay if (mbs) { 879584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 880584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 881584200bdSSatish Balay } 882584200bdSSatish Balay /* reset ilen and imax for each row */ 883584200bdSSatish Balay for (i=0; i<mbs; i++) { 884584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 885584200bdSSatish Balay } 886a7c10996SSatish Balay a->nz = ai[mbs]; 887584200bdSSatish Balay 888584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 889584200bdSSatish Balay if (fshift && a->diag) { 890606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 891b424e231SHong Zhang PetscLogObjectMemory(A,-(mbs+1)*sizeof(int)); 892584200bdSSatish Balay a->diag = 0; 893584200bdSSatish Balay } 894bba1ac68SSatish Balay PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",m,A->n,a->bs,fshift*bs2,a->nz*bs2); 895bba1ac68SSatish Balay PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",a->reallocs); 896b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 897e2f3b5e9SSatish Balay a->reallocs = 0; 8980e6d2581SBarry Smith A->info.nz_unneeded = (PetscReal)fshift*bs2; 899*cf4441caSHong Zhang 900a56a16c8SHong Zhang #if defined(PETSC_HAVE_DSCPACK) 901a56a16c8SHong Zhang ierr = PetscOptionsHasName(PETSC_NULL,"-mat_baij_dscpack",&flag);CHKERRQ(ierr); 902a56a16c8SHong Zhang if (flag) { ierr = MatUseDSCPACK_MPIBAIJ(A);CHKERRQ(ierr); } 903a56a16c8SHong Zhang #endif 904a56a16c8SHong Zhang 9053a40ed3dSBarry Smith PetscFunctionReturn(0); 906584200bdSSatish Balay } 907584200bdSSatish Balay 9085a838052SSatish Balay 909bea157c4SSatish Balay 910bea157c4SSatish Balay /* 911bea157c4SSatish Balay This function returns an array of flags which indicate the locations of contiguous 912bea157c4SSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 913bea157c4SSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 914bea157c4SSatish Balay Assume: sizes should be long enough to hold all the values. 915bea157c4SSatish Balay */ 9164a2ae208SSatish Balay #undef __FUNCT__ 9174a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks" 918bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max) 919d9b7c43dSSatish Balay { 920bea157c4SSatish Balay int i,j,k,row; 921bea157c4SSatish Balay PetscTruth flg; 9223a40ed3dSBarry Smith 923433994e6SBarry Smith PetscFunctionBegin; 924bea157c4SSatish Balay for (i=0,j=0; i<n; j++) { 925bea157c4SSatish Balay row = idx[i]; 926bea157c4SSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 927bea157c4SSatish Balay sizes[j] = 1; 928bea157c4SSatish Balay i++; 929e4fda26cSSatish Balay } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */ 930bea157c4SSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 931bea157c4SSatish Balay i++; 932bea157c4SSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 933bea157c4SSatish Balay flg = PETSC_TRUE; 934bea157c4SSatish Balay for (k=1; k<bs; k++) { 935bea157c4SSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 936bea157c4SSatish Balay flg = PETSC_FALSE; 937bea157c4SSatish Balay break; 938d9b7c43dSSatish Balay } 939bea157c4SSatish Balay } 940bea157c4SSatish Balay if (flg == PETSC_TRUE) { /* No break in the bs */ 941bea157c4SSatish Balay sizes[j] = bs; 942bea157c4SSatish Balay i+= bs; 943bea157c4SSatish Balay } else { 944bea157c4SSatish Balay sizes[j] = 1; 945bea157c4SSatish Balay i++; 946bea157c4SSatish Balay } 947bea157c4SSatish Balay } 948bea157c4SSatish Balay } 949bea157c4SSatish Balay *bs_max = j; 9503a40ed3dSBarry Smith PetscFunctionReturn(0); 951d9b7c43dSSatish Balay } 952d9b7c43dSSatish Balay 9534a2ae208SSatish Balay #undef __FUNCT__ 9544a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ" 95587828ca2SBarry Smith int MatZeroRows_SeqBAIJ(Mat A,IS is,PetscScalar *diag) 956d9b7c43dSSatish Balay { 957d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 958b6815fffSBarry Smith int ierr,i,j,k,count,is_n,*is_idx,*rows; 959bea157c4SSatish Balay int bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max; 96087828ca2SBarry Smith PetscScalar zero = 0.0; 9613f1db9ecSBarry Smith MatScalar *aa; 962d9b7c43dSSatish Balay 9633a40ed3dSBarry Smith PetscFunctionBegin; 964d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 965b9b97703SBarry Smith ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr); 966d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 967d9b7c43dSSatish Balay 968bea157c4SSatish Balay /* allocate memory for rows,sizes */ 969b0a32e0cSBarry Smith ierr = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr); 970bea157c4SSatish Balay sizes = rows + is_n; 971bea157c4SSatish Balay 972563b5814SBarry Smith /* copy IS values to rows, and sort them */ 973bea157c4SSatish Balay for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; } 974bea157c4SSatish Balay ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr); 975dffd3267SBarry Smith if (baij->keepzeroedrows) { 976dffd3267SBarry Smith for (i=0; i<is_n; i++) { sizes[i] = 1; } 977dffd3267SBarry Smith bs_max = is_n; 978dffd3267SBarry Smith } else { 979bea157c4SSatish Balay ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr); 980dffd3267SBarry Smith } 981b97a56abSSatish Balay ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr); 982bea157c4SSatish Balay 983bea157c4SSatish Balay for (i=0,j=0; i<bs_max; j+=sizes[i],i++) { 984bea157c4SSatish Balay row = rows[j]; 985273d9f13SBarry Smith if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row); 986bea157c4SSatish Balay count = (baij->i[row/bs +1] - baij->i[row/bs])*bs; 987bea157c4SSatish Balay aa = baij->a + baij->i[row/bs]*bs2 + (row%bs); 988dffd3267SBarry Smith if (sizes[i] == bs && !baij->keepzeroedrows) { 989bea157c4SSatish Balay if (diag) { 990bea157c4SSatish Balay if (baij->ilen[row/bs] > 0) { 991bea157c4SSatish Balay baij->ilen[row/bs] = 1; 992bea157c4SSatish Balay baij->j[baij->i[row/bs]] = row/bs; 993bea157c4SSatish Balay ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr); 994a07cd24cSSatish Balay } 995563b5814SBarry Smith /* Now insert all the diagonal values for this bs */ 996bea157c4SSatish Balay for (k=0; k<bs; k++) { 997bea157c4SSatish Balay ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr); 998bea157c4SSatish Balay } 999bea157c4SSatish Balay } else { /* (!diag) */ 1000bea157c4SSatish Balay baij->ilen[row/bs] = 0; 1001bea157c4SSatish Balay } /* end (!diag) */ 1002bea157c4SSatish Balay } else { /* (sizes[i] != bs) */ 1003aa482453SBarry Smith #if defined (PETSC_USE_DEBUG) 100429bbc08cSBarry Smith if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1"); 1005bea157c4SSatish Balay #endif 1006bea157c4SSatish Balay for (k=0; k<count; k++) { 1007d9b7c43dSSatish Balay aa[0] = zero; 1008d9b7c43dSSatish Balay aa += bs; 1009d9b7c43dSSatish Balay } 1010d9b7c43dSSatish Balay if (diag) { 1011f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 1012d9b7c43dSSatish Balay } 1013d9b7c43dSSatish Balay } 1014bea157c4SSatish Balay } 1015bea157c4SSatish Balay 1016606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 10179a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10183a40ed3dSBarry Smith PetscFunctionReturn(0); 1019d9b7c43dSSatish Balay } 10201c351548SSatish Balay 10214a2ae208SSatish Balay #undef __FUNCT__ 10224a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ" 102387828ca2SBarry Smith int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v,InsertMode is) 10242d61bbb3SSatish Balay { 10252d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 10262d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 1027273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 10282d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 1029549d3d68SSatish Balay int ridx,cidx,bs2=a->bs2,ierr; 1030273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 10313f1db9ecSBarry Smith MatScalar *ap,value,*aa=a->a,*bap; 10322d61bbb3SSatish Balay 10332d61bbb3SSatish Balay PetscFunctionBegin; 10342d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 10352d61bbb3SSatish Balay row = im[k]; brow = row/bs; 10365ef9f2a5SBarry Smith if (row < 0) continue; 1037aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 1038273d9f13SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m); 10392d61bbb3SSatish Balay #endif 10402d61bbb3SSatish Balay rp = aj + ai[brow]; 10412d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 10422d61bbb3SSatish Balay rmax = imax[brow]; 10432d61bbb3SSatish Balay nrow = ailen[brow]; 10442d61bbb3SSatish Balay low = 0; 10452d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 10465ef9f2a5SBarry Smith if (in[l] < 0) continue; 1047aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 1048273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n); 10492d61bbb3SSatish Balay #endif 10502d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 10512d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 10522d61bbb3SSatish Balay if (roworiented) { 10535ef9f2a5SBarry Smith value = v[l + k*n]; 10542d61bbb3SSatish Balay } else { 10552d61bbb3SSatish Balay value = v[k + l*m]; 10562d61bbb3SSatish Balay } 10572d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 10582d61bbb3SSatish Balay while (high-low > 7) { 10592d61bbb3SSatish Balay t = (low+high)/2; 10602d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 10612d61bbb3SSatish Balay else low = t; 10622d61bbb3SSatish Balay } 10632d61bbb3SSatish Balay for (i=low; i<high; i++) { 10642d61bbb3SSatish Balay if (rp[i] > bcol) break; 10652d61bbb3SSatish Balay if (rp[i] == bcol) { 10662d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 10672d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 10682d61bbb3SSatish Balay else *bap = value; 10692d61bbb3SSatish Balay goto noinsert1; 10702d61bbb3SSatish Balay } 10712d61bbb3SSatish Balay } 10722d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 107329bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10742d61bbb3SSatish Balay if (nrow >= rmax) { 10752d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 10762d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 10773f1db9ecSBarry Smith MatScalar *new_a; 10782d61bbb3SSatish Balay 107929bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10802d61bbb3SSatish Balay 10812d61bbb3SSatish Balay /* Malloc new storage space */ 10823f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 1083b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 10842d61bbb3SSatish Balay new_j = (int*)(new_a + bs2*new_nz); 10852d61bbb3SSatish Balay new_i = new_j + new_nz; 10862d61bbb3SSatish Balay 10872d61bbb3SSatish Balay /* copy over old data into new slots */ 10882d61bbb3SSatish Balay for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];} 10892d61bbb3SSatish Balay for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 1090549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr); 10912d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 1092549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr); 1093549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1094549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 1095549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 10962d61bbb3SSatish Balay /* free up old matrix storage */ 1097606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 1098606d414cSSatish Balay if (!a->singlemalloc) { 1099606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 1100606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 1101606d414cSSatish Balay } 11022d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 1103c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 11042d61bbb3SSatish Balay 11052d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 11062d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 1107b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 11082d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 11092d61bbb3SSatish Balay a->reallocs++; 11102d61bbb3SSatish Balay a->nz++; 11112d61bbb3SSatish Balay } 11122d61bbb3SSatish Balay N = nrow++ - 1; 11132d61bbb3SSatish Balay /* shift up all the later entries in this row */ 11142d61bbb3SSatish Balay for (ii=N; ii>=i; ii--) { 11152d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 1116549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 11172d61bbb3SSatish Balay } 1118549d3d68SSatish Balay if (N>=i) { 1119549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 1120549d3d68SSatish Balay } 11212d61bbb3SSatish Balay rp[i] = bcol; 11222d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 11232d61bbb3SSatish Balay noinsert1:; 11242d61bbb3SSatish Balay low = i; 11252d61bbb3SSatish Balay } 11262d61bbb3SSatish Balay ailen[brow] = nrow; 11272d61bbb3SSatish Balay } 11282d61bbb3SSatish Balay PetscFunctionReturn(0); 11292d61bbb3SSatish Balay } 11302d61bbb3SSatish Balay 11312d61bbb3SSatish Balay 11324a2ae208SSatish Balay #undef __FUNCT__ 11334a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ" 11345ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 11352d61bbb3SSatish Balay { 11362d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data; 11372d61bbb3SSatish Balay Mat outA; 11382d61bbb3SSatish Balay int ierr; 1139667159a5SBarry Smith PetscTruth row_identity,col_identity; 11402d61bbb3SSatish Balay 11412d61bbb3SSatish Balay PetscFunctionBegin; 114229bbc08cSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU"); 1143667159a5SBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1144667159a5SBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1145667159a5SBarry Smith if (!row_identity || !col_identity) { 114629bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1147667159a5SBarry Smith } 11482d61bbb3SSatish Balay 11492d61bbb3SSatish Balay outA = inA; 11502d61bbb3SSatish Balay inA->factor = FACTOR_LU; 11512d61bbb3SSatish Balay 11522d61bbb3SSatish Balay if (!a->diag) { 1153c4992f7dSBarry Smith ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr); 11542d61bbb3SSatish Balay } 1155cf242676SKris Buschelman 1156c38d4ed2SBarry Smith a->row = row; 1157c38d4ed2SBarry Smith a->col = col; 1158c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1159c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1160c38d4ed2SBarry Smith 1161c38d4ed2SBarry Smith /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 11624c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1163b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1164c38d4ed2SBarry Smith 1165cf242676SKris Buschelman /* 1166cf242676SKris Buschelman Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver 1167cf242676SKris Buschelman for ILU(0) factorization with natural ordering 1168cf242676SKris Buschelman */ 1169cf242676SKris Buschelman if (a->bs < 8) { 1170cf242676SKris Buschelman ierr = MatSeqBAIJ_UpdateFactorNumeric_NaturalOrdering(inA);CHKERRQ(ierr); 1171cf242676SKris Buschelman } else { 1172c38d4ed2SBarry Smith if (!a->solve_work) { 117387828ca2SBarry Smith ierr = PetscMalloc((inA->m+a->bs)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 117487828ca2SBarry Smith PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(PetscScalar)); 1175c38d4ed2SBarry Smith } 11762d61bbb3SSatish Balay } 11772d61bbb3SSatish Balay 1178667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr); 1179667159a5SBarry Smith 11802d61bbb3SSatish Balay PetscFunctionReturn(0); 11812d61bbb3SSatish Balay } 11824a2ae208SSatish Balay #undef __FUNCT__ 11834a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ" 1184ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1185ba4ca20aSSatish Balay { 1186c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1187ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1188d132466eSBarry Smith int ierr; 1189ba4ca20aSSatish Balay 11903a40ed3dSBarry Smith PetscFunctionBegin; 1191c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1192d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1193d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n");CHKERRQ(ierr); 11943a40ed3dSBarry Smith PetscFunctionReturn(0); 1195ba4ca20aSSatish Balay } 1196d9b7c43dSSatish Balay 1197fb2e594dSBarry Smith EXTERN_C_BEGIN 11984a2ae208SSatish Balay #undef __FUNCT__ 11994a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 120027a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 120127a8da17SBarry Smith { 120227a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 120314db4f74SSatish Balay int i,nz,nbs; 120427a8da17SBarry Smith 120527a8da17SBarry Smith PetscFunctionBegin; 120614db4f74SSatish Balay nz = baij->maxnz/baij->bs2; 120714db4f74SSatish Balay nbs = baij->nbs; 120827a8da17SBarry Smith for (i=0; i<nz; i++) { 120927a8da17SBarry Smith baij->j[i] = indices[i]; 121027a8da17SBarry Smith } 121127a8da17SBarry Smith baij->nz = nz; 121214db4f74SSatish Balay for (i=0; i<nbs; i++) { 121327a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 121427a8da17SBarry Smith } 121527a8da17SBarry Smith 121627a8da17SBarry Smith PetscFunctionReturn(0); 121727a8da17SBarry Smith } 1218fb2e594dSBarry Smith EXTERN_C_END 121927a8da17SBarry Smith 12204a2ae208SSatish Balay #undef __FUNCT__ 12214a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices" 122227a8da17SBarry Smith /*@ 122327a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 122427a8da17SBarry Smith in the matrix. 122527a8da17SBarry Smith 122627a8da17SBarry Smith Input Parameters: 122727a8da17SBarry Smith + mat - the SeqBAIJ matrix 122827a8da17SBarry Smith - indices - the column indices 122927a8da17SBarry Smith 123015091d37SBarry Smith Level: advanced 123115091d37SBarry Smith 123227a8da17SBarry Smith Notes: 123327a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 123427a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 123527a8da17SBarry Smith of the MatSetValues() operation. 123627a8da17SBarry Smith 123727a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 123827a8da17SBarry Smith MatCreateSeqBAIJ(). 123927a8da17SBarry Smith 124027a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 124127a8da17SBarry Smith 124227a8da17SBarry Smith @*/ 124327a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 124427a8da17SBarry Smith { 124527a8da17SBarry Smith int ierr,(*f)(Mat,int *); 124627a8da17SBarry Smith 124727a8da17SBarry Smith PetscFunctionBegin; 124827a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1249c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 125027a8da17SBarry Smith if (f) { 125127a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 125227a8da17SBarry Smith } else { 125329bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 125427a8da17SBarry Smith } 125527a8da17SBarry Smith PetscFunctionReturn(0); 125627a8da17SBarry Smith } 125727a8da17SBarry Smith 12584a2ae208SSatish Balay #undef __FUNCT__ 12594a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ" 1260273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v) 1261273d9f13SBarry Smith { 1262273d9f13SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1263273d9f13SBarry Smith int ierr,i,j,n,row,bs,*ai,*aj,mbs; 1264273d9f13SBarry Smith PetscReal atmp; 126587828ca2SBarry Smith PetscScalar *x,zero = 0.0; 1266273d9f13SBarry Smith MatScalar *aa; 1267273d9f13SBarry Smith int ncols,brow,krow,kcol; 1268273d9f13SBarry Smith 1269273d9f13SBarry Smith PetscFunctionBegin; 1270273d9f13SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1271273d9f13SBarry Smith bs = a->bs; 1272273d9f13SBarry Smith aa = a->a; 1273273d9f13SBarry Smith ai = a->i; 1274273d9f13SBarry Smith aj = a->j; 1275273d9f13SBarry Smith mbs = a->mbs; 1276273d9f13SBarry Smith 1277273d9f13SBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 1278273d9f13SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1279273d9f13SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1280273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1281273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1282273d9f13SBarry Smith ncols = ai[1] - ai[0]; ai++; 1283273d9f13SBarry Smith brow = bs*i; 1284273d9f13SBarry Smith for (j=0; j<ncols; j++){ 1285273d9f13SBarry Smith /* bcol = bs*(*aj); */ 1286273d9f13SBarry Smith for (kcol=0; kcol<bs; kcol++){ 1287273d9f13SBarry Smith for (krow=0; krow<bs; krow++){ 1288273d9f13SBarry Smith atmp = PetscAbsScalar(*aa); aa++; 1289273d9f13SBarry Smith row = brow + krow; /* row index */ 1290273d9f13SBarry Smith /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */ 1291273d9f13SBarry Smith if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp; 1292273d9f13SBarry Smith } 1293273d9f13SBarry Smith } 1294273d9f13SBarry Smith aj++; 1295273d9f13SBarry Smith } 1296273d9f13SBarry Smith } 1297273d9f13SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1298273d9f13SBarry Smith PetscFunctionReturn(0); 1299273d9f13SBarry Smith } 1300273d9f13SBarry Smith 13014a2ae208SSatish Balay #undef __FUNCT__ 13024a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ" 1303273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A) 1304273d9f13SBarry Smith { 1305273d9f13SBarry Smith int ierr; 1306273d9f13SBarry Smith 1307273d9f13SBarry Smith PetscFunctionBegin; 1308273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr); 1309273d9f13SBarry Smith PetscFunctionReturn(0); 1310273d9f13SBarry Smith } 1311273d9f13SBarry Smith 13124a2ae208SSatish Balay #undef __FUNCT__ 13134a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ" 131487828ca2SBarry Smith int MatGetArray_SeqBAIJ(Mat A,PetscScalar **array) 1315f2a5309cSSatish Balay { 1316f2a5309cSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1317f2a5309cSSatish Balay PetscFunctionBegin; 1318f2a5309cSSatish Balay *array = a->a; 1319f2a5309cSSatish Balay PetscFunctionReturn(0); 1320f2a5309cSSatish Balay } 1321f2a5309cSSatish Balay 13224a2ae208SSatish Balay #undef __FUNCT__ 13234a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ" 132487828ca2SBarry Smith int MatRestoreArray_SeqBAIJ(Mat A,PetscScalar **array) 1325f2a5309cSSatish Balay { 1326f2a5309cSSatish Balay PetscFunctionBegin; 1327f2a5309cSSatish Balay PetscFunctionReturn(0); 1328f2a5309cSSatish Balay } 1329f2a5309cSSatish Balay 13302593348eSBarry Smith /* -------------------------------------------------------------------*/ 1331cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1332cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1333cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1334cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1335cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 13367c922b88SBarry Smith MatMultTranspose_SeqBAIJ, 13377c922b88SBarry Smith MatMultTransposeAdd_SeqBAIJ, 1338cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1339cc2dc46cSBarry Smith 0, 1340cc2dc46cSBarry Smith 0, 1341cc2dc46cSBarry Smith 0, 1342cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1343cc2dc46cSBarry Smith 0, 1344b6490206SBarry Smith 0, 1345f2501298SSatish Balay MatTranspose_SeqBAIJ, 1346cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1347cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1348cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1349cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1350cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1351b6490206SBarry Smith 0, 1352cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1353cc2dc46cSBarry Smith 0, 1354cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1355cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1356cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1357cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1358cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1359cc2dc46cSBarry Smith 0, 1360cc2dc46cSBarry Smith 0, 1361273d9f13SBarry Smith MatSetUpPreallocation_SeqBAIJ, 1362cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1363cc2dc46cSBarry Smith 0, 1364f2a5309cSSatish Balay MatGetArray_SeqBAIJ, 1365f2a5309cSSatish Balay MatRestoreArray_SeqBAIJ, 13662e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1367cc2dc46cSBarry Smith 0, 1368cc2dc46cSBarry Smith 0, 1369cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1370cc2dc46cSBarry Smith 0, 1371cc2dc46cSBarry Smith 0, 1372cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1373cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1374cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1375cc2dc46cSBarry Smith 0, 1376cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1377cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1378cc2dc46cSBarry Smith 0, 1379cc2dc46cSBarry Smith 0, 1380cc2dc46cSBarry Smith 0, 1381cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 13823b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 138392c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1384cc2dc46cSBarry Smith 0, 1385cc2dc46cSBarry Smith 0, 1386cc2dc46cSBarry Smith 0, 1387cc2dc46cSBarry Smith 0, 1388cc2dc46cSBarry Smith 0, 1389cc2dc46cSBarry Smith 0, 1390d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1391cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1392b9b97703SBarry Smith MatDestroy_SeqBAIJ, 1393b9b97703SBarry Smith MatView_SeqBAIJ, 13943a64cc32SBarry Smith MatGetPetscMaps_Petsc, 1395273d9f13SBarry Smith 0, 1396273d9f13SBarry Smith 0, 1397273d9f13SBarry Smith 0, 1398273d9f13SBarry Smith 0, 1399273d9f13SBarry Smith 0, 1400273d9f13SBarry Smith 0, 1401273d9f13SBarry Smith MatGetRowMax_SeqBAIJ, 1402273d9f13SBarry Smith MatConvert_Basic}; 14032593348eSBarry Smith 14043e90b805SBarry Smith EXTERN_C_BEGIN 14054a2ae208SSatish Balay #undef __FUNCT__ 14064a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ" 14073e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat) 14083e90b805SBarry Smith { 14093e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1410273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2; 1411d132466eSBarry Smith int ierr; 14123e90b805SBarry Smith 14133e90b805SBarry Smith PetscFunctionBegin; 14143e90b805SBarry Smith if (aij->nonew != 1) { 141529bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14163e90b805SBarry Smith } 14173e90b805SBarry Smith 14183e90b805SBarry Smith /* allocate space for values if not already there */ 14193e90b805SBarry Smith if (!aij->saved_values) { 142087828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 14213e90b805SBarry Smith } 14223e90b805SBarry Smith 14233e90b805SBarry Smith /* copy values over */ 142487828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 14253e90b805SBarry Smith PetscFunctionReturn(0); 14263e90b805SBarry Smith } 14273e90b805SBarry Smith EXTERN_C_END 14283e90b805SBarry Smith 14293e90b805SBarry Smith EXTERN_C_BEGIN 14304a2ae208SSatish Balay #undef __FUNCT__ 14314a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ" 143232e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat) 14333e90b805SBarry Smith { 14343e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1435273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr; 14363e90b805SBarry Smith 14373e90b805SBarry Smith PetscFunctionBegin; 14383e90b805SBarry Smith if (aij->nonew != 1) { 143929bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14403e90b805SBarry Smith } 14413e90b805SBarry Smith if (!aij->saved_values) { 144229bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 14433e90b805SBarry Smith } 14443e90b805SBarry Smith 14453e90b805SBarry Smith /* copy values over */ 144687828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 14473e90b805SBarry Smith PetscFunctionReturn(0); 14483e90b805SBarry Smith } 14493e90b805SBarry Smith EXTERN_C_END 14503e90b805SBarry Smith 1451273d9f13SBarry Smith EXTERN_C_BEGIN 1452273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*); 1453273d9f13SBarry Smith EXTERN_C_END 1454273d9f13SBarry Smith 1455273d9f13SBarry Smith EXTERN_C_BEGIN 14564a2ae208SSatish Balay #undef __FUNCT__ 14574a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ" 1458273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B) 14592593348eSBarry Smith { 1460273d9f13SBarry Smith int ierr,size; 1461b6490206SBarry Smith Mat_SeqBAIJ *b; 14623b2fbd54SBarry Smith 14633a40ed3dSBarry Smith PetscFunctionBegin; 1464273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 146529bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1466b6490206SBarry Smith 1467273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 1468273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 1469b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr); 1470b0a32e0cSBarry Smith B->data = (void*)b; 1471549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr); 1472549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 14732593348eSBarry Smith B->factor = 0; 14742593348eSBarry Smith B->lupivotthreshold = 1.0; 147590f02eecSBarry Smith B->mapping = 0; 14762593348eSBarry Smith b->row = 0; 14772593348eSBarry Smith b->col = 0; 1478e51c0b9cSSatish Balay b->icol = 0; 14792593348eSBarry Smith b->reallocs = 0; 14803e90b805SBarry Smith b->saved_values = 0; 1481cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 1482563b5814SBarry Smith b->setvalueslen = 0; 1483563b5814SBarry Smith b->setvaluescopy = PETSC_NULL; 1484563b5814SBarry Smith #endif 14858661488fSKris Buschelman b->single_precision_solves = PETSC_FALSE; 14862593348eSBarry Smith 14873a64cc32SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 14883a64cc32SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 1489a5ae1ecdSBarry Smith 1490c4992f7dSBarry Smith b->sorted = PETSC_FALSE; 1491c4992f7dSBarry Smith b->roworiented = PETSC_TRUE; 14922593348eSBarry Smith b->nonew = 0; 14932593348eSBarry Smith b->diag = 0; 14942593348eSBarry Smith b->solve_work = 0; 1495de6a44a3SBarry Smith b->mult_work = 0; 14962a1b7f2aSHong Zhang B->spptr = 0; 14970e6d2581SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1498883fce79SBarry Smith b->keepzeroedrows = PETSC_FALSE; 14994e220ebcSLois Curfman McInnes 1500f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 15013e90b805SBarry Smith "MatStoreValues_SeqBAIJ", 1502bc4b532fSSatish Balay MatStoreValues_SeqBAIJ);CHKERRQ(ierr); 1503f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 15043e90b805SBarry Smith "MatRetrieveValues_SeqBAIJ", 1505bc4b532fSSatish Balay MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr); 1506f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 150727a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 1508bc4b532fSSatish Balay MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 1509273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C", 1510273d9f13SBarry Smith "MatConvert_SeqBAIJ_SeqAIJ", 1511273d9f13SBarry Smith MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr); 15123a40ed3dSBarry Smith PetscFunctionReturn(0); 15132593348eSBarry Smith } 1514273d9f13SBarry Smith EXTERN_C_END 15152593348eSBarry Smith 15164a2ae208SSatish Balay #undef __FUNCT__ 15174a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ" 15182e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 15192593348eSBarry Smith { 15202593348eSBarry Smith Mat C; 1521b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data; 152227a8da17SBarry Smith int i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1523de6a44a3SBarry Smith 15243a40ed3dSBarry Smith PetscFunctionBegin; 152529bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 15262593348eSBarry Smith 15272593348eSBarry Smith *B = 0; 1528273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 1529273d9f13SBarry Smith ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr); 1530273d9f13SBarry Smith c = (Mat_SeqBAIJ*)C->data; 153144cd7ae7SLois Curfman McInnes 1532b6490206SBarry Smith c->bs = a->bs; 15339df24120SSatish Balay c->bs2 = a->bs2; 1534b6490206SBarry Smith c->mbs = a->mbs; 1535b6490206SBarry Smith c->nbs = a->nbs; 153635d8aa7fSBarry Smith ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 15372593348eSBarry Smith 1538b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 1539b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 1540b6490206SBarry Smith for (i=0; i<mbs; i++) { 15412593348eSBarry Smith c->imax[i] = a->imax[i]; 15422593348eSBarry Smith c->ilen[i] = a->ilen[i]; 15432593348eSBarry Smith } 15442593348eSBarry Smith 15452593348eSBarry Smith /* allocate the matrix space */ 1546c4992f7dSBarry Smith c->singlemalloc = PETSC_TRUE; 15473f1db9ecSBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int)); 1548b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 15497e67e3f9SSatish Balay c->j = (int*)(c->a + nz*bs2); 1550de6a44a3SBarry Smith c->i = c->j + nz; 1551549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr); 1552b6490206SBarry Smith if (mbs > 0) { 1553549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr); 15542e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 1555549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 15562e8a6d31SBarry Smith } else { 1557549d3d68SSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 15582593348eSBarry Smith } 15592593348eSBarry Smith } 15602593348eSBarry Smith 1561b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 15622593348eSBarry Smith c->sorted = a->sorted; 15632593348eSBarry Smith c->roworiented = a->roworiented; 15642593348eSBarry Smith c->nonew = a->nonew; 15652593348eSBarry Smith 15662593348eSBarry Smith if (a->diag) { 1567b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 1568b0a32e0cSBarry Smith PetscLogObjectMemory(C,(mbs+1)*sizeof(int)); 1569b6490206SBarry Smith for (i=0; i<mbs; i++) { 15702593348eSBarry Smith c->diag[i] = a->diag[i]; 15712593348eSBarry Smith } 157298305bb5SBarry Smith } else c->diag = 0; 15732593348eSBarry Smith c->nz = a->nz; 15742593348eSBarry Smith c->maxnz = a->maxnz; 15752593348eSBarry Smith c->solve_work = 0; 15762a1b7f2aSHong Zhang C->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 15777fc0212eSBarry Smith c->mult_work = 0; 1578273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 1579273d9f13SBarry Smith C->assembled = PETSC_TRUE; 15802593348eSBarry Smith *B = C; 1581b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 15823a40ed3dSBarry Smith PetscFunctionReturn(0); 15832593348eSBarry Smith } 15842593348eSBarry Smith 1585273d9f13SBarry Smith EXTERN_C_BEGIN 15864a2ae208SSatish Balay #undef __FUNCT__ 15874a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ" 1588b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A) 15892593348eSBarry Smith { 1590b6490206SBarry Smith Mat_SeqBAIJ *a; 15912593348eSBarry Smith Mat B; 1592f1af5d2fSBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1; 1593b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 159435aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1595a7c10996SSatish Balay int *masked,nmask,tmp,bs2,ishift; 159687828ca2SBarry Smith PetscScalar *aa; 159719bcc07fSBarry Smith MPI_Comm comm = ((PetscObject)viewer)->comm; 15982593348eSBarry Smith 15993a40ed3dSBarry Smith PetscFunctionBegin; 1600b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 1601de6a44a3SBarry Smith bs2 = bs*bs; 1602b6490206SBarry Smith 1603d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 160429bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 1605b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 16060752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 1607552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 16082593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 16092593348eSBarry Smith 1610d64ed03dSBarry Smith if (header[3] < 0) { 161129bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ"); 1612d64ed03dSBarry Smith } 1613d64ed03dSBarry Smith 161429bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 161535aab85fSBarry Smith 161635aab85fSBarry Smith /* 161735aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 161835aab85fSBarry Smith divisible by the blocksize 161935aab85fSBarry Smith */ 1620b6490206SBarry Smith mbs = M/bs; 162135aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 162235aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 162335aab85fSBarry Smith else mbs++; 162435aab85fSBarry Smith if (extra_rows) { 1625b0a32e0cSBarry Smith PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 162635aab85fSBarry Smith } 1627b6490206SBarry Smith 16282593348eSBarry Smith /* read in row lengths */ 1629b0a32e0cSBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr); 16300752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 163135aab85fSBarry Smith for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 16322593348eSBarry Smith 1633b6490206SBarry Smith /* read in column indices */ 1634b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr); 16350752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 163635aab85fSBarry Smith for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 1637b6490206SBarry Smith 1638b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1639b0a32e0cSBarry Smith ierr = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr); 1640549d3d68SSatish Balay ierr = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr); 1641b0a32e0cSBarry Smith ierr = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr); 1642549d3d68SSatish Balay ierr = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr); 164335aab85fSBarry Smith masked = mask + mbs; 1644b6490206SBarry Smith rowcount = 0; nzcount = 0; 1645b6490206SBarry Smith for (i=0; i<mbs; i++) { 164635aab85fSBarry Smith nmask = 0; 1647b6490206SBarry Smith for (j=0; j<bs; j++) { 1648b6490206SBarry Smith kmax = rowlengths[rowcount]; 1649b6490206SBarry Smith for (k=0; k<kmax; k++) { 165035aab85fSBarry Smith tmp = jj[nzcount++]/bs; 165135aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1652b6490206SBarry Smith } 1653b6490206SBarry Smith rowcount++; 1654b6490206SBarry Smith } 165535aab85fSBarry Smith browlengths[i] += nmask; 165635aab85fSBarry Smith /* zero out the mask elements we set */ 165735aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1658b6490206SBarry Smith } 1659b6490206SBarry Smith 16602593348eSBarry Smith /* create our matrix */ 16613eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 16622593348eSBarry Smith B = *A; 1663b6490206SBarry Smith a = (Mat_SeqBAIJ*)B->data; 16642593348eSBarry Smith 16652593348eSBarry Smith /* set matrix "i" values */ 1666de6a44a3SBarry Smith a->i[0] = 0; 1667b6490206SBarry Smith for (i=1; i<= mbs; i++) { 1668b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1669b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 16702593348eSBarry Smith } 1671b6490206SBarry Smith a->nz = 0; 1672b6490206SBarry Smith for (i=0; i<mbs; i++) a->nz += browlengths[i]; 16732593348eSBarry Smith 1674b6490206SBarry Smith /* read in nonzero values */ 167587828ca2SBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscScalar),&aa);CHKERRQ(ierr); 16760752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 167735aab85fSBarry Smith for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 1678b6490206SBarry Smith 1679b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1680b6490206SBarry Smith nzcount = 0; jcount = 0; 1681b6490206SBarry Smith for (i=0; i<mbs; i++) { 1682b6490206SBarry Smith nzcountb = nzcount; 168335aab85fSBarry Smith nmask = 0; 1684b6490206SBarry Smith for (j=0; j<bs; j++) { 1685b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1686b6490206SBarry Smith for (k=0; k<kmax; k++) { 168735aab85fSBarry Smith tmp = jj[nzcount++]/bs; 168835aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1689b6490206SBarry Smith } 1690b6490206SBarry Smith } 1691de6a44a3SBarry Smith /* sort the masked values */ 1692433994e6SBarry Smith ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 1693de6a44a3SBarry Smith 1694b6490206SBarry Smith /* set "j" values into matrix */ 1695b6490206SBarry Smith maskcount = 1; 169635aab85fSBarry Smith for (j=0; j<nmask; j++) { 169735aab85fSBarry Smith a->j[jcount++] = masked[j]; 1698de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1699b6490206SBarry Smith } 1700b6490206SBarry Smith /* set "a" values into matrix */ 1701de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1702b6490206SBarry Smith for (j=0; j<bs; j++) { 1703b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1704b6490206SBarry Smith for (k=0; k<kmax; k++) { 1705de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1706de6a44a3SBarry Smith block = mask[tmp] - 1; 1707de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1708de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1709375fe846SBarry Smith a->a[idx] = (MatScalar)aa[nzcountb++]; 1710b6490206SBarry Smith } 1711b6490206SBarry Smith } 171235aab85fSBarry Smith /* zero out the mask elements we set */ 171335aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1714b6490206SBarry Smith } 171529bbc08cSBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 1716b6490206SBarry Smith 1717606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 1718606d414cSSatish Balay ierr = PetscFree(browlengths);CHKERRQ(ierr); 1719606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 1720606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 1721606d414cSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 1722b6490206SBarry Smith 1723b6490206SBarry Smith B->assembled = PETSC_TRUE; 1724de6a44a3SBarry Smith 17259c01be13SBarry Smith ierr = MatView_Private(B);CHKERRQ(ierr); 17263a40ed3dSBarry Smith PetscFunctionReturn(0); 17272593348eSBarry Smith } 1728273d9f13SBarry Smith EXTERN_C_END 17292593348eSBarry Smith 17304a2ae208SSatish Balay #undef __FUNCT__ 17314a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ" 1732273d9f13SBarry Smith /*@C 1733273d9f13SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 1734273d9f13SBarry Smith compressed row) format. For good matrix assembly performance the 1735273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1736273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1737273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 17382593348eSBarry Smith 1739273d9f13SBarry Smith Collective on MPI_Comm 1740273d9f13SBarry Smith 1741273d9f13SBarry Smith Input Parameters: 1742273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 1743273d9f13SBarry Smith . bs - size of block 1744273d9f13SBarry Smith . m - number of rows 1745273d9f13SBarry Smith . n - number of columns 174635d8aa7fSBarry Smith . nz - number of nonzero blocks per block row (same for all rows) 174735d8aa7fSBarry Smith - nnz - array containing the number of nonzero blocks in the various block rows 1748273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1749273d9f13SBarry Smith 1750273d9f13SBarry Smith Output Parameter: 1751273d9f13SBarry Smith . A - the matrix 1752273d9f13SBarry Smith 1753273d9f13SBarry Smith Options Database Keys: 1754273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1755273d9f13SBarry Smith block calculations (much slower) 1756273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1757273d9f13SBarry Smith 1758273d9f13SBarry Smith Level: intermediate 1759273d9f13SBarry Smith 1760273d9f13SBarry Smith Notes: 176135d8aa7fSBarry Smith A nonzero block is any block that as 1 or more nonzeros in it 176235d8aa7fSBarry Smith 1763273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1764273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1765273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1766273d9f13SBarry Smith 1767273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1768273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1769273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1770273d9f13SBarry Smith matrices. 1771273d9f13SBarry Smith 1772273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1773273d9f13SBarry Smith @*/ 1774273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A) 1775273d9f13SBarry Smith { 1776273d9f13SBarry Smith int ierr; 1777273d9f13SBarry Smith 1778273d9f13SBarry Smith PetscFunctionBegin; 1779273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 1780273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr); 1781273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr); 1782273d9f13SBarry Smith PetscFunctionReturn(0); 1783273d9f13SBarry Smith } 1784273d9f13SBarry Smith 17854a2ae208SSatish Balay #undef __FUNCT__ 17864a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation" 1787273d9f13SBarry Smith /*@C 1788273d9f13SBarry Smith MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros 1789273d9f13SBarry Smith per row in the matrix. For good matrix assembly performance the 1790273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1791273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1792273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 1793273d9f13SBarry Smith 1794273d9f13SBarry Smith Collective on MPI_Comm 1795273d9f13SBarry Smith 1796273d9f13SBarry Smith Input Parameters: 1797273d9f13SBarry Smith + A - the matrix 1798273d9f13SBarry Smith . bs - size of block 1799273d9f13SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1800273d9f13SBarry Smith - nnz - array containing the number of block nonzeros in the various block rows 1801273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1802273d9f13SBarry Smith 1803273d9f13SBarry Smith Options Database Keys: 1804273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1805273d9f13SBarry Smith block calculations (much slower) 1806273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1807273d9f13SBarry Smith 1808273d9f13SBarry Smith Level: intermediate 1809273d9f13SBarry Smith 1810273d9f13SBarry Smith Notes: 1811273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1812273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1813273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1814273d9f13SBarry Smith 1815273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1816273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1817273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1818273d9f13SBarry Smith matrices. 1819273d9f13SBarry Smith 1820273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1821273d9f13SBarry Smith @*/ 1822273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz) 1823273d9f13SBarry Smith { 1824273d9f13SBarry Smith Mat_SeqBAIJ *b; 1825273d9f13SBarry Smith int i,len,ierr,mbs,nbs,bs2,newbs = bs; 1826273d9f13SBarry Smith PetscTruth flg; 1827273d9f13SBarry Smith 1828273d9f13SBarry Smith PetscFunctionBegin; 1829273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr); 1830273d9f13SBarry Smith if (!flg) PetscFunctionReturn(0); 1831273d9f13SBarry Smith 1832273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1833b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr); 1834273d9f13SBarry Smith if (nnz && newbs != bs) { 1835273d9f13SBarry Smith SETERRQ(1,"Cannot change blocksize from command line if setting nnz"); 1836273d9f13SBarry Smith } 1837273d9f13SBarry Smith bs = newbs; 1838273d9f13SBarry Smith 1839273d9f13SBarry Smith mbs = B->m/bs; 1840273d9f13SBarry Smith nbs = B->n/bs; 1841273d9f13SBarry Smith bs2 = bs*bs; 1842273d9f13SBarry Smith 1843273d9f13SBarry Smith if (mbs*bs!=B->m || nbs*bs!=B->n) { 184435d8aa7fSBarry Smith SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs); 1845273d9f13SBarry Smith } 1846273d9f13SBarry Smith 1847435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1848435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 1849273d9f13SBarry Smith if (nnz) { 1850273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1851273d9f13SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 18523a7fca6bSBarry 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); 1853273d9f13SBarry Smith } 1854273d9f13SBarry Smith } 1855273d9f13SBarry Smith 1856273d9f13SBarry Smith b = (Mat_SeqBAIJ*)B->data; 1857b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr); 185854138f6bSKris Buschelman B->ops->solve = MatSolve_SeqBAIJ_Update; 185954138f6bSKris Buschelman B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_Update; 1860273d9f13SBarry Smith if (!flg) { 1861273d9f13SBarry Smith switch (bs) { 1862273d9f13SBarry Smith case 1: 1863273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1864273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1865273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 1866273d9f13SBarry Smith break; 1867273d9f13SBarry Smith case 2: 1868273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1869273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1870273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 1871273d9f13SBarry Smith break; 1872273d9f13SBarry Smith case 3: 1873273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1874273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1875273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 1876273d9f13SBarry Smith break; 1877273d9f13SBarry Smith case 4: 1878273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1879273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1880273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 1881273d9f13SBarry Smith break; 1882273d9f13SBarry Smith case 5: 1883273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1884273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1885273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 1886273d9f13SBarry Smith break; 1887273d9f13SBarry Smith case 6: 1888273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6; 1889273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_6; 1890273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_6; 1891273d9f13SBarry Smith break; 1892273d9f13SBarry Smith case 7: 189354138f6bSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7; 1894273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1895273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 1896273d9f13SBarry Smith break; 1897273d9f13SBarry Smith default: 189854138f6bSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_N; 1899273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_N; 1900273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_N; 1901273d9f13SBarry Smith break; 1902273d9f13SBarry Smith } 1903273d9f13SBarry Smith } 1904273d9f13SBarry Smith b->bs = bs; 1905273d9f13SBarry Smith b->mbs = mbs; 1906273d9f13SBarry Smith b->nbs = nbs; 1907b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 1908273d9f13SBarry Smith if (!nnz) { 1909435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1910273d9f13SBarry Smith else if (nz <= 0) nz = 1; 1911273d9f13SBarry Smith for (i=0; i<mbs; i++) b->imax[i] = nz; 1912273d9f13SBarry Smith nz = nz*mbs; 1913273d9f13SBarry Smith } else { 1914273d9f13SBarry Smith nz = 0; 1915273d9f13SBarry Smith for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 1916273d9f13SBarry Smith } 1917273d9f13SBarry Smith 1918273d9f13SBarry Smith /* allocate the matrix space */ 1919273d9f13SBarry Smith len = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int); 1920b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 1921273d9f13SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1922273d9f13SBarry Smith b->j = (int*)(b->a + nz*bs2); 1923273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 1924273d9f13SBarry Smith b->i = b->j + nz; 1925273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 1926273d9f13SBarry Smith 1927273d9f13SBarry Smith b->i[0] = 0; 1928273d9f13SBarry Smith for (i=1; i<mbs+1; i++) { 1929273d9f13SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 1930273d9f13SBarry Smith } 1931273d9f13SBarry Smith 1932273d9f13SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 193316d6aa21SSatish Balay ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 1934b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1935273d9f13SBarry Smith for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 1936273d9f13SBarry Smith 1937273d9f13SBarry Smith b->bs = bs; 1938273d9f13SBarry Smith b->bs2 = bs2; 1939273d9f13SBarry Smith b->mbs = mbs; 1940273d9f13SBarry Smith b->nz = 0; 1941273d9f13SBarry Smith b->maxnz = nz*bs2; 1942273d9f13SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1943273d9f13SBarry Smith PetscFunctionReturn(0); 1944273d9f13SBarry Smith } 19452593348eSBarry Smith 1946