1*87828ca2SBarry Smith /*$Id: baij.c,v 1.243 2001/07/20 21:10:11 buschelm Exp bsmith $*/ 22593348eSBarry Smith 32593348eSBarry Smith /* 4b6490206SBarry Smith Defines the basic matrix operations for the BAIJ (compressed row) 52593348eSBarry Smith matrix storage format. 62593348eSBarry Smith */ 7a2ccead7SSatish Balay #include "petscsys.h" /*I "petscmat.h" I*/ 870f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h" 91a6a6d98SBarry Smith #include "src/vec/vecimpl.h" 101a6a6d98SBarry Smith #include "src/inline/spops.h" 113b547af2SSatish Balay 1295d5f7c2SBarry Smith /* UGLY, ugly, ugly 13*87828ca2SBarry 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 2495d5f7c2SBarry Smith 252d61bbb3SSatish Balay #define CHUNKSIZE 10 26de6a44a3SBarry Smith 27be5855fcSBarry Smith /* 28be5855fcSBarry Smith Checks for missing diagonals 29be5855fcSBarry Smith */ 304a2ae208SSatish Balay #undef __FUNCT__ 314a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqBAIJ" 32c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A) 33be5855fcSBarry Smith { 34be5855fcSBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 35883fce79SBarry Smith int *diag,*jj = a->j,i,ierr; 36be5855fcSBarry Smith 37be5855fcSBarry Smith PetscFunctionBegin; 38c4992f7dSBarry Smith ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr); 39883fce79SBarry Smith diag = a->diag; 400e8e8aceSBarry Smith for (i=0; i<a->mbs; i++) { 41be5855fcSBarry Smith if (jj[diag[i]] != i) { 4229bbc08cSBarry Smith SETERRQ1(1,"Matrix is missing diagonal number %d",i); 43be5855fcSBarry Smith } 44be5855fcSBarry Smith } 45be5855fcSBarry Smith PetscFunctionReturn(0); 46be5855fcSBarry Smith } 47be5855fcSBarry Smith 484a2ae208SSatish Balay #undef __FUNCT__ 494a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqBAIJ" 50c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A) 51de6a44a3SBarry Smith { 52de6a44a3SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 5382502324SSatish Balay int i,j,*diag,m = a->mbs,ierr; 54de6a44a3SBarry Smith 553a40ed3dSBarry Smith PetscFunctionBegin; 56883fce79SBarry Smith if (a->diag) PetscFunctionReturn(0); 57883fce79SBarry Smith 58b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr); 59b0a32e0cSBarry Smith PetscLogObjectMemory(A,(m+1)*sizeof(int)); 607fc0212eSBarry Smith for (i=0; i<m; i++) { 61ecc615b2SBarry Smith diag[i] = a->i[i+1]; 62de6a44a3SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 63de6a44a3SBarry Smith if (a->j[j] == i) { 64de6a44a3SBarry Smith diag[i] = j; 65de6a44a3SBarry Smith break; 66de6a44a3SBarry Smith } 67de6a44a3SBarry Smith } 68de6a44a3SBarry Smith } 69de6a44a3SBarry Smith a->diag = diag; 703a40ed3dSBarry Smith PetscFunctionReturn(0); 71de6a44a3SBarry Smith } 722593348eSBarry Smith 732593348eSBarry Smith 74ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 753b2fbd54SBarry Smith 764a2ae208SSatish Balay #undef __FUNCT__ 774a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqBAIJ" 780e6d2581SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 793b2fbd54SBarry Smith { 803b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 813b2fbd54SBarry Smith int ierr,n = a->mbs,i; 823b2fbd54SBarry Smith 833a40ed3dSBarry Smith PetscFunctionBegin; 843b2fbd54SBarry Smith *nn = n; 853a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 863b2fbd54SBarry Smith if (symmetric) { 873b2fbd54SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 883b2fbd54SBarry Smith } else if (oshift == 1) { 893b2fbd54SBarry Smith /* temporarily add 1 to i and j indices */ 90435da068SBarry Smith int nz = a->i[n]; 913b2fbd54SBarry Smith for (i=0; i<nz; i++) a->j[i]++; 923b2fbd54SBarry Smith for (i=0; i<n+1; i++) a->i[i]++; 933b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 943b2fbd54SBarry Smith } else { 953b2fbd54SBarry Smith *ia = a->i; *ja = a->j; 963b2fbd54SBarry Smith } 973b2fbd54SBarry Smith 983a40ed3dSBarry Smith PetscFunctionReturn(0); 993b2fbd54SBarry Smith } 1003b2fbd54SBarry Smith 1014a2ae208SSatish Balay #undef __FUNCT__ 1024a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqBAIJ" 103435da068SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 1043b2fbd54SBarry Smith { 1053b2fbd54SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 106606d414cSSatish Balay int i,n = a->mbs,ierr; 1073b2fbd54SBarry Smith 1083a40ed3dSBarry Smith PetscFunctionBegin; 1093a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1103b2fbd54SBarry Smith if (symmetric) { 111606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 112606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 113af5da2bfSBarry Smith } else if (oshift == 1) { 114435da068SBarry Smith int nz = a->i[n]-1; 1153b2fbd54SBarry Smith for (i=0; i<nz; i++) a->j[i]--; 1163b2fbd54SBarry Smith for (i=0; i<n+1; i++) a->i[i]--; 1173b2fbd54SBarry Smith } 1183a40ed3dSBarry Smith PetscFunctionReturn(0); 1193b2fbd54SBarry Smith } 1203b2fbd54SBarry Smith 1214a2ae208SSatish Balay #undef __FUNCT__ 1224a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqBAIJ" 1232d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs) 1242d61bbb3SSatish Balay { 1252d61bbb3SSatish Balay Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data; 1262d61bbb3SSatish Balay 1272d61bbb3SSatish Balay PetscFunctionBegin; 1282d61bbb3SSatish Balay *bs = baij->bs; 1292d61bbb3SSatish Balay PetscFunctionReturn(0); 1302d61bbb3SSatish Balay } 1312d61bbb3SSatish Balay 1322d61bbb3SSatish Balay 1334a2ae208SSatish Balay #undef __FUNCT__ 1344a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqBAIJ" 135e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A) 1362d61bbb3SSatish Balay { 1372d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 138e51c0b9cSSatish Balay int ierr; 1392d61bbb3SSatish Balay 140433994e6SBarry Smith PetscFunctionBegin; 141aa482453SBarry Smith #if defined(PETSC_USE_LOG) 142b0a32e0cSBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 1432d61bbb3SSatish Balay #endif 144606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 145606d414cSSatish Balay if (!a->singlemalloc) { 146606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 147606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 148606d414cSSatish Balay } 149c38d4ed2SBarry Smith if (a->row) { 150c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 151c38d4ed2SBarry Smith } 152c38d4ed2SBarry Smith if (a->col) { 153c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 154c38d4ed2SBarry Smith } 155606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 156606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 157606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 158606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 159606d414cSSatish Balay if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);} 160e51c0b9cSSatish Balay if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 161606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 162563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 163563b5814SBarry Smith if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);} 164563b5814SBarry Smith #endif 165606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 1662d61bbb3SSatish Balay PetscFunctionReturn(0); 1672d61bbb3SSatish Balay } 1682d61bbb3SSatish Balay 1694a2ae208SSatish Balay #undef __FUNCT__ 1704a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqBAIJ" 1712d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op) 1722d61bbb3SSatish Balay { 1732d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1742d61bbb3SSatish Balay 1752d61bbb3SSatish Balay PetscFunctionBegin; 176aa275fccSKris Buschelman switch (op) { 177aa275fccSKris Buschelman case MAT_ROW_ORIENTED: 178aa275fccSKris Buschelman a->roworiented = PETSC_TRUE; 179aa275fccSKris Buschelman break; 180aa275fccSKris Buschelman case MAT_COLUMN_ORIENTED: 181aa275fccSKris Buschelman a->roworiented = PETSC_FALSE; 182aa275fccSKris Buschelman break; 183aa275fccSKris Buschelman case MAT_COLUMNS_SORTED: 184aa275fccSKris Buschelman a->sorted = PETSC_TRUE; 185aa275fccSKris Buschelman break; 186aa275fccSKris Buschelman case MAT_COLUMNS_UNSORTED: 187aa275fccSKris Buschelman a->sorted = PETSC_FALSE; 188aa275fccSKris Buschelman break; 189aa275fccSKris Buschelman case MAT_KEEP_ZEROED_ROWS: 190aa275fccSKris Buschelman a->keepzeroedrows = PETSC_TRUE; 191aa275fccSKris Buschelman break; 192aa275fccSKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 193aa275fccSKris Buschelman a->nonew = 1; 194aa275fccSKris Buschelman break; 195aa275fccSKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 196aa275fccSKris Buschelman a->nonew = -1; 197aa275fccSKris Buschelman break; 198aa275fccSKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 199aa275fccSKris Buschelman a->nonew = -2; 200aa275fccSKris Buschelman break; 201aa275fccSKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 202aa275fccSKris Buschelman a->nonew = 0; 203aa275fccSKris Buschelman break; 204aa275fccSKris Buschelman case MAT_ROWS_SORTED: 205aa275fccSKris Buschelman case MAT_ROWS_UNSORTED: 206aa275fccSKris Buschelman case MAT_YES_NEW_DIAGONALS: 207aa275fccSKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 208aa275fccSKris Buschelman case MAT_USE_HASH_TABLE: 209b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n"); 210aa275fccSKris Buschelman break; 211aa275fccSKris Buschelman case MAT_NO_NEW_DIAGONALS: 21229bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 213bd648c37SKris Buschelman break; 214bd648c37SKris Buschelman case MAT_USE_SINGLE_PRECISION_SOLVES: 215bd648c37SKris Buschelman if (a->bs==4) { 21694ee7fc8SKris Buschelman PetscTruth sse_enabled_local,sse_enabled_global; 217bd648c37SKris Buschelman int ierr; 21894ee7fc8SKris Buschelman 21994ee7fc8SKris Buschelman sse_enabled_local = PETSC_FALSE; 22094ee7fc8SKris Buschelman sse_enabled_global = PETSC_FALSE; 22194ee7fc8SKris Buschelman 22294ee7fc8SKris Buschelman ierr = PetscSSEIsEnabled(A->comm,&sse_enabled_local,&sse_enabled_global);CHKERRQ(ierr); 223e64df4b9SKris Buschelman #if defined(PETSC_HAVE_SSE) 22494ee7fc8SKris Buschelman if (sse_enabled_local) { 22554138f6bSKris Buschelman a->single_precision_solves = PETSC_TRUE; 22654138f6bSKris Buschelman A->ops->solve = MatSolve_SeqBAIJ_Update; 22754138f6bSKris Buschelman A->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_Update; 228cf242676SKris Buschelman PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES set\n"); 22954138f6bSKris Buschelman break; 23094ee7fc8SKris Buschelman } else { 23194ee7fc8SKris Buschelman PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n"); 2328661488fSKris Buschelman } 233e64df4b9SKris Buschelman #else 234bd648c37SKris Buschelman PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n"); 235e64df4b9SKris Buschelman #endif 236bd648c37SKris Buschelman } 237bd648c37SKris Buschelman break; 238aa275fccSKris Buschelman default: 23929bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"unknown option"); 2402d61bbb3SSatish Balay } 2412d61bbb3SSatish Balay PetscFunctionReturn(0); 2422d61bbb3SSatish Balay } 2432d61bbb3SSatish Balay 2444a2ae208SSatish Balay #undef __FUNCT__ 2454a2ae208SSatish Balay #define __FUNCT__ "MatGetOwnershipRange_SeqBAIJ" 2462d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n) 2472d61bbb3SSatish Balay { 2482d61bbb3SSatish Balay PetscFunctionBegin; 2494c49b128SBarry Smith if (m) *m = 0; 250273d9f13SBarry Smith if (n) *n = A->m; 2512d61bbb3SSatish Balay PetscFunctionReturn(0); 2522d61bbb3SSatish Balay } 2532d61bbb3SSatish Balay 2544a2ae208SSatish Balay #undef __FUNCT__ 2554a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ" 256*87828ca2SBarry Smith int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 2572d61bbb3SSatish Balay { 2582d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 25982502324SSatish Balay int itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr; 2603f1db9ecSBarry Smith MatScalar *aa,*aa_i; 261*87828ca2SBarry Smith PetscScalar *v_i; 2622d61bbb3SSatish Balay 2632d61bbb3SSatish Balay PetscFunctionBegin; 2642d61bbb3SSatish Balay bs = a->bs; 2652d61bbb3SSatish Balay ai = a->i; 2662d61bbb3SSatish Balay aj = a->j; 2672d61bbb3SSatish Balay aa = a->a; 2682d61bbb3SSatish Balay bs2 = a->bs2; 2692d61bbb3SSatish Balay 270273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range"); 2712d61bbb3SSatish Balay 2722d61bbb3SSatish Balay bn = row/bs; /* Block number */ 2732d61bbb3SSatish Balay bp = row % bs; /* Block Position */ 2742d61bbb3SSatish Balay M = ai[bn+1] - ai[bn]; 2752d61bbb3SSatish Balay *nz = bs*M; 2762d61bbb3SSatish Balay 2772d61bbb3SSatish Balay if (v) { 2782d61bbb3SSatish Balay *v = 0; 2792d61bbb3SSatish Balay if (*nz) { 280*87828ca2SBarry Smith ierr = PetscMalloc((*nz)*sizeof(PetscScalar),v);CHKERRQ(ierr); 2812d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2822d61bbb3SSatish Balay v_i = *v + i*bs; 2832d61bbb3SSatish Balay aa_i = aa + bs2*(ai[bn] + i); 2842d61bbb3SSatish Balay for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];} 2852d61bbb3SSatish Balay } 2862d61bbb3SSatish Balay } 2872d61bbb3SSatish Balay } 2882d61bbb3SSatish Balay 2892d61bbb3SSatish Balay if (idx) { 2902d61bbb3SSatish Balay *idx = 0; 2912d61bbb3SSatish Balay if (*nz) { 292b0a32e0cSBarry Smith ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr); 2932d61bbb3SSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 2942d61bbb3SSatish Balay idx_i = *idx + i*bs; 2952d61bbb3SSatish Balay itmp = bs*aj[ai[bn] + i]; 2962d61bbb3SSatish Balay for (j=0; j<bs; j++) {idx_i[j] = itmp++;} 2972d61bbb3SSatish Balay } 2982d61bbb3SSatish Balay } 2992d61bbb3SSatish Balay } 3002d61bbb3SSatish Balay PetscFunctionReturn(0); 3012d61bbb3SSatish Balay } 3022d61bbb3SSatish Balay 3034a2ae208SSatish Balay #undef __FUNCT__ 3044a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ" 305*87828ca2SBarry Smith int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 3062d61bbb3SSatish Balay { 307606d414cSSatish Balay int ierr; 308606d414cSSatish Balay 3092d61bbb3SSatish Balay PetscFunctionBegin; 310606d414cSSatish Balay if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 311606d414cSSatish Balay if (v) {if (*v) {ierr = PetscFree(*v);CHKERRQ(ierr);}} 3122d61bbb3SSatish Balay PetscFunctionReturn(0); 3132d61bbb3SSatish Balay } 3142d61bbb3SSatish Balay 3154a2ae208SSatish Balay #undef __FUNCT__ 3164a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ" 3172d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B) 3182d61bbb3SSatish Balay { 3192d61bbb3SSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data; 3202d61bbb3SSatish Balay Mat C; 3212d61bbb3SSatish Balay int i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col; 322273d9f13SBarry Smith int *rows,*cols,bs2=a->bs2; 323*87828ca2SBarry Smith PetscScalar *array; 3242d61bbb3SSatish Balay 3252d61bbb3SSatish Balay PetscFunctionBegin; 32629bbc08cSBarry Smith if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place"); 327b0a32e0cSBarry Smith ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr); 328549d3d68SSatish Balay ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr); 3292d61bbb3SSatish Balay 330375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 331*87828ca2SBarry Smith ierr = PetscMalloc(a->bs2*a->nz*sizeof(PetscScalar),&array);CHKERRQ(ierr); 332*87828ca2SBarry Smith for (i=0; i<a->bs2*a->nz; i++) array[i] = (PetscScalar)a->a[i]; 333375fe846SBarry Smith #else 3343eda8832SBarry Smith array = a->a; 335375fe846SBarry Smith #endif 336375fe846SBarry Smith 3372d61bbb3SSatish Balay for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1; 338273d9f13SBarry Smith ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr); 339606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 340b0a32e0cSBarry Smith ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr); 3412d61bbb3SSatish Balay cols = rows + bs; 3422d61bbb3SSatish Balay for (i=0; i<mbs; i++) { 3432d61bbb3SSatish Balay cols[0] = i*bs; 3442d61bbb3SSatish Balay for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1; 3452d61bbb3SSatish Balay len = ai[i+1] - ai[i]; 3462d61bbb3SSatish Balay for (j=0; j<len; j++) { 3472d61bbb3SSatish Balay rows[0] = (*aj++)*bs; 3482d61bbb3SSatish Balay for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1; 3492d61bbb3SSatish Balay ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr); 3502d61bbb3SSatish Balay array += bs2; 3512d61bbb3SSatish Balay } 3522d61bbb3SSatish Balay } 353606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 354375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 355375fe846SBarry Smith ierr = PetscFree(array); 356375fe846SBarry Smith #endif 3572d61bbb3SSatish Balay 3582d61bbb3SSatish Balay ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3592d61bbb3SSatish Balay ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3602d61bbb3SSatish Balay 361c4992f7dSBarry Smith if (B) { 3622d61bbb3SSatish Balay *B = C; 3632d61bbb3SSatish Balay } else { 364273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 3652d61bbb3SSatish Balay } 3662d61bbb3SSatish Balay PetscFunctionReturn(0); 3672d61bbb3SSatish Balay } 3682d61bbb3SSatish Balay 3694a2ae208SSatish Balay #undef __FUNCT__ 3704a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary" 371b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer) 3722593348eSBarry Smith { 373b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 3749df24120SSatish Balay int i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2; 375*87828ca2SBarry Smith PetscScalar *aa; 376ce6f0cecSBarry Smith FILE *file; 3772593348eSBarry Smith 3783a40ed3dSBarry Smith PetscFunctionBegin; 379b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 380b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 3812593348eSBarry Smith col_lens[0] = MAT_COOKIE; 3823b2fbd54SBarry Smith 383273d9f13SBarry Smith col_lens[1] = A->m; 384273d9f13SBarry Smith col_lens[2] = A->n; 3857e67e3f9SSatish Balay col_lens[3] = a->nz*bs2; 3862593348eSBarry Smith 3872593348eSBarry Smith /* store lengths of each row and write (including header) to file */ 388b6490206SBarry Smith count = 0; 389b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 390b6490206SBarry Smith for (j=0; j<bs; j++) { 391b6490206SBarry Smith col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]); 392b6490206SBarry Smith } 3932593348eSBarry Smith } 394273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 395606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 3962593348eSBarry Smith 3972593348eSBarry Smith /* store column indices (zero start index) */ 398b0a32e0cSBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr); 399b6490206SBarry Smith count = 0; 400b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 401b6490206SBarry Smith for (j=0; j<bs; j++) { 402b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 403b6490206SBarry Smith for (l=0; l<bs; l++) { 404b6490206SBarry Smith jj[count++] = bs*a->j[k] + l; 4052593348eSBarry Smith } 4062593348eSBarry Smith } 407b6490206SBarry Smith } 408b6490206SBarry Smith } 4090752156aSBarry Smith ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr); 410606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 4112593348eSBarry Smith 4122593348eSBarry Smith /* store nonzero values */ 413*87828ca2SBarry Smith ierr = PetscMalloc((a->nz+1)*bs2*sizeof(PetscScalar),&aa);CHKERRQ(ierr); 414b6490206SBarry Smith count = 0; 415b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 416b6490206SBarry Smith for (j=0; j<bs; j++) { 417b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 418b6490206SBarry Smith for (l=0; l<bs; l++) { 4197e67e3f9SSatish Balay aa[count++] = a->a[bs2*k + l*bs + j]; 420b6490206SBarry Smith } 421b6490206SBarry Smith } 422b6490206SBarry Smith } 423b6490206SBarry Smith } 4240752156aSBarry Smith ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 425606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 426ce6f0cecSBarry Smith 427b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 428ce6f0cecSBarry Smith if (file) { 429ce6f0cecSBarry Smith fprintf(file,"-matload_block_size %d\n",a->bs); 430ce6f0cecSBarry Smith } 4313a40ed3dSBarry Smith PetscFunctionReturn(0); 4322593348eSBarry Smith } 4332593348eSBarry Smith 4344a2ae208SSatish Balay #undef __FUNCT__ 4354a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII" 436b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer) 4372593348eSBarry Smith { 438b6490206SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 439fb9695e5SSatish Balay int ierr,i,j,bs = a->bs,k,l,bs2=a->bs2; 440f3ef73ceSBarry Smith PetscViewerFormat format; 4412593348eSBarry Smith 4423a40ed3dSBarry Smith PetscFunctionBegin; 443b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 444fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) { 445b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %d\n",bs);CHKERRQ(ierr); 446fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 44729bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Matlab format not supported"); 448fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 449b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 45044cd7ae7SLois Curfman McInnes for (i=0; i<a->mbs; i++) { 45144cd7ae7SLois Curfman McInnes for (j=0; j<bs; j++) { 452b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 45344cd7ae7SLois Curfman McInnes for (k=a->i[i]; k<a->i[i+1]; k++) { 45444cd7ae7SLois Curfman McInnes for (l=0; l<bs; l++) { 455aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4560e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 457b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l, 4580e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4590e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 460b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l, 4610e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4620e6d2581SBarry Smith } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 463b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4640ef38995SBarry Smith } 46544cd7ae7SLois Curfman McInnes #else 4660ef38995SBarry Smith if (a->a[bs2*k + l*bs + j] != 0.0) { 467b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 4680ef38995SBarry Smith } 46944cd7ae7SLois Curfman McInnes #endif 47044cd7ae7SLois Curfman McInnes } 47144cd7ae7SLois Curfman McInnes } 472b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 47344cd7ae7SLois Curfman McInnes } 47444cd7ae7SLois Curfman McInnes } 475b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4760ef38995SBarry Smith } else { 477b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 478b6490206SBarry Smith for (i=0; i<a->mbs; i++) { 479b6490206SBarry Smith for (j=0; j<bs; j++) { 480b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr); 481b6490206SBarry Smith for (k=a->i[i]; k<a->i[i+1]; k++) { 482b6490206SBarry Smith for (l=0; l<bs; l++) { 483aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 4840e6d2581SBarry Smith if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 485b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l, 4860e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4870e6d2581SBarry Smith } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 488b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l, 4890e6d2581SBarry Smith PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 4900ef38995SBarry Smith } else { 491b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 49288685aaeSLois Curfman McInnes } 49388685aaeSLois Curfman McInnes #else 494b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 49588685aaeSLois Curfman McInnes #endif 4962593348eSBarry Smith } 4972593348eSBarry Smith } 498b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 4992593348eSBarry Smith } 5002593348eSBarry Smith } 501b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 502b6490206SBarry Smith } 503b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 5043a40ed3dSBarry Smith PetscFunctionReturn(0); 5052593348eSBarry Smith } 5062593348eSBarry Smith 5074a2ae208SSatish Balay #undef __FUNCT__ 5084a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom" 509b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 5103270192aSSatish Balay { 51177ed5343SBarry Smith Mat A = (Mat) Aa; 5123270192aSSatish Balay Mat_SeqBAIJ *a=(Mat_SeqBAIJ*)A->data; 513b65db4caSBarry Smith int row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2; 5140e6d2581SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 5153f1db9ecSBarry Smith MatScalar *aa; 516b0a32e0cSBarry Smith PetscViewer viewer; 5173270192aSSatish Balay 5183a40ed3dSBarry Smith PetscFunctionBegin; 5193270192aSSatish Balay 520b65db4caSBarry Smith /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/ 52177ed5343SBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 52277ed5343SBarry Smith 523b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 52477ed5343SBarry Smith 5253270192aSSatish Balay /* loop over matrix elements drawing boxes */ 526b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 5273270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5283270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 529273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5303270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5313270192aSSatish Balay aa = a->a + j*bs2; 5323270192aSSatish Balay for (k=0; k<bs; k++) { 5333270192aSSatish Balay for (l=0; l<bs; l++) { 5340e6d2581SBarry Smith if (PetscRealPart(*aa++) >= 0.) continue; 535b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5363270192aSSatish Balay } 5373270192aSSatish Balay } 5383270192aSSatish Balay } 5393270192aSSatish Balay } 540b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 5413270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5423270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 543273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5443270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5453270192aSSatish Balay aa = a->a + j*bs2; 5463270192aSSatish Balay for (k=0; k<bs; k++) { 5473270192aSSatish Balay for (l=0; l<bs; l++) { 5480e6d2581SBarry Smith if (PetscRealPart(*aa++) != 0.) continue; 549b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5503270192aSSatish Balay } 5513270192aSSatish Balay } 5523270192aSSatish Balay } 5533270192aSSatish Balay } 5543270192aSSatish Balay 555b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 5563270192aSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 5573270192aSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 558273d9f13SBarry Smith y_l = A->m - row - 1.0; y_r = y_l + 1.0; 5593270192aSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 5603270192aSSatish Balay aa = a->a + j*bs2; 5613270192aSSatish Balay for (k=0; k<bs; k++) { 5623270192aSSatish Balay for (l=0; l<bs; l++) { 5630e6d2581SBarry Smith if (PetscRealPart(*aa++) <= 0.) continue; 564b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 5653270192aSSatish Balay } 5663270192aSSatish Balay } 5673270192aSSatish Balay } 5683270192aSSatish Balay } 56977ed5343SBarry Smith PetscFunctionReturn(0); 57077ed5343SBarry Smith } 5713270192aSSatish Balay 5724a2ae208SSatish Balay #undef __FUNCT__ 5734a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw" 574b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer) 57577ed5343SBarry Smith { 5767dce120fSSatish Balay int ierr; 5770e6d2581SBarry Smith PetscReal xl,yl,xr,yr,w,h; 578b0a32e0cSBarry Smith PetscDraw draw; 57977ed5343SBarry Smith PetscTruth isnull; 5803270192aSSatish Balay 58177ed5343SBarry Smith PetscFunctionBegin; 58277ed5343SBarry Smith 583b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 584b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 58577ed5343SBarry Smith 58677ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 587273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 58877ed5343SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 589b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 590b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 59177ed5343SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5923a40ed3dSBarry Smith PetscFunctionReturn(0); 5933270192aSSatish Balay } 5943270192aSSatish Balay 5954a2ae208SSatish Balay #undef __FUNCT__ 5964a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ" 597b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer) 5982593348eSBarry Smith { 59919bcc07fSBarry Smith int ierr; 6006831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 6012593348eSBarry Smith 6023a40ed3dSBarry Smith PetscFunctionBegin; 603b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 604b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 605fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 606fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 6070f5bd95cSBarry Smith if (issocket) { 60829bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported"); 6090f5bd95cSBarry Smith } else if (isascii){ 6103a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 6110f5bd95cSBarry Smith } else if (isbinary) { 6123a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr); 6130f5bd95cSBarry Smith } else if (isdraw) { 6143a40ed3dSBarry Smith ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr); 6155cd90555SBarry Smith } else { 61629bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name); 6172593348eSBarry Smith } 6183a40ed3dSBarry Smith PetscFunctionReturn(0); 6192593348eSBarry Smith } 620b6490206SBarry Smith 621cd0e1443SSatish Balay 6224a2ae208SSatish Balay #undef __FUNCT__ 6234a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ" 624*87828ca2SBarry Smith int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v) 625cd0e1443SSatish Balay { 626cd0e1443SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 6272d61bbb3SSatish Balay int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 6282d61bbb3SSatish Balay int *ai = a->i,*ailen = a->ilen; 6292d61bbb3SSatish Balay int brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2; 6303f1db9ecSBarry Smith MatScalar *ap,*aa = a->a,zero = 0.0; 631cd0e1443SSatish Balay 6323a40ed3dSBarry Smith PetscFunctionBegin; 6332d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over rows */ 634cd0e1443SSatish Balay row = im[k]; brow = row/bs; 63529bbc08cSBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row"); 636273d9f13SBarry Smith if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 6372d61bbb3SSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 6382c3acbe9SBarry Smith nrow = ailen[brow]; 6392d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over columns */ 64029bbc08cSBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column"); 641273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 6422d61bbb3SSatish Balay col = in[l] ; 6432d61bbb3SSatish Balay bcol = col/bs; 6442d61bbb3SSatish Balay cidx = col%bs; 6452d61bbb3SSatish Balay ridx = row%bs; 6462d61bbb3SSatish Balay high = nrow; 6472d61bbb3SSatish Balay low = 0; /* assume unsorted */ 6482d61bbb3SSatish Balay while (high-low > 5) { 649cd0e1443SSatish Balay t = (low+high)/2; 650cd0e1443SSatish Balay if (rp[t] > bcol) high = t; 651cd0e1443SSatish Balay else low = t; 652cd0e1443SSatish Balay } 653cd0e1443SSatish Balay for (i=low; i<high; i++) { 654cd0e1443SSatish Balay if (rp[i] > bcol) break; 655cd0e1443SSatish Balay if (rp[i] == bcol) { 6562d61bbb3SSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 6572d61bbb3SSatish Balay goto finished; 658cd0e1443SSatish Balay } 659cd0e1443SSatish Balay } 6602d61bbb3SSatish Balay *v++ = zero; 6612d61bbb3SSatish Balay finished:; 662cd0e1443SSatish Balay } 663cd0e1443SSatish Balay } 6643a40ed3dSBarry Smith PetscFunctionReturn(0); 665cd0e1443SSatish Balay } 666cd0e1443SSatish Balay 66795d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE) 6684a2ae208SSatish Balay #undef __FUNCT__ 6694a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ" 670*87828ca2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,PetscScalar *v,InsertMode addv) 67195d5f7c2SBarry Smith { 672563b5814SBarry Smith Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data; 673563b5814SBarry Smith int ierr,i,N = m*n*b->bs2; 674563b5814SBarry Smith MatScalar *vsingle; 67595d5f7c2SBarry Smith 67695d5f7c2SBarry Smith PetscFunctionBegin; 677563b5814SBarry Smith if (N > b->setvalueslen) { 678563b5814SBarry Smith if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);} 679b0a32e0cSBarry Smith ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr); 680563b5814SBarry Smith b->setvalueslen = N; 681563b5814SBarry Smith } 682563b5814SBarry Smith vsingle = b->setvaluescopy; 68395d5f7c2SBarry Smith for (i=0; i<N; i++) { 68495d5f7c2SBarry Smith vsingle[i] = v[i]; 68595d5f7c2SBarry Smith } 68695d5f7c2SBarry Smith ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr); 68795d5f7c2SBarry Smith PetscFunctionReturn(0); 68895d5f7c2SBarry Smith } 68995d5f7c2SBarry Smith #endif 69095d5f7c2SBarry Smith 6912d61bbb3SSatish Balay 6924a2ae208SSatish Balay #undef __FUNCT__ 6934a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ" 69495d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is) 69592c4ed94SBarry Smith { 69692c4ed94SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 6978a84c255SSatish Balay int *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 698273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 699549d3d68SSatish Balay int *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr; 700273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 70195d5f7c2SBarry Smith MatScalar *value = v,*ap,*aa = a->a,*bap; 70292c4ed94SBarry Smith 7033a40ed3dSBarry Smith PetscFunctionBegin; 7040e324ae4SSatish Balay if (roworiented) { 7050e324ae4SSatish Balay stepval = (n-1)*bs; 7060e324ae4SSatish Balay } else { 7070e324ae4SSatish Balay stepval = (m-1)*bs; 7080e324ae4SSatish Balay } 70992c4ed94SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 71092c4ed94SBarry Smith row = im[k]; 7115ef9f2a5SBarry Smith if (row < 0) continue; 712aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 71329bbc08cSBarry Smith if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 71492c4ed94SBarry Smith #endif 71592c4ed94SBarry Smith rp = aj + ai[row]; 71692c4ed94SBarry Smith ap = aa + bs2*ai[row]; 71792c4ed94SBarry Smith rmax = imax[row]; 71892c4ed94SBarry Smith nrow = ailen[row]; 71992c4ed94SBarry Smith low = 0; 72092c4ed94SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 7215ef9f2a5SBarry Smith if (in[l] < 0) continue; 722aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 72329bbc08cSBarry Smith if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 72492c4ed94SBarry Smith #endif 72592c4ed94SBarry Smith col = in[l]; 72692c4ed94SBarry Smith if (roworiented) { 7270e324ae4SSatish Balay value = v + k*(stepval+bs)*bs + l*bs; 7280e324ae4SSatish Balay } else { 7290e324ae4SSatish Balay value = v + l*(stepval+bs)*bs + k*bs; 73092c4ed94SBarry Smith } 73192c4ed94SBarry Smith if (!sorted) low = 0; high = nrow; 73292c4ed94SBarry Smith while (high-low > 7) { 73392c4ed94SBarry Smith t = (low+high)/2; 73492c4ed94SBarry Smith if (rp[t] > col) high = t; 73592c4ed94SBarry Smith else low = t; 73692c4ed94SBarry Smith } 73792c4ed94SBarry Smith for (i=low; i<high; i++) { 73892c4ed94SBarry Smith if (rp[i] > col) break; 73992c4ed94SBarry Smith if (rp[i] == col) { 7408a84c255SSatish Balay bap = ap + bs2*i; 7410e324ae4SSatish Balay if (roworiented) { 7428a84c255SSatish Balay if (is == ADD_VALUES) { 743dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 744dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7458a84c255SSatish Balay bap[jj] += *value++; 746dd9472c6SBarry Smith } 747dd9472c6SBarry Smith } 7480e324ae4SSatish Balay } else { 749dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 750dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 7510e324ae4SSatish Balay bap[jj] = *value++; 7528a84c255SSatish Balay } 753dd9472c6SBarry Smith } 754dd9472c6SBarry Smith } 7550e324ae4SSatish Balay } else { 7560e324ae4SSatish Balay if (is == ADD_VALUES) { 757dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 758dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7590e324ae4SSatish Balay *bap++ += *value++; 760dd9472c6SBarry Smith } 761dd9472c6SBarry Smith } 7620e324ae4SSatish Balay } else { 763dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 764dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 7650e324ae4SSatish Balay *bap++ = *value++; 7660e324ae4SSatish Balay } 7678a84c255SSatish Balay } 768dd9472c6SBarry Smith } 769dd9472c6SBarry Smith } 770f1241b54SBarry Smith goto noinsert2; 77192c4ed94SBarry Smith } 77292c4ed94SBarry Smith } 77389280ab3SLois Curfman McInnes if (nonew == 1) goto noinsert2; 77429bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 77592c4ed94SBarry Smith if (nrow >= rmax) { 77692c4ed94SBarry Smith /* there is no extra room in row, therefore enlarge */ 77792c4ed94SBarry Smith int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 7783f1db9ecSBarry Smith MatScalar *new_a; 77992c4ed94SBarry Smith 78029bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 78189280ab3SLois Curfman McInnes 78292c4ed94SBarry Smith /* malloc new storage space */ 7833f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 784b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 78592c4ed94SBarry Smith new_j = (int*)(new_a + bs2*new_nz); 78692c4ed94SBarry Smith new_i = new_j + new_nz; 78792c4ed94SBarry Smith 78892c4ed94SBarry Smith /* copy over old data into new slots */ 78992c4ed94SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 79092c4ed94SBarry Smith for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 791549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr); 79292c4ed94SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow); 793549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr); 794549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 795549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 796549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 79792c4ed94SBarry Smith /* free up old matrix storage */ 798606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 799606d414cSSatish Balay if (!a->singlemalloc) { 800606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 801606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 802606d414cSSatish Balay } 80392c4ed94SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 804c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 80592c4ed94SBarry Smith 80692c4ed94SBarry Smith rp = aj + ai[row]; ap = aa + bs2*ai[row]; 80792c4ed94SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 808b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 80992c4ed94SBarry Smith a->maxnz += bs2*CHUNKSIZE; 81092c4ed94SBarry Smith a->reallocs++; 81192c4ed94SBarry Smith a->nz++; 81292c4ed94SBarry Smith } 81392c4ed94SBarry Smith N = nrow++ - 1; 81492c4ed94SBarry Smith /* shift up all the later entries in this row */ 81592c4ed94SBarry Smith for (ii=N; ii>=i; ii--) { 81692c4ed94SBarry Smith rp[ii+1] = rp[ii]; 817549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 81892c4ed94SBarry Smith } 819549d3d68SSatish Balay if (N >= i) { 820549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 821549d3d68SSatish Balay } 82292c4ed94SBarry Smith rp[i] = col; 8238a84c255SSatish Balay bap = ap + bs2*i; 8240e324ae4SSatish Balay if (roworiented) { 825dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 826dd9472c6SBarry Smith for (jj=ii; jj<bs2; jj+=bs) { 8270e324ae4SSatish Balay bap[jj] = *value++; 828dd9472c6SBarry Smith } 829dd9472c6SBarry Smith } 8300e324ae4SSatish Balay } else { 831dd9472c6SBarry Smith for (ii=0; ii<bs; ii++,value+=stepval) { 832dd9472c6SBarry Smith for (jj=0; jj<bs; jj++) { 8330e324ae4SSatish Balay *bap++ = *value++; 8340e324ae4SSatish Balay } 835dd9472c6SBarry Smith } 836dd9472c6SBarry Smith } 837f1241b54SBarry Smith noinsert2:; 83892c4ed94SBarry Smith low = i; 83992c4ed94SBarry Smith } 84092c4ed94SBarry Smith ailen[row] = nrow; 84192c4ed94SBarry Smith } 8423a40ed3dSBarry Smith PetscFunctionReturn(0); 84392c4ed94SBarry Smith } 84492c4ed94SBarry Smith 845f2501298SSatish Balay 8464a2ae208SSatish Balay #undef __FUNCT__ 8474a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ" 8488f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode) 849584200bdSSatish Balay { 850584200bdSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 851584200bdSSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 852273d9f13SBarry Smith int m = A->m,*ip,N,*ailen = a->ilen; 853549d3d68SSatish Balay int mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr; 8543f1db9ecSBarry Smith MatScalar *aa = a->a,*ap; 855584200bdSSatish Balay 8563a40ed3dSBarry Smith PetscFunctionBegin; 8573a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 858584200bdSSatish Balay 85943ee02c3SBarry Smith if (m) rmax = ailen[0]; 860584200bdSSatish Balay for (i=1; i<mbs; i++) { 861584200bdSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 862584200bdSSatish Balay fshift += imax[i-1] - ailen[i-1]; 863d402145bSBarry Smith rmax = PetscMax(rmax,ailen[i]); 864584200bdSSatish Balay if (fshift) { 865a7c10996SSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 866584200bdSSatish Balay N = ailen[i]; 867584200bdSSatish Balay for (j=0; j<N; j++) { 868584200bdSSatish Balay ip[j-fshift] = ip[j]; 869549d3d68SSatish Balay ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr); 870584200bdSSatish Balay } 871584200bdSSatish Balay } 872584200bdSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 873584200bdSSatish Balay } 874584200bdSSatish Balay if (mbs) { 875584200bdSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 876584200bdSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 877584200bdSSatish Balay } 878584200bdSSatish Balay /* reset ilen and imax for each row */ 879584200bdSSatish Balay for (i=0; i<mbs; i++) { 880584200bdSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 881584200bdSSatish Balay } 882a7c10996SSatish Balay a->nz = ai[mbs]; 883584200bdSSatish Balay 884584200bdSSatish Balay /* diagonals may have moved, so kill the diagonal pointers */ 885584200bdSSatish Balay if (fshift && a->diag) { 886606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 887b0a32e0cSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(int)); 888584200bdSSatish Balay a->diag = 0; 889584200bdSSatish Balay } 890b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n", 891273d9f13SBarry Smith m,A->n,a->bs,fshift*bs2,a->nz*bs2); 892b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n", 893584200bdSSatish Balay a->reallocs); 894b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax); 895e2f3b5e9SSatish Balay a->reallocs = 0; 8960e6d2581SBarry Smith A->info.nz_unneeded = (PetscReal)fshift*bs2; 8974e220ebcSLois Curfman McInnes 8983a40ed3dSBarry Smith PetscFunctionReturn(0); 899584200bdSSatish Balay } 900584200bdSSatish Balay 9015a838052SSatish Balay 902bea157c4SSatish Balay 903bea157c4SSatish Balay /* 904bea157c4SSatish Balay This function returns an array of flags which indicate the locations of contiguous 905bea157c4SSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 906bea157c4SSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 907bea157c4SSatish Balay Assume: sizes should be long enough to hold all the values. 908bea157c4SSatish Balay */ 9094a2ae208SSatish Balay #undef __FUNCT__ 9104a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks" 911bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max) 912d9b7c43dSSatish Balay { 913bea157c4SSatish Balay int i,j,k,row; 914bea157c4SSatish Balay PetscTruth flg; 9153a40ed3dSBarry Smith 916433994e6SBarry Smith PetscFunctionBegin; 917bea157c4SSatish Balay for (i=0,j=0; i<n; j++) { 918bea157c4SSatish Balay row = idx[i]; 919bea157c4SSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 920bea157c4SSatish Balay sizes[j] = 1; 921bea157c4SSatish Balay i++; 922e4fda26cSSatish Balay } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */ 923bea157c4SSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 924bea157c4SSatish Balay i++; 925bea157c4SSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 926bea157c4SSatish Balay flg = PETSC_TRUE; 927bea157c4SSatish Balay for (k=1; k<bs; k++) { 928bea157c4SSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 929bea157c4SSatish Balay flg = PETSC_FALSE; 930bea157c4SSatish Balay break; 931d9b7c43dSSatish Balay } 932bea157c4SSatish Balay } 933bea157c4SSatish Balay if (flg == PETSC_TRUE) { /* No break in the bs */ 934bea157c4SSatish Balay sizes[j] = bs; 935bea157c4SSatish Balay i+= bs; 936bea157c4SSatish Balay } else { 937bea157c4SSatish Balay sizes[j] = 1; 938bea157c4SSatish Balay i++; 939bea157c4SSatish Balay } 940bea157c4SSatish Balay } 941bea157c4SSatish Balay } 942bea157c4SSatish Balay *bs_max = j; 9433a40ed3dSBarry Smith PetscFunctionReturn(0); 944d9b7c43dSSatish Balay } 945d9b7c43dSSatish Balay 9464a2ae208SSatish Balay #undef __FUNCT__ 9474a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ" 948*87828ca2SBarry Smith int MatZeroRows_SeqBAIJ(Mat A,IS is,PetscScalar *diag) 949d9b7c43dSSatish Balay { 950d9b7c43dSSatish Balay Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data; 951b6815fffSBarry Smith int ierr,i,j,k,count,is_n,*is_idx,*rows; 952bea157c4SSatish Balay int bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max; 953*87828ca2SBarry Smith PetscScalar zero = 0.0; 9543f1db9ecSBarry Smith MatScalar *aa; 955d9b7c43dSSatish Balay 9563a40ed3dSBarry Smith PetscFunctionBegin; 957d9b7c43dSSatish Balay /* Make a copy of the IS and sort it */ 958b9b97703SBarry Smith ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr); 959d9b7c43dSSatish Balay ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr); 960d9b7c43dSSatish Balay 961bea157c4SSatish Balay /* allocate memory for rows,sizes */ 962b0a32e0cSBarry Smith ierr = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr); 963bea157c4SSatish Balay sizes = rows + is_n; 964bea157c4SSatish Balay 965563b5814SBarry Smith /* copy IS values to rows, and sort them */ 966bea157c4SSatish Balay for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; } 967bea157c4SSatish Balay ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr); 968dffd3267SBarry Smith if (baij->keepzeroedrows) { 969dffd3267SBarry Smith for (i=0; i<is_n; i++) { sizes[i] = 1; } 970dffd3267SBarry Smith bs_max = is_n; 971dffd3267SBarry Smith } else { 972bea157c4SSatish Balay ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr); 973dffd3267SBarry Smith } 974b97a56abSSatish Balay ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr); 975bea157c4SSatish Balay 976bea157c4SSatish Balay for (i=0,j=0; i<bs_max; j+=sizes[i],i++) { 977bea157c4SSatish Balay row = rows[j]; 978273d9f13SBarry Smith if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row); 979bea157c4SSatish Balay count = (baij->i[row/bs +1] - baij->i[row/bs])*bs; 980bea157c4SSatish Balay aa = baij->a + baij->i[row/bs]*bs2 + (row%bs); 981dffd3267SBarry Smith if (sizes[i] == bs && !baij->keepzeroedrows) { 982bea157c4SSatish Balay if (diag) { 983bea157c4SSatish Balay if (baij->ilen[row/bs] > 0) { 984bea157c4SSatish Balay baij->ilen[row/bs] = 1; 985bea157c4SSatish Balay baij->j[baij->i[row/bs]] = row/bs; 986bea157c4SSatish Balay ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr); 987a07cd24cSSatish Balay } 988563b5814SBarry Smith /* Now insert all the diagonal values for this bs */ 989bea157c4SSatish Balay for (k=0; k<bs; k++) { 990bea157c4SSatish Balay ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr); 991bea157c4SSatish Balay } 992bea157c4SSatish Balay } else { /* (!diag) */ 993bea157c4SSatish Balay baij->ilen[row/bs] = 0; 994bea157c4SSatish Balay } /* end (!diag) */ 995bea157c4SSatish Balay } else { /* (sizes[i] != bs) */ 996aa482453SBarry Smith #if defined (PETSC_USE_DEBUG) 99729bbc08cSBarry Smith if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1"); 998bea157c4SSatish Balay #endif 999bea157c4SSatish Balay for (k=0; k<count; k++) { 1000d9b7c43dSSatish Balay aa[0] = zero; 1001d9b7c43dSSatish Balay aa += bs; 1002d9b7c43dSSatish Balay } 1003d9b7c43dSSatish Balay if (diag) { 1004f830108cSBarry Smith ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); 1005d9b7c43dSSatish Balay } 1006d9b7c43dSSatish Balay } 1007bea157c4SSatish Balay } 1008bea157c4SSatish Balay 1009606d414cSSatish Balay ierr = PetscFree(rows);CHKERRQ(ierr); 10109a8dea36SBarry Smith ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10113a40ed3dSBarry Smith PetscFunctionReturn(0); 1012d9b7c43dSSatish Balay } 10131c351548SSatish Balay 10144a2ae208SSatish Balay #undef __FUNCT__ 10154a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ" 1016*87828ca2SBarry Smith int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v,InsertMode is) 10172d61bbb3SSatish Balay { 10182d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 10192d61bbb3SSatish Balay int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted; 1020273d9f13SBarry Smith int *imax=a->imax,*ai=a->i,*ailen=a->ilen; 10212d61bbb3SSatish Balay int *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol; 1022549d3d68SSatish Balay int ridx,cidx,bs2=a->bs2,ierr; 1023273d9f13SBarry Smith PetscTruth roworiented=a->roworiented; 10243f1db9ecSBarry Smith MatScalar *ap,value,*aa=a->a,*bap; 10252d61bbb3SSatish Balay 10262d61bbb3SSatish Balay PetscFunctionBegin; 10272d61bbb3SSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 10282d61bbb3SSatish Balay row = im[k]; brow = row/bs; 10295ef9f2a5SBarry Smith if (row < 0) continue; 1030aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 1031273d9f13SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m); 10322d61bbb3SSatish Balay #endif 10332d61bbb3SSatish Balay rp = aj + ai[brow]; 10342d61bbb3SSatish Balay ap = aa + bs2*ai[brow]; 10352d61bbb3SSatish Balay rmax = imax[brow]; 10362d61bbb3SSatish Balay nrow = ailen[brow]; 10372d61bbb3SSatish Balay low = 0; 10382d61bbb3SSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 10395ef9f2a5SBarry Smith if (in[l] < 0) continue; 1040aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 1041273d9f13SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n); 10422d61bbb3SSatish Balay #endif 10432d61bbb3SSatish Balay col = in[l]; bcol = col/bs; 10442d61bbb3SSatish Balay ridx = row % bs; cidx = col % bs; 10452d61bbb3SSatish Balay if (roworiented) { 10465ef9f2a5SBarry Smith value = v[l + k*n]; 10472d61bbb3SSatish Balay } else { 10482d61bbb3SSatish Balay value = v[k + l*m]; 10492d61bbb3SSatish Balay } 10502d61bbb3SSatish Balay if (!sorted) low = 0; high = nrow; 10512d61bbb3SSatish Balay while (high-low > 7) { 10522d61bbb3SSatish Balay t = (low+high)/2; 10532d61bbb3SSatish Balay if (rp[t] > bcol) high = t; 10542d61bbb3SSatish Balay else low = t; 10552d61bbb3SSatish Balay } 10562d61bbb3SSatish Balay for (i=low; i<high; i++) { 10572d61bbb3SSatish Balay if (rp[i] > bcol) break; 10582d61bbb3SSatish Balay if (rp[i] == bcol) { 10592d61bbb3SSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 10602d61bbb3SSatish Balay if (is == ADD_VALUES) *bap += value; 10612d61bbb3SSatish Balay else *bap = value; 10622d61bbb3SSatish Balay goto noinsert1; 10632d61bbb3SSatish Balay } 10642d61bbb3SSatish Balay } 10652d61bbb3SSatish Balay if (nonew == 1) goto noinsert1; 106629bbc08cSBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10672d61bbb3SSatish Balay if (nrow >= rmax) { 10682d61bbb3SSatish Balay /* there is no extra room in row, therefore enlarge */ 10692d61bbb3SSatish Balay int new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j; 10703f1db9ecSBarry Smith MatScalar *new_a; 10712d61bbb3SSatish Balay 107229bbc08cSBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 10732d61bbb3SSatish Balay 10742d61bbb3SSatish Balay /* Malloc new storage space */ 10753f1db9ecSBarry Smith len = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int); 1076b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 10772d61bbb3SSatish Balay new_j = (int*)(new_a + bs2*new_nz); 10782d61bbb3SSatish Balay new_i = new_j + new_nz; 10792d61bbb3SSatish Balay 10802d61bbb3SSatish Balay /* copy over old data into new slots */ 10812d61bbb3SSatish Balay for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];} 10822d61bbb3SSatish Balay for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 1083549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr); 10842d61bbb3SSatish Balay len = (new_nz - CHUNKSIZE - ai[brow] - nrow); 1085549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr); 1086549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1087549d3d68SSatish Balay ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr); 1088549d3d68SSatish Balay ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr); 10892d61bbb3SSatish Balay /* free up old matrix storage */ 1090606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 1091606d414cSSatish Balay if (!a->singlemalloc) { 1092606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 1093606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 1094606d414cSSatish Balay } 10952d61bbb3SSatish Balay aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 1096c4992f7dSBarry Smith a->singlemalloc = PETSC_TRUE; 10972d61bbb3SSatish Balay 10982d61bbb3SSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 10992d61bbb3SSatish Balay rmax = imax[brow] = imax[brow] + CHUNKSIZE; 1100b0a32e0cSBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar))); 11012d61bbb3SSatish Balay a->maxnz += bs2*CHUNKSIZE; 11022d61bbb3SSatish Balay a->reallocs++; 11032d61bbb3SSatish Balay a->nz++; 11042d61bbb3SSatish Balay } 11052d61bbb3SSatish Balay N = nrow++ - 1; 11062d61bbb3SSatish Balay /* shift up all the later entries in this row */ 11072d61bbb3SSatish Balay for (ii=N; ii>=i; ii--) { 11082d61bbb3SSatish Balay rp[ii+1] = rp[ii]; 1109549d3d68SSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 11102d61bbb3SSatish Balay } 1111549d3d68SSatish Balay if (N>=i) { 1112549d3d68SSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 1113549d3d68SSatish Balay } 11142d61bbb3SSatish Balay rp[i] = bcol; 11152d61bbb3SSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 11162d61bbb3SSatish Balay noinsert1:; 11172d61bbb3SSatish Balay low = i; 11182d61bbb3SSatish Balay } 11192d61bbb3SSatish Balay ailen[brow] = nrow; 11202d61bbb3SSatish Balay } 11212d61bbb3SSatish Balay PetscFunctionReturn(0); 11222d61bbb3SSatish Balay } 11232d61bbb3SSatish Balay 11242d61bbb3SSatish Balay 11254a2ae208SSatish Balay #undef __FUNCT__ 11264a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ" 11275ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 11282d61bbb3SSatish Balay { 11292d61bbb3SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data; 11302d61bbb3SSatish Balay Mat outA; 11312d61bbb3SSatish Balay int ierr; 1132667159a5SBarry Smith PetscTruth row_identity,col_identity; 11332d61bbb3SSatish Balay 11342d61bbb3SSatish Balay PetscFunctionBegin; 113529bbc08cSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU"); 1136667159a5SBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1137667159a5SBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1138667159a5SBarry Smith if (!row_identity || !col_identity) { 113929bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1140667159a5SBarry Smith } 11412d61bbb3SSatish Balay 11422d61bbb3SSatish Balay outA = inA; 11432d61bbb3SSatish Balay inA->factor = FACTOR_LU; 11442d61bbb3SSatish Balay 11452d61bbb3SSatish Balay if (!a->diag) { 1146c4992f7dSBarry Smith ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr); 11472d61bbb3SSatish Balay } 1148cf242676SKris Buschelman 1149c38d4ed2SBarry Smith a->row = row; 1150c38d4ed2SBarry Smith a->col = col; 1151c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1152c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1153c38d4ed2SBarry Smith 1154c38d4ed2SBarry Smith /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 11554c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1156b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1157c38d4ed2SBarry Smith 1158cf242676SKris Buschelman /* 1159cf242676SKris Buschelman Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver 1160cf242676SKris Buschelman for ILU(0) factorization with natural ordering 1161cf242676SKris Buschelman */ 1162cf242676SKris Buschelman if (a->bs < 8) { 1163cf242676SKris Buschelman ierr = MatSeqBAIJ_UpdateFactorNumeric_NaturalOrdering(inA);CHKERRQ(ierr); 1164cf242676SKris Buschelman } else { 1165c38d4ed2SBarry Smith if (!a->solve_work) { 1166*87828ca2SBarry Smith ierr = PetscMalloc((inA->m+a->bs)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 1167*87828ca2SBarry Smith PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(PetscScalar)); 1168c38d4ed2SBarry Smith } 11692d61bbb3SSatish Balay } 11702d61bbb3SSatish Balay 1171667159a5SBarry Smith ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr); 1172667159a5SBarry Smith 11732d61bbb3SSatish Balay PetscFunctionReturn(0); 11742d61bbb3SSatish Balay } 11754a2ae208SSatish Balay #undef __FUNCT__ 11764a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ" 1177ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A) 1178ba4ca20aSSatish Balay { 1179c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1180ba4ca20aSSatish Balay MPI_Comm comm = A->comm; 1181d132466eSBarry Smith int ierr; 1182ba4ca20aSSatish Balay 11833a40ed3dSBarry Smith PetscFunctionBegin; 1184c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1185d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1186d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_block_size <block_size>\n");CHKERRQ(ierr); 11873a40ed3dSBarry Smith PetscFunctionReturn(0); 1188ba4ca20aSSatish Balay } 1189d9b7c43dSSatish Balay 1190fb2e594dSBarry Smith EXTERN_C_BEGIN 11914a2ae208SSatish Balay #undef __FUNCT__ 11924a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ" 119327a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices) 119427a8da17SBarry Smith { 119527a8da17SBarry Smith Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data; 119627a8da17SBarry Smith int i,nz,n; 119727a8da17SBarry Smith 119827a8da17SBarry Smith PetscFunctionBegin; 119927a8da17SBarry Smith nz = baij->maxnz; 1200273d9f13SBarry Smith n = mat->n; 120127a8da17SBarry Smith for (i=0; i<nz; i++) { 120227a8da17SBarry Smith baij->j[i] = indices[i]; 120327a8da17SBarry Smith } 120427a8da17SBarry Smith baij->nz = nz; 120527a8da17SBarry Smith for (i=0; i<n; i++) { 120627a8da17SBarry Smith baij->ilen[i] = baij->imax[i]; 120727a8da17SBarry Smith } 120827a8da17SBarry Smith 120927a8da17SBarry Smith PetscFunctionReturn(0); 121027a8da17SBarry Smith } 1211fb2e594dSBarry Smith EXTERN_C_END 121227a8da17SBarry Smith 12134a2ae208SSatish Balay #undef __FUNCT__ 12144a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices" 121527a8da17SBarry Smith /*@ 121627a8da17SBarry Smith MatSeqBAIJSetColumnIndices - Set the column indices for all the rows 121727a8da17SBarry Smith in the matrix. 121827a8da17SBarry Smith 121927a8da17SBarry Smith Input Parameters: 122027a8da17SBarry Smith + mat - the SeqBAIJ matrix 122127a8da17SBarry Smith - indices - the column indices 122227a8da17SBarry Smith 122315091d37SBarry Smith Level: advanced 122415091d37SBarry Smith 122527a8da17SBarry Smith Notes: 122627a8da17SBarry Smith This can be called if you have precomputed the nonzero structure of the 122727a8da17SBarry Smith matrix and want to provide it to the matrix object to improve the performance 122827a8da17SBarry Smith of the MatSetValues() operation. 122927a8da17SBarry Smith 123027a8da17SBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 123127a8da17SBarry Smith MatCreateSeqBAIJ(). 123227a8da17SBarry Smith 123327a8da17SBarry Smith MUST be called before any calls to MatSetValues(); 123427a8da17SBarry Smith 123527a8da17SBarry Smith @*/ 123627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices) 123727a8da17SBarry Smith { 123827a8da17SBarry Smith int ierr,(*f)(Mat,int *); 123927a8da17SBarry Smith 124027a8da17SBarry Smith PetscFunctionBegin; 124127a8da17SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1242b9617806SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr); 124327a8da17SBarry Smith if (f) { 124427a8da17SBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 124527a8da17SBarry Smith } else { 124629bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 124727a8da17SBarry Smith } 124827a8da17SBarry Smith PetscFunctionReturn(0); 124927a8da17SBarry Smith } 125027a8da17SBarry Smith 12514a2ae208SSatish Balay #undef __FUNCT__ 12524a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ" 1253273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v) 1254273d9f13SBarry Smith { 1255273d9f13SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1256273d9f13SBarry Smith int ierr,i,j,n,row,bs,*ai,*aj,mbs; 1257273d9f13SBarry Smith PetscReal atmp; 1258*87828ca2SBarry Smith PetscScalar *x,zero = 0.0; 1259273d9f13SBarry Smith MatScalar *aa; 1260273d9f13SBarry Smith int ncols,brow,krow,kcol; 1261273d9f13SBarry Smith 1262273d9f13SBarry Smith PetscFunctionBegin; 1263273d9f13SBarry Smith if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1264273d9f13SBarry Smith bs = a->bs; 1265273d9f13SBarry Smith aa = a->a; 1266273d9f13SBarry Smith ai = a->i; 1267273d9f13SBarry Smith aj = a->j; 1268273d9f13SBarry Smith mbs = a->mbs; 1269273d9f13SBarry Smith 1270273d9f13SBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 1271273d9f13SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1272273d9f13SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1273273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1274273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1275273d9f13SBarry Smith ncols = ai[1] - ai[0]; ai++; 1276273d9f13SBarry Smith brow = bs*i; 1277273d9f13SBarry Smith for (j=0; j<ncols; j++){ 1278273d9f13SBarry Smith /* bcol = bs*(*aj); */ 1279273d9f13SBarry Smith for (kcol=0; kcol<bs; kcol++){ 1280273d9f13SBarry Smith for (krow=0; krow<bs; krow++){ 1281273d9f13SBarry Smith atmp = PetscAbsScalar(*aa); aa++; 1282273d9f13SBarry Smith row = brow + krow; /* row index */ 1283273d9f13SBarry Smith /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */ 1284273d9f13SBarry Smith if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp; 1285273d9f13SBarry Smith } 1286273d9f13SBarry Smith } 1287273d9f13SBarry Smith aj++; 1288273d9f13SBarry Smith } 1289273d9f13SBarry Smith } 1290273d9f13SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1291273d9f13SBarry Smith PetscFunctionReturn(0); 1292273d9f13SBarry Smith } 1293273d9f13SBarry Smith 12944a2ae208SSatish Balay #undef __FUNCT__ 12954a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ" 1296273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A) 1297273d9f13SBarry Smith { 1298273d9f13SBarry Smith int ierr; 1299273d9f13SBarry Smith 1300273d9f13SBarry Smith PetscFunctionBegin; 1301273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr); 1302273d9f13SBarry Smith PetscFunctionReturn(0); 1303273d9f13SBarry Smith } 1304273d9f13SBarry Smith 13054a2ae208SSatish Balay #undef __FUNCT__ 13064a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ" 1307*87828ca2SBarry Smith int MatGetArray_SeqBAIJ(Mat A,PetscScalar **array) 1308f2a5309cSSatish Balay { 1309f2a5309cSSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; 1310f2a5309cSSatish Balay PetscFunctionBegin; 1311f2a5309cSSatish Balay *array = a->a; 1312f2a5309cSSatish Balay PetscFunctionReturn(0); 1313f2a5309cSSatish Balay } 1314f2a5309cSSatish Balay 13154a2ae208SSatish Balay #undef __FUNCT__ 13164a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ" 1317*87828ca2SBarry Smith int MatRestoreArray_SeqBAIJ(Mat A,PetscScalar **array) 1318f2a5309cSSatish Balay { 1319f2a5309cSSatish Balay PetscFunctionBegin; 1320f2a5309cSSatish Balay PetscFunctionReturn(0); 1321f2a5309cSSatish Balay } 1322f2a5309cSSatish Balay 13232593348eSBarry Smith /* -------------------------------------------------------------------*/ 1324cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ, 1325cc2dc46cSBarry Smith MatGetRow_SeqBAIJ, 1326cc2dc46cSBarry Smith MatRestoreRow_SeqBAIJ, 1327cc2dc46cSBarry Smith MatMult_SeqBAIJ_N, 1328cc2dc46cSBarry Smith MatMultAdd_SeqBAIJ_N, 13297c922b88SBarry Smith MatMultTranspose_SeqBAIJ, 13307c922b88SBarry Smith MatMultTransposeAdd_SeqBAIJ, 1331cc2dc46cSBarry Smith MatSolve_SeqBAIJ_N, 1332cc2dc46cSBarry Smith 0, 1333cc2dc46cSBarry Smith 0, 1334cc2dc46cSBarry Smith 0, 1335cc2dc46cSBarry Smith MatLUFactor_SeqBAIJ, 1336cc2dc46cSBarry Smith 0, 1337b6490206SBarry Smith 0, 1338f2501298SSatish Balay MatTranspose_SeqBAIJ, 1339cc2dc46cSBarry Smith MatGetInfo_SeqBAIJ, 1340cc2dc46cSBarry Smith MatEqual_SeqBAIJ, 1341cc2dc46cSBarry Smith MatGetDiagonal_SeqBAIJ, 1342cc2dc46cSBarry Smith MatDiagonalScale_SeqBAIJ, 1343cc2dc46cSBarry Smith MatNorm_SeqBAIJ, 1344b6490206SBarry Smith 0, 1345cc2dc46cSBarry Smith MatAssemblyEnd_SeqBAIJ, 1346cc2dc46cSBarry Smith 0, 1347cc2dc46cSBarry Smith MatSetOption_SeqBAIJ, 1348cc2dc46cSBarry Smith MatZeroEntries_SeqBAIJ, 1349cc2dc46cSBarry Smith MatZeroRows_SeqBAIJ, 1350cc2dc46cSBarry Smith MatLUFactorSymbolic_SeqBAIJ, 1351cc2dc46cSBarry Smith MatLUFactorNumeric_SeqBAIJ_N, 1352cc2dc46cSBarry Smith 0, 1353cc2dc46cSBarry Smith 0, 1354273d9f13SBarry Smith MatSetUpPreallocation_SeqBAIJ, 1355273d9f13SBarry Smith 0, 1356cc2dc46cSBarry Smith MatGetOwnershipRange_SeqBAIJ, 1357cc2dc46cSBarry Smith MatILUFactorSymbolic_SeqBAIJ, 1358cc2dc46cSBarry Smith 0, 1359f2a5309cSSatish Balay MatGetArray_SeqBAIJ, 1360f2a5309cSSatish Balay MatRestoreArray_SeqBAIJ, 13612e8a6d31SBarry Smith MatDuplicate_SeqBAIJ, 1362cc2dc46cSBarry Smith 0, 1363cc2dc46cSBarry Smith 0, 1364cc2dc46cSBarry Smith MatILUFactor_SeqBAIJ, 1365cc2dc46cSBarry Smith 0, 1366cc2dc46cSBarry Smith 0, 1367cc2dc46cSBarry Smith MatGetSubMatrices_SeqBAIJ, 1368cc2dc46cSBarry Smith MatIncreaseOverlap_SeqBAIJ, 1369cc2dc46cSBarry Smith MatGetValues_SeqBAIJ, 1370cc2dc46cSBarry Smith 0, 1371cc2dc46cSBarry Smith MatPrintHelp_SeqBAIJ, 1372cc2dc46cSBarry Smith MatScale_SeqBAIJ, 1373cc2dc46cSBarry Smith 0, 1374cc2dc46cSBarry Smith 0, 1375cc2dc46cSBarry Smith 0, 1376cc2dc46cSBarry Smith MatGetBlockSize_SeqBAIJ, 13773b2fbd54SBarry Smith MatGetRowIJ_SeqBAIJ, 137892c4ed94SBarry Smith MatRestoreRowIJ_SeqBAIJ, 1379cc2dc46cSBarry Smith 0, 1380cc2dc46cSBarry Smith 0, 1381cc2dc46cSBarry Smith 0, 1382cc2dc46cSBarry Smith 0, 1383cc2dc46cSBarry Smith 0, 1384cc2dc46cSBarry Smith 0, 1385d3825aa8SBarry Smith MatSetValuesBlocked_SeqBAIJ, 1386cc2dc46cSBarry Smith MatGetSubMatrix_SeqBAIJ, 1387b9b97703SBarry Smith MatDestroy_SeqBAIJ, 1388b9b97703SBarry Smith MatView_SeqBAIJ, 13893a64cc32SBarry Smith MatGetPetscMaps_Petsc, 1390273d9f13SBarry Smith 0, 1391273d9f13SBarry Smith 0, 1392273d9f13SBarry Smith 0, 1393273d9f13SBarry Smith 0, 1394273d9f13SBarry Smith 0, 1395273d9f13SBarry Smith 0, 1396273d9f13SBarry Smith MatGetRowMax_SeqBAIJ, 1397273d9f13SBarry Smith MatConvert_Basic}; 13982593348eSBarry Smith 13993e90b805SBarry Smith EXTERN_C_BEGIN 14004a2ae208SSatish Balay #undef __FUNCT__ 14014a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ" 14023e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat) 14033e90b805SBarry Smith { 14043e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1405273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2; 1406d132466eSBarry Smith int ierr; 14073e90b805SBarry Smith 14083e90b805SBarry Smith PetscFunctionBegin; 14093e90b805SBarry Smith if (aij->nonew != 1) { 141029bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14113e90b805SBarry Smith } 14123e90b805SBarry Smith 14133e90b805SBarry Smith /* allocate space for values if not already there */ 14143e90b805SBarry Smith if (!aij->saved_values) { 1415*87828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 14163e90b805SBarry Smith } 14173e90b805SBarry Smith 14183e90b805SBarry Smith /* copy values over */ 1419*87828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 14203e90b805SBarry Smith PetscFunctionReturn(0); 14213e90b805SBarry Smith } 14223e90b805SBarry Smith EXTERN_C_END 14233e90b805SBarry Smith 14243e90b805SBarry Smith EXTERN_C_BEGIN 14254a2ae208SSatish Balay #undef __FUNCT__ 14264a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ" 142732e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat) 14283e90b805SBarry Smith { 14293e90b805SBarry Smith Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data; 1430273d9f13SBarry Smith int nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr; 14313e90b805SBarry Smith 14323e90b805SBarry Smith PetscFunctionBegin; 14333e90b805SBarry Smith if (aij->nonew != 1) { 143429bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 14353e90b805SBarry Smith } 14363e90b805SBarry Smith if (!aij->saved_values) { 143729bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 14383e90b805SBarry Smith } 14393e90b805SBarry Smith 14403e90b805SBarry Smith /* copy values over */ 1441*87828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 14423e90b805SBarry Smith PetscFunctionReturn(0); 14433e90b805SBarry Smith } 14443e90b805SBarry Smith EXTERN_C_END 14453e90b805SBarry Smith 1446273d9f13SBarry Smith EXTERN_C_BEGIN 1447273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*); 1448273d9f13SBarry Smith EXTERN_C_END 1449273d9f13SBarry Smith 1450273d9f13SBarry Smith EXTERN_C_BEGIN 14514a2ae208SSatish Balay #undef __FUNCT__ 14524a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ" 1453273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B) 14542593348eSBarry Smith { 1455273d9f13SBarry Smith int ierr,size; 1456b6490206SBarry Smith Mat_SeqBAIJ *b; 14573b2fbd54SBarry Smith 14583a40ed3dSBarry Smith PetscFunctionBegin; 1459273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 146029bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1461b6490206SBarry Smith 1462273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 1463273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 1464b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr); 1465b0a32e0cSBarry Smith B->data = (void*)b; 1466549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr); 1467549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 14682593348eSBarry Smith B->factor = 0; 14692593348eSBarry Smith B->lupivotthreshold = 1.0; 147090f02eecSBarry Smith B->mapping = 0; 14712593348eSBarry Smith b->row = 0; 14722593348eSBarry Smith b->col = 0; 1473e51c0b9cSSatish Balay b->icol = 0; 14742593348eSBarry Smith b->reallocs = 0; 14753e90b805SBarry Smith b->saved_values = 0; 1476cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE) 1477563b5814SBarry Smith b->setvalueslen = 0; 1478563b5814SBarry Smith b->setvaluescopy = PETSC_NULL; 1479563b5814SBarry Smith #endif 14808661488fSKris Buschelman b->single_precision_solves = PETSC_FALSE; 14812593348eSBarry Smith 14823a64cc32SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 14833a64cc32SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 1484a5ae1ecdSBarry Smith 1485c4992f7dSBarry Smith b->sorted = PETSC_FALSE; 1486c4992f7dSBarry Smith b->roworiented = PETSC_TRUE; 14872593348eSBarry Smith b->nonew = 0; 14882593348eSBarry Smith b->diag = 0; 14892593348eSBarry Smith b->solve_work = 0; 1490de6a44a3SBarry Smith b->mult_work = 0; 14912593348eSBarry Smith b->spptr = 0; 14920e6d2581SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1493883fce79SBarry Smith b->keepzeroedrows = PETSC_FALSE; 14944e220ebcSLois Curfman McInnes 1495f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 14963e90b805SBarry Smith "MatStoreValues_SeqBAIJ", 1497bc4b532fSSatish Balay MatStoreValues_SeqBAIJ);CHKERRQ(ierr); 1498f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 14993e90b805SBarry Smith "MatRetrieveValues_SeqBAIJ", 1500bc4b532fSSatish Balay MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr); 1501f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C", 150227a8da17SBarry Smith "MatSeqBAIJSetColumnIndices_SeqBAIJ", 1503bc4b532fSSatish Balay MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr); 1504273d9f13SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C", 1505273d9f13SBarry Smith "MatConvert_SeqBAIJ_SeqAIJ", 1506273d9f13SBarry Smith MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr); 15073a40ed3dSBarry Smith PetscFunctionReturn(0); 15082593348eSBarry Smith } 1509273d9f13SBarry Smith EXTERN_C_END 15102593348eSBarry Smith 15114a2ae208SSatish Balay #undef __FUNCT__ 15124a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ" 15132e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 15142593348eSBarry Smith { 15152593348eSBarry Smith Mat C; 1516b6490206SBarry Smith Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data; 151727a8da17SBarry Smith int i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr; 1518de6a44a3SBarry Smith 15193a40ed3dSBarry Smith PetscFunctionBegin; 152029bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 15212593348eSBarry Smith 15222593348eSBarry Smith *B = 0; 1523273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 1524273d9f13SBarry Smith ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr); 1525273d9f13SBarry Smith c = (Mat_SeqBAIJ*)C->data; 152644cd7ae7SLois Curfman McInnes 1527b6490206SBarry Smith c->bs = a->bs; 15289df24120SSatish Balay c->bs2 = a->bs2; 1529b6490206SBarry Smith c->mbs = a->mbs; 1530b6490206SBarry Smith c->nbs = a->nbs; 153135d8aa7fSBarry Smith ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 15322593348eSBarry Smith 1533b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 1534b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 1535b6490206SBarry Smith for (i=0; i<mbs; i++) { 15362593348eSBarry Smith c->imax[i] = a->imax[i]; 15372593348eSBarry Smith c->ilen[i] = a->ilen[i]; 15382593348eSBarry Smith } 15392593348eSBarry Smith 15402593348eSBarry Smith /* allocate the matrix space */ 1541c4992f7dSBarry Smith c->singlemalloc = PETSC_TRUE; 15423f1db9ecSBarry Smith len = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int)); 1543b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 15447e67e3f9SSatish Balay c->j = (int*)(c->a + nz*bs2); 1545de6a44a3SBarry Smith c->i = c->j + nz; 1546549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr); 1547b6490206SBarry Smith if (mbs > 0) { 1548549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr); 15492e8a6d31SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 1550549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 15512e8a6d31SBarry Smith } else { 1552549d3d68SSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 15532593348eSBarry Smith } 15542593348eSBarry Smith } 15552593348eSBarry Smith 1556b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 15572593348eSBarry Smith c->sorted = a->sorted; 15582593348eSBarry Smith c->roworiented = a->roworiented; 15592593348eSBarry Smith c->nonew = a->nonew; 15602593348eSBarry Smith 15612593348eSBarry Smith if (a->diag) { 1562b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 1563b0a32e0cSBarry Smith PetscLogObjectMemory(C,(mbs+1)*sizeof(int)); 1564b6490206SBarry Smith for (i=0; i<mbs; i++) { 15652593348eSBarry Smith c->diag[i] = a->diag[i]; 15662593348eSBarry Smith } 156798305bb5SBarry Smith } else c->diag = 0; 15682593348eSBarry Smith c->nz = a->nz; 15692593348eSBarry Smith c->maxnz = a->maxnz; 15702593348eSBarry Smith c->solve_work = 0; 15712593348eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 15727fc0212eSBarry Smith c->mult_work = 0; 1573273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 1574273d9f13SBarry Smith C->assembled = PETSC_TRUE; 15752593348eSBarry Smith *B = C; 1576b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 15773a40ed3dSBarry Smith PetscFunctionReturn(0); 15782593348eSBarry Smith } 15792593348eSBarry Smith 1580273d9f13SBarry Smith EXTERN_C_BEGIN 15814a2ae208SSatish Balay #undef __FUNCT__ 15824a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ" 1583b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A) 15842593348eSBarry Smith { 1585b6490206SBarry Smith Mat_SeqBAIJ *a; 15862593348eSBarry Smith Mat B; 1587f1af5d2fSBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1; 1588b6490206SBarry Smith int *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount; 158935aab85fSBarry Smith int kmax,jcount,block,idx,point,nzcountb,extra_rows; 1590a7c10996SSatish Balay int *masked,nmask,tmp,bs2,ishift; 1591*87828ca2SBarry Smith PetscScalar *aa; 159219bcc07fSBarry Smith MPI_Comm comm = ((PetscObject)viewer)->comm; 15932593348eSBarry Smith 15943a40ed3dSBarry Smith PetscFunctionBegin; 1595b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 1596de6a44a3SBarry Smith bs2 = bs*bs; 1597b6490206SBarry Smith 1598d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 159929bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 1600b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 16010752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 160229bbc08cSBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 16032593348eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 16042593348eSBarry Smith 1605d64ed03dSBarry Smith if (header[3] < 0) { 160629bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ"); 1607d64ed03dSBarry Smith } 1608d64ed03dSBarry Smith 160929bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 161035aab85fSBarry Smith 161135aab85fSBarry Smith /* 161235aab85fSBarry Smith This code adds extra rows to make sure the number of rows is 161335aab85fSBarry Smith divisible by the blocksize 161435aab85fSBarry Smith */ 1615b6490206SBarry Smith mbs = M/bs; 161635aab85fSBarry Smith extra_rows = bs - M + bs*(mbs); 161735aab85fSBarry Smith if (extra_rows == bs) extra_rows = 0; 161835aab85fSBarry Smith else mbs++; 161935aab85fSBarry Smith if (extra_rows) { 1620b0a32e0cSBarry Smith PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n"); 162135aab85fSBarry Smith } 1622b6490206SBarry Smith 16232593348eSBarry Smith /* read in row lengths */ 1624b0a32e0cSBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr); 16250752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 162635aab85fSBarry Smith for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 16272593348eSBarry Smith 1628b6490206SBarry Smith /* read in column indices */ 1629b0a32e0cSBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr); 16300752156aSBarry Smith ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 163135aab85fSBarry Smith for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 1632b6490206SBarry Smith 1633b6490206SBarry Smith /* loop over row lengths determining block row lengths */ 1634b0a32e0cSBarry Smith ierr = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr); 1635549d3d68SSatish Balay ierr = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr); 1636b0a32e0cSBarry Smith ierr = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr); 1637549d3d68SSatish Balay ierr = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr); 163835aab85fSBarry Smith masked = mask + mbs; 1639b6490206SBarry Smith rowcount = 0; nzcount = 0; 1640b6490206SBarry Smith for (i=0; i<mbs; i++) { 164135aab85fSBarry Smith nmask = 0; 1642b6490206SBarry Smith for (j=0; j<bs; j++) { 1643b6490206SBarry Smith kmax = rowlengths[rowcount]; 1644b6490206SBarry Smith for (k=0; k<kmax; k++) { 164535aab85fSBarry Smith tmp = jj[nzcount++]/bs; 164635aab85fSBarry Smith if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;} 1647b6490206SBarry Smith } 1648b6490206SBarry Smith rowcount++; 1649b6490206SBarry Smith } 165035aab85fSBarry Smith browlengths[i] += nmask; 165135aab85fSBarry Smith /* zero out the mask elements we set */ 165235aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1653b6490206SBarry Smith } 1654b6490206SBarry Smith 16552593348eSBarry Smith /* create our matrix */ 16563eee16b0SBarry Smith ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr); 16572593348eSBarry Smith B = *A; 1658b6490206SBarry Smith a = (Mat_SeqBAIJ*)B->data; 16592593348eSBarry Smith 16602593348eSBarry Smith /* set matrix "i" values */ 1661de6a44a3SBarry Smith a->i[0] = 0; 1662b6490206SBarry Smith for (i=1; i<= mbs; i++) { 1663b6490206SBarry Smith a->i[i] = a->i[i-1] + browlengths[i-1]; 1664b6490206SBarry Smith a->ilen[i-1] = browlengths[i-1]; 16652593348eSBarry Smith } 1666b6490206SBarry Smith a->nz = 0; 1667b6490206SBarry Smith for (i=0; i<mbs; i++) a->nz += browlengths[i]; 16682593348eSBarry Smith 1669b6490206SBarry Smith /* read in nonzero values */ 1670*87828ca2SBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscScalar),&aa);CHKERRQ(ierr); 16710752156aSBarry Smith ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 167235aab85fSBarry Smith for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 1673b6490206SBarry Smith 1674b6490206SBarry Smith /* set "a" and "j" values into matrix */ 1675b6490206SBarry Smith nzcount = 0; jcount = 0; 1676b6490206SBarry Smith for (i=0; i<mbs; i++) { 1677b6490206SBarry Smith nzcountb = nzcount; 167835aab85fSBarry Smith nmask = 0; 1679b6490206SBarry Smith for (j=0; j<bs; j++) { 1680b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1681b6490206SBarry Smith for (k=0; k<kmax; k++) { 168235aab85fSBarry Smith tmp = jj[nzcount++]/bs; 168335aab85fSBarry Smith if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;} 1684b6490206SBarry Smith } 1685b6490206SBarry Smith } 1686de6a44a3SBarry Smith /* sort the masked values */ 1687433994e6SBarry Smith ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 1688de6a44a3SBarry Smith 1689b6490206SBarry Smith /* set "j" values into matrix */ 1690b6490206SBarry Smith maskcount = 1; 169135aab85fSBarry Smith for (j=0; j<nmask; j++) { 169235aab85fSBarry Smith a->j[jcount++] = masked[j]; 1693de6a44a3SBarry Smith mask[masked[j]] = maskcount++; 1694b6490206SBarry Smith } 1695b6490206SBarry Smith /* set "a" values into matrix */ 1696de6a44a3SBarry Smith ishift = bs2*a->i[i]; 1697b6490206SBarry Smith for (j=0; j<bs; j++) { 1698b6490206SBarry Smith kmax = rowlengths[i*bs+j]; 1699b6490206SBarry Smith for (k=0; k<kmax; k++) { 1700de6a44a3SBarry Smith tmp = jj[nzcountb]/bs ; 1701de6a44a3SBarry Smith block = mask[tmp] - 1; 1702de6a44a3SBarry Smith point = jj[nzcountb] - bs*tmp; 1703de6a44a3SBarry Smith idx = ishift + bs2*block + j + bs*point; 1704375fe846SBarry Smith a->a[idx] = (MatScalar)aa[nzcountb++]; 1705b6490206SBarry Smith } 1706b6490206SBarry Smith } 170735aab85fSBarry Smith /* zero out the mask elements we set */ 170835aab85fSBarry Smith for (j=0; j<nmask; j++) mask[masked[j]] = 0; 1709b6490206SBarry Smith } 171029bbc08cSBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 1711b6490206SBarry Smith 1712606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 1713606d414cSSatish Balay ierr = PetscFree(browlengths);CHKERRQ(ierr); 1714606d414cSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 1715606d414cSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 1716606d414cSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 1717b6490206SBarry Smith 1718b6490206SBarry Smith B->assembled = PETSC_TRUE; 1719de6a44a3SBarry Smith 17209c01be13SBarry Smith ierr = MatView_Private(B);CHKERRQ(ierr); 17213a40ed3dSBarry Smith PetscFunctionReturn(0); 17222593348eSBarry Smith } 1723273d9f13SBarry Smith EXTERN_C_END 17242593348eSBarry Smith 17254a2ae208SSatish Balay #undef __FUNCT__ 17264a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ" 1727273d9f13SBarry Smith /*@C 1728273d9f13SBarry Smith MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block 1729273d9f13SBarry Smith compressed row) format. For good matrix assembly performance the 1730273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1731273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1732273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 17332593348eSBarry Smith 1734273d9f13SBarry Smith Collective on MPI_Comm 1735273d9f13SBarry Smith 1736273d9f13SBarry Smith Input Parameters: 1737273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 1738273d9f13SBarry Smith . bs - size of block 1739273d9f13SBarry Smith . m - number of rows 1740273d9f13SBarry Smith . n - number of columns 174135d8aa7fSBarry Smith . nz - number of nonzero blocks per block row (same for all rows) 174235d8aa7fSBarry Smith - nnz - array containing the number of nonzero blocks in the various block rows 1743273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1744273d9f13SBarry Smith 1745273d9f13SBarry Smith Output Parameter: 1746273d9f13SBarry Smith . A - the matrix 1747273d9f13SBarry Smith 1748273d9f13SBarry Smith Options Database Keys: 1749273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1750273d9f13SBarry Smith block calculations (much slower) 1751273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1752273d9f13SBarry Smith 1753273d9f13SBarry Smith Level: intermediate 1754273d9f13SBarry Smith 1755273d9f13SBarry Smith Notes: 175635d8aa7fSBarry Smith A nonzero block is any block that as 1 or more nonzeros in it 175735d8aa7fSBarry Smith 1758273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1759273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1760273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1761273d9f13SBarry Smith 1762273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1763273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1764273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1765273d9f13SBarry Smith matrices. 1766273d9f13SBarry Smith 1767273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1768273d9f13SBarry Smith @*/ 1769273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A) 1770273d9f13SBarry Smith { 1771273d9f13SBarry Smith int ierr; 1772273d9f13SBarry Smith 1773273d9f13SBarry Smith PetscFunctionBegin; 1774273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 1775273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr); 1776273d9f13SBarry Smith ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr); 1777273d9f13SBarry Smith PetscFunctionReturn(0); 1778273d9f13SBarry Smith } 1779273d9f13SBarry Smith 17804a2ae208SSatish Balay #undef __FUNCT__ 17814a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation" 1782273d9f13SBarry Smith /*@C 1783273d9f13SBarry Smith MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros 1784273d9f13SBarry Smith per row in the matrix. For good matrix assembly performance the 1785273d9f13SBarry Smith user should preallocate the matrix storage by setting the parameter nz 1786273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 1787273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 1788273d9f13SBarry Smith 1789273d9f13SBarry Smith Collective on MPI_Comm 1790273d9f13SBarry Smith 1791273d9f13SBarry Smith Input Parameters: 1792273d9f13SBarry Smith + A - the matrix 1793273d9f13SBarry Smith . bs - size of block 1794273d9f13SBarry Smith . nz - number of block nonzeros per block row (same for all rows) 1795273d9f13SBarry Smith - nnz - array containing the number of block nonzeros in the various block rows 1796273d9f13SBarry Smith (possibly different for each block row) or PETSC_NULL 1797273d9f13SBarry Smith 1798273d9f13SBarry Smith Options Database Keys: 1799273d9f13SBarry Smith . -mat_no_unroll - uses code that does not unroll the loops in the 1800273d9f13SBarry Smith block calculations (much slower) 1801273d9f13SBarry Smith . -mat_block_size - size of the blocks to use 1802273d9f13SBarry Smith 1803273d9f13SBarry Smith Level: intermediate 1804273d9f13SBarry Smith 1805273d9f13SBarry Smith Notes: 1806273d9f13SBarry Smith The block AIJ format is fully compatible with standard Fortran 77 1807273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 1808273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 1809273d9f13SBarry Smith 1810273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 1811273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1812273d9f13SBarry Smith allocation. For additional details, see the users manual chapter on 1813273d9f13SBarry Smith matrices. 1814273d9f13SBarry Smith 1815273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ() 1816273d9f13SBarry Smith @*/ 1817273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz) 1818273d9f13SBarry Smith { 1819273d9f13SBarry Smith Mat_SeqBAIJ *b; 1820273d9f13SBarry Smith int i,len,ierr,mbs,nbs,bs2,newbs = bs; 1821273d9f13SBarry Smith PetscTruth flg; 1822273d9f13SBarry Smith 1823273d9f13SBarry Smith PetscFunctionBegin; 1824273d9f13SBarry Smith ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr); 1825273d9f13SBarry Smith if (!flg) PetscFunctionReturn(0); 1826273d9f13SBarry Smith 1827273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1828b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr); 1829273d9f13SBarry Smith if (nnz && newbs != bs) { 1830273d9f13SBarry Smith SETERRQ(1,"Cannot change blocksize from command line if setting nnz"); 1831273d9f13SBarry Smith } 1832273d9f13SBarry Smith bs = newbs; 1833273d9f13SBarry Smith 1834273d9f13SBarry Smith mbs = B->m/bs; 1835273d9f13SBarry Smith nbs = B->n/bs; 1836273d9f13SBarry Smith bs2 = bs*bs; 1837273d9f13SBarry Smith 1838273d9f13SBarry Smith if (mbs*bs!=B->m || nbs*bs!=B->n) { 183935d8aa7fSBarry Smith SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs); 1840273d9f13SBarry Smith } 1841273d9f13SBarry Smith 1842435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1843435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 1844273d9f13SBarry Smith if (nnz) { 1845273d9f13SBarry Smith for (i=0; i<mbs; i++) { 1846273d9f13SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 18473a7fca6bSBarry 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); 1848273d9f13SBarry Smith } 1849273d9f13SBarry Smith } 1850273d9f13SBarry Smith 1851273d9f13SBarry Smith b = (Mat_SeqBAIJ*)B->data; 1852b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr); 185354138f6bSKris Buschelman B->ops->solve = MatSolve_SeqBAIJ_Update; 185454138f6bSKris Buschelman B->ops->solvetranspose = MatSolveTranspose_SeqBAIJ_Update; 1855273d9f13SBarry Smith if (!flg) { 1856273d9f13SBarry Smith switch (bs) { 1857273d9f13SBarry Smith case 1: 1858273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1; 1859273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_1; 1860273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_1; 1861273d9f13SBarry Smith break; 1862273d9f13SBarry Smith case 2: 1863273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2; 1864273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_2; 1865273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_2; 1866273d9f13SBarry Smith break; 1867273d9f13SBarry Smith case 3: 1868273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3; 1869273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_3; 1870273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_3; 1871273d9f13SBarry Smith break; 1872273d9f13SBarry Smith case 4: 1873273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4; 1874273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_4; 1875273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_4; 1876273d9f13SBarry Smith break; 1877273d9f13SBarry Smith case 5: 1878273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5; 1879273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_5; 1880273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_5; 1881273d9f13SBarry Smith break; 1882273d9f13SBarry Smith case 6: 1883273d9f13SBarry Smith B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6; 1884273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_6; 1885273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_6; 1886273d9f13SBarry Smith break; 1887273d9f13SBarry Smith case 7: 188854138f6bSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7; 1889273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_7; 1890273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_7; 1891273d9f13SBarry Smith break; 1892273d9f13SBarry Smith default: 189354138f6bSKris Buschelman B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_N; 1894273d9f13SBarry Smith B->ops->mult = MatMult_SeqBAIJ_N; 1895273d9f13SBarry Smith B->ops->multadd = MatMultAdd_SeqBAIJ_N; 1896273d9f13SBarry Smith break; 1897273d9f13SBarry Smith } 1898273d9f13SBarry Smith } 1899273d9f13SBarry Smith b->bs = bs; 1900273d9f13SBarry Smith b->mbs = mbs; 1901273d9f13SBarry Smith b->nbs = nbs; 1902b0a32e0cSBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 1903273d9f13SBarry Smith if (!nnz) { 1904435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 1905273d9f13SBarry Smith else if (nz <= 0) nz = 1; 1906273d9f13SBarry Smith for (i=0; i<mbs; i++) b->imax[i] = nz; 1907273d9f13SBarry Smith nz = nz*mbs; 1908273d9f13SBarry Smith } else { 1909273d9f13SBarry Smith nz = 0; 1910273d9f13SBarry Smith for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 1911273d9f13SBarry Smith } 1912273d9f13SBarry Smith 1913273d9f13SBarry Smith /* allocate the matrix space */ 1914273d9f13SBarry Smith len = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int); 1915b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 1916273d9f13SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 1917273d9f13SBarry Smith b->j = (int*)(b->a + nz*bs2); 1918273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 1919273d9f13SBarry Smith b->i = b->j + nz; 1920273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 1921273d9f13SBarry Smith 1922273d9f13SBarry Smith b->i[0] = 0; 1923273d9f13SBarry Smith for (i=1; i<mbs+1; i++) { 1924273d9f13SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 1925273d9f13SBarry Smith } 1926273d9f13SBarry Smith 1927273d9f13SBarry Smith /* b->ilen will count nonzeros in each block row so far. */ 192816d6aa21SSatish Balay ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 1929b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ)); 1930273d9f13SBarry Smith for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 1931273d9f13SBarry Smith 1932273d9f13SBarry Smith b->bs = bs; 1933273d9f13SBarry Smith b->bs2 = bs2; 1934273d9f13SBarry Smith b->mbs = mbs; 1935273d9f13SBarry Smith b->nz = 0; 1936273d9f13SBarry Smith b->maxnz = nz*bs2; 1937273d9f13SBarry Smith B->info.nz_unneeded = (PetscReal)b->maxnz; 1938273d9f13SBarry Smith PetscFunctionReturn(0); 1939273d9f13SBarry Smith } 19402593348eSBarry Smith 1941