149b5e25fSSatish Balay 249b5e25fSSatish Balay /* 3a1373b80SHong Zhang Defines the basic matrix operations for the SBAIJ (compressed row) 449b5e25fSSatish Balay matrix storage format. 549b5e25fSSatish Balay */ 6c6db04a5SJed Brown #include <../src/mat/impls/baij/seq/baij.h> /*I "petscmat.h" I*/ 7c6db04a5SJed Brown #include <../src/mat/impls/sbaij/seq/sbaij.h> 8c6db04a5SJed Brown #include <petscblaslapack.h> 949b5e25fSSatish Balay 10c6db04a5SJed Brown #include <../src/mat/impls/sbaij/seq/relax.h> 1170dcbbb9SBarry Smith #define USESHORT 12c6db04a5SJed Brown #include <../src/mat/impls/sbaij/seq/relax.h> 1370dcbbb9SBarry Smith 146214f412SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 15cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqSBAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 166214f412SHong Zhang #endif 1728d58a37SPierre Jolivet PETSC_INTERN PetscErrorCode MatConvert_MPISBAIJ_Basic(Mat,MatType,MatReuse,Mat*); 18b5b17502SBarry Smith 1949b5e25fSSatish Balay /* 2049b5e25fSSatish Balay Checks for missing diagonals 2149b5e25fSSatish Balay */ 22ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqSBAIJ(Mat A,PetscBool *missing,PetscInt *dd) 2349b5e25fSSatish Balay { 24045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 256849ba73SBarry Smith PetscErrorCode ierr; 267734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 2749b5e25fSSatish Balay 2849b5e25fSSatish Balay PetscFunctionBegin; 29045c9aa0SHong Zhang ierr = MatMarkDiagonal_SeqSBAIJ(A);CHKERRQ(ierr); 302af78befSBarry Smith *missing = PETSC_FALSE; 317734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 32358d2f5dSShri Abhyankar *missing = PETSC_TRUE; 33358d2f5dSShri Abhyankar if (dd) *dd = 0; 34955c1f14SBarry Smith ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 35358d2f5dSShri Abhyankar } else { 36358d2f5dSShri Abhyankar diag = a->diag; 3749b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 387734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 392af78befSBarry Smith *missing = PETSC_TRUE; 402af78befSBarry Smith if (dd) *dd = i; 412af78befSBarry Smith break; 422af78befSBarry Smith } 4349b5e25fSSatish Balay } 44358d2f5dSShri Abhyankar } 4549b5e25fSSatish Balay PetscFunctionReturn(0); 4649b5e25fSSatish Balay } 4749b5e25fSSatish Balay 48dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqSBAIJ(Mat A) 4949b5e25fSSatish Balay { 50045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 516849ba73SBarry Smith PetscErrorCode ierr; 5248dd3d27SHong Zhang PetscInt i,j; 5349b5e25fSSatish Balay 5449b5e25fSSatish Balay PetscFunctionBegin; 5509f38230SBarry Smith if (!a->diag) { 56785e854fSJed Brown ierr = PetscMalloc1(a->mbs,&a->diag);CHKERRQ(ierr); 573bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,a->mbs*sizeof(PetscInt));CHKERRQ(ierr); 58c760cd28SBarry Smith a->free_diag = PETSC_TRUE; 5909f38230SBarry Smith } 6048dd3d27SHong Zhang for (i=0; i<a->mbs; i++) { 6148dd3d27SHong Zhang a->diag[i] = a->i[i+1]; 6248dd3d27SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 6348dd3d27SHong Zhang if (a->j[j] == i) { 6448dd3d27SHong Zhang a->diag[i] = j; 6548dd3d27SHong Zhang break; 6648dd3d27SHong Zhang } 6748dd3d27SHong Zhang } 6848dd3d27SHong Zhang } 6949b5e25fSSatish Balay PetscFunctionReturn(0); 7049b5e25fSSatish Balay } 7149b5e25fSSatish Balay 721a83f524SJed Brown static PetscErrorCode MatGetRowIJ_SeqSBAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool blockcompressed,PetscInt *nn,const PetscInt *inia[],const PetscInt *inja[],PetscBool *done) 7349b5e25fSSatish Balay { 74a6ece127SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 758f7157efSSatish Balay PetscErrorCode ierr; 762462f5fdSStefano Zampini PetscInt i,j,n = a->mbs,nz = a->i[n],*tia,*tja,bs = A->rmap->bs,k,l,cnt; 772462f5fdSStefano Zampini PetscInt **ia = (PetscInt**)inia,**ja = (PetscInt**)inja; 7849b5e25fSSatish Balay 7949b5e25fSSatish Balay PetscFunctionBegin; 80d3e5a4abSHong Zhang *nn = n; 81a1373b80SHong Zhang if (!ia) PetscFunctionReturn(0); 822462f5fdSStefano Zampini if (symmetric) { 832462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,PETSC_FALSE,0,0,&tia,&tja);CHKERRQ(ierr); 842462f5fdSStefano Zampini nz = tia[n]; 852462f5fdSStefano Zampini } else { 862462f5fdSStefano Zampini tia = a->i; tja = a->j; 872462f5fdSStefano Zampini } 882462f5fdSStefano Zampini 892462f5fdSStefano Zampini if (!blockcompressed && bs > 1) { 902462f5fdSStefano Zampini (*nn) *= bs; 918f7157efSSatish Balay /* malloc & create the natural set of indices */ 922462f5fdSStefano Zampini ierr = PetscMalloc1((n+1)*bs,ia);CHKERRQ(ierr); 932462f5fdSStefano Zampini if (n) { 942462f5fdSStefano Zampini (*ia)[0] = oshift; 952462f5fdSStefano Zampini for (j=1; j<bs; j++) { 962462f5fdSStefano Zampini (*ia)[j] = (tia[1]-tia[0])*bs+(*ia)[j-1]; 972462f5fdSStefano Zampini } 982462f5fdSStefano Zampini } 992462f5fdSStefano Zampini 1002462f5fdSStefano Zampini for (i=1; i<n; i++) { 1012462f5fdSStefano Zampini (*ia)[i*bs] = (tia[i]-tia[i-1])*bs + (*ia)[i*bs-1]; 1022462f5fdSStefano Zampini for (j=1; j<bs; j++) { 1032462f5fdSStefano Zampini (*ia)[i*bs+j] = (tia[i+1]-tia[i])*bs + (*ia)[i*bs+j-1]; 1042462f5fdSStefano Zampini } 1052462f5fdSStefano Zampini } 1062462f5fdSStefano Zampini if (n) { 1072462f5fdSStefano Zampini (*ia)[n*bs] = (tia[n]-tia[n-1])*bs + (*ia)[n*bs-1]; 1082462f5fdSStefano Zampini } 1092462f5fdSStefano Zampini 1102462f5fdSStefano Zampini if (inja) { 1112462f5fdSStefano Zampini ierr = PetscMalloc1(nz*bs*bs,ja);CHKERRQ(ierr); 1122462f5fdSStefano Zampini cnt = 0; 1132462f5fdSStefano Zampini for (i=0; i<n; i++) { 1148f7157efSSatish Balay for (j=0; j<bs; j++) { 1152462f5fdSStefano Zampini for (k=tia[i]; k<tia[i+1]; k++) { 1162462f5fdSStefano Zampini for (l=0; l<bs; l++) { 1172462f5fdSStefano Zampini (*ja)[cnt++] = bs*tja[k] + l; 1188f7157efSSatish Balay } 1198f7157efSSatish Balay } 1208f7157efSSatish Balay } 1218f7157efSSatish Balay } 1228f7157efSSatish Balay } 1232462f5fdSStefano Zampini 1242462f5fdSStefano Zampini if (symmetric) { /* deallocate memory allocated in MatToSymmetricIJ_SeqAIJ() */ 1252462f5fdSStefano Zampini ierr = PetscFree(tia);CHKERRQ(ierr); 1262462f5fdSStefano Zampini ierr = PetscFree(tja);CHKERRQ(ierr); 1272462f5fdSStefano Zampini } 1282462f5fdSStefano Zampini } else if (oshift == 1) { 1292462f5fdSStefano Zampini if (symmetric) { 1302462f5fdSStefano Zampini nz = tia[A->rmap->n/bs]; 1312462f5fdSStefano Zampini /* add 1 to i and j indices */ 1322462f5fdSStefano Zampini for (i=0; i<A->rmap->n/bs+1; i++) tia[i] = tia[i] + 1; 1332462f5fdSStefano Zampini *ia = tia; 1342462f5fdSStefano Zampini if (ja) { 1352462f5fdSStefano Zampini for (i=0; i<nz; i++) tja[i] = tja[i] + 1; 1362462f5fdSStefano Zampini *ja = tja; 1372462f5fdSStefano Zampini } 1382462f5fdSStefano Zampini } else { 1392462f5fdSStefano Zampini nz = a->i[A->rmap->n/bs]; 1402462f5fdSStefano Zampini /* malloc space and add 1 to i and j indices */ 1412462f5fdSStefano Zampini ierr = PetscMalloc1(A->rmap->n/bs+1,ia);CHKERRQ(ierr); 1422462f5fdSStefano Zampini for (i=0; i<A->rmap->n/bs+1; i++) (*ia)[i] = a->i[i] + 1; 1432462f5fdSStefano Zampini if (ja) { 1442462f5fdSStefano Zampini ierr = PetscMalloc1(nz,ja);CHKERRQ(ierr); 1452462f5fdSStefano Zampini for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 1462462f5fdSStefano Zampini } 1472462f5fdSStefano Zampini } 1482462f5fdSStefano Zampini } else { 1492462f5fdSStefano Zampini *ia = tia; 1502462f5fdSStefano Zampini if (ja) *ja = tja; 151a6ece127SHong Zhang } 15249b5e25fSSatish Balay PetscFunctionReturn(0); 15349b5e25fSSatish Balay } 15449b5e25fSSatish Balay 1551a83f524SJed Brown static PetscErrorCode MatRestoreRowIJ_SeqSBAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool blockcompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 15649b5e25fSSatish Balay { 1578f7157efSSatish Balay PetscErrorCode ierr; 158a6ece127SHong Zhang 15949b5e25fSSatish Balay PetscFunctionBegin; 16049b5e25fSSatish Balay if (!ia) PetscFunctionReturn(0); 1612462f5fdSStefano Zampini if ((!blockcompressed && A->rmap->bs > 1) || (symmetric || oshift == 1)) { 1622462f5fdSStefano Zampini ierr = PetscFree(*ia);CHKERRQ(ierr); 1632462f5fdSStefano Zampini if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 164a6ece127SHong Zhang } 165a6ece127SHong Zhang PetscFunctionReturn(0); 16649b5e25fSSatish Balay } 16749b5e25fSSatish Balay 168dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqSBAIJ(Mat A) 16949b5e25fSSatish Balay { 17049b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 171dfbe8321SBarry Smith PetscErrorCode ierr; 17249b5e25fSSatish Balay 17349b5e25fSSatish Balay PetscFunctionBegin; 174a9f03627SSatish Balay #if defined(PETSC_USE_LOG) 175d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, NZ=%D",A->rmap->N,a->nz); 176a9f03627SSatish Balay #endif 177e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 1787f53bb6cSHong Zhang if (a->free_diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 1796bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 1806bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 1816bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 182c31cb41cSBarry Smith ierr = PetscFree(a->idiag);CHKERRQ(ierr); 183c31cb41cSBarry Smith ierr = PetscFree(a->inode.size);CHKERRQ(ierr); 184c760cd28SBarry Smith if (a->free_imax_ilen) {ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr);} 18505b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 18641f059aeSBarry Smith ierr = PetscFree(a->sor_work);CHKERRQ(ierr); 18705b42c5fSBarry Smith ierr = PetscFree(a->solves_work);CHKERRQ(ierr); 18805b42c5fSBarry Smith ierr = PetscFree(a->mult_work);CHKERRQ(ierr); 18905b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 1904da8f245SBarry Smith if (a->free_jshort) {ierr = PetscFree(a->jshort);CHKERRQ(ierr);} 1911a3463dfSHong Zhang ierr = PetscFree(a->inew);CHKERRQ(ierr); 1926bf464f9SBarry Smith ierr = MatDestroy(&a->parent);CHKERRQ(ierr); 193bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 194901853e0SKris Buschelman 195dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 196bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 197bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 198bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqSBAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 199bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqsbaij_seqaij_C",NULL);CHKERRQ(ierr); 200bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqsbaij_seqbaij_C",NULL);CHKERRQ(ierr); 201bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqSBAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 20238f409ebSLisandro Dalcin ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqSBAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 2036214f412SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 2046214f412SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqsbaij_elemental_C",NULL);CHKERRQ(ierr); 2056214f412SHong Zhang #endif 20649b5e25fSSatish Balay PetscFunctionReturn(0); 20749b5e25fSSatish Balay } 20849b5e25fSSatish Balay 209ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqSBAIJ(Mat A,MatOption op,PetscBool flg) 21049b5e25fSSatish Balay { 211045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 212*eb1ec7c1SStefano Zampini #if defined(PETSC_USE_COMPLEX) 213*eb1ec7c1SStefano Zampini PetscInt bs; 214*eb1ec7c1SStefano Zampini #endif 21563ba0a88SBarry Smith PetscErrorCode ierr; 21649b5e25fSSatish Balay 21749b5e25fSSatish Balay PetscFunctionBegin; 218*eb1ec7c1SStefano Zampini #if defined(PETSC_USE_COMPLEX) 219*eb1ec7c1SStefano Zampini ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 220*eb1ec7c1SStefano Zampini #endif 2214d9d31abSKris Buschelman switch (op) { 2224d9d31abSKris Buschelman case MAT_ROW_ORIENTED: 2234e0d8c25SBarry Smith a->roworiented = flg; 2244d9d31abSKris Buschelman break; 225a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 226a9817697SBarry Smith a->keepnonzeropattern = flg; 2274d9d31abSKris Buschelman break; 228512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 229512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 2304d9d31abSKris Buschelman break; 2314d9d31abSKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 2324e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 2334d9d31abSKris Buschelman break; 2344d9d31abSKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 2354e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 2364d9d31abSKris Buschelman break; 23728b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 23828b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 23928b2fa4aSMatthew Knepley break; 2404e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 2414d9d31abSKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 2424d9d31abSKris Buschelman case MAT_USE_HASH_TABLE: 243071fcb05SBarry Smith case MAT_SORTED_FULL: 244290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 2454d9d31abSKris Buschelman break; 2469a4540c5SBarry Smith case MAT_HERMITIAN: 247*eb1ec7c1SStefano Zampini #if defined(PETSC_USE_COMPLEX) 248*eb1ec7c1SStefano Zampini if (flg) { /* disable transpose ops */ 249*eb1ec7c1SStefano Zampini if (bs > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for Hermitian with block size greater than 1"); 250*eb1ec7c1SStefano Zampini A->ops->multtranspose = NULL; 251*eb1ec7c1SStefano Zampini A->ops->multtransposeadd = NULL; 252*eb1ec7c1SStefano Zampini A->symmetric = PETSC_FALSE; 253*eb1ec7c1SStefano Zampini } 2540f2140c7SStefano Zampini #endif 255eeffb40dSHong Zhang break; 25677e54ba9SKris Buschelman case MAT_SYMMETRIC: 257*eb1ec7c1SStefano Zampini case MAT_SPD: 258*eb1ec7c1SStefano Zampini #if defined(PETSC_USE_COMPLEX) 259*eb1ec7c1SStefano Zampini if (flg) { /* An hermitian and symmetric matrix has zero imaginary part (restore back transpose ops) */ 260*eb1ec7c1SStefano Zampini A->ops->multtranspose = A->ops->mult; 261*eb1ec7c1SStefano Zampini A->ops->multtransposeadd = A->ops->multadd; 262*eb1ec7c1SStefano Zampini } 263*eb1ec7c1SStefano Zampini #endif 264*eb1ec7c1SStefano Zampini break; 265*eb1ec7c1SStefano Zampini /* These options are handled directly by MatSetOption() */ 26677e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 2679a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 268672ba085SHong Zhang case MAT_STRUCTURE_ONLY: 2694dcd73b1SHong Zhang /* These options are handled directly by MatSetOption() */ 270290bbb0aSBarry Smith break; 271941593c8SHong Zhang case MAT_IGNORE_LOWER_TRIANGULAR: 2724e0d8c25SBarry Smith a->ignore_ltriangular = flg; 273941593c8SHong Zhang break; 274941593c8SHong Zhang case MAT_ERROR_LOWER_TRIANGULAR: 2754e0d8c25SBarry Smith a->ignore_ltriangular = flg; 27677e54ba9SKris Buschelman break; 277f5edf698SHong Zhang case MAT_GETROW_UPPERTRIANGULAR: 2784e0d8c25SBarry Smith a->getrow_utriangular = flg; 279f5edf698SHong Zhang break; 280c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 281c10200c1SHong Zhang break; 2824d9d31abSKris Buschelman default: 283e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 28449b5e25fSSatish Balay } 28549b5e25fSSatish Balay PetscFunctionReturn(0); 28649b5e25fSSatish Balay } 28749b5e25fSSatish Balay 28852768537SHong Zhang PetscErrorCode MatGetRow_SeqSBAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 28949b5e25fSSatish Balay { 29049b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 2916849ba73SBarry Smith PetscErrorCode ierr; 29249b5e25fSSatish Balay 29349b5e25fSSatish Balay PetscFunctionBegin; 294e32f2f54SBarry Smith if (A && !a->getrow_utriangular) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatGetRow is not supported for SBAIJ matrix format. Getting the upper triangular part of row, run with -mat_getrow_uppertriangular, call MatSetOption(mat,MAT_GETROW_UPPERTRIANGULAR,PETSC_TRUE) or MatGetRowUpperTriangular()"); 29552768537SHong Zhang 296f5edf698SHong Zhang /* Get the upper triangular part of the row */ 29752768537SHong Zhang ierr = MatGetRow_SeqBAIJ_private(A,row,nz,idx,v,a->i,a->j,a->a);CHKERRQ(ierr); 29849b5e25fSSatish Balay PetscFunctionReturn(0); 29949b5e25fSSatish Balay } 30049b5e25fSSatish Balay 30113f74950SBarry Smith PetscErrorCode MatRestoreRow_SeqSBAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 30249b5e25fSSatish Balay { 303dfbe8321SBarry Smith PetscErrorCode ierr; 30449b5e25fSSatish Balay 30549b5e25fSSatish Balay PetscFunctionBegin; 30605b42c5fSBarry Smith if (idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);} 30705b42c5fSBarry Smith if (v) {ierr = PetscFree(*v);CHKERRQ(ierr);} 30849b5e25fSSatish Balay PetscFunctionReturn(0); 30949b5e25fSSatish Balay } 31049b5e25fSSatish Balay 311f5edf698SHong Zhang PetscErrorCode MatGetRowUpperTriangular_SeqSBAIJ(Mat A) 312f5edf698SHong Zhang { 313f5edf698SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 314f5edf698SHong Zhang 315f5edf698SHong Zhang PetscFunctionBegin; 316f5edf698SHong Zhang a->getrow_utriangular = PETSC_TRUE; 317f5edf698SHong Zhang PetscFunctionReturn(0); 318f5edf698SHong Zhang } 319a323099bSStefano Zampini 320f5edf698SHong Zhang PetscErrorCode MatRestoreRowUpperTriangular_SeqSBAIJ(Mat A) 321f5edf698SHong Zhang { 322f5edf698SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 323f5edf698SHong Zhang 324f5edf698SHong Zhang PetscFunctionBegin; 325f5edf698SHong Zhang a->getrow_utriangular = PETSC_FALSE; 326f5edf698SHong Zhang PetscFunctionReturn(0); 327f5edf698SHong Zhang } 328f5edf698SHong Zhang 329fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqSBAIJ(Mat A,MatReuse reuse,Mat *B) 33049b5e25fSSatish Balay { 331dfbe8321SBarry Smith PetscErrorCode ierr; 3325fd66863SKarl Rupp 33349b5e25fSSatish Balay PetscFunctionBegin; 334cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX) { 335999d9058SBarry Smith ierr = MatDuplicate(A,MAT_COPY_VALUES,B);CHKERRQ(ierr); 336cf37664fSBarry Smith } else if (reuse == MAT_REUSE_MATRIX) { 337cf37664fSBarry Smith ierr = MatCopy(A,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 338fc4dec0aSBarry Smith } 3398115998fSBarry Smith PetscFunctionReturn(0); 34049b5e25fSSatish Balay } 34149b5e25fSSatish Balay 3427da1fb6eSBarry Smith PetscErrorCode MatView_SeqSBAIJ_ASCII(Mat A,PetscViewer viewer) 34349b5e25fSSatish Balay { 34449b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 345dfbe8321SBarry Smith PetscErrorCode ierr; 346d0f46423SBarry Smith PetscInt i,j,bs = A->rmap->bs,k,l,bs2=a->bs2; 347f3ef73ceSBarry Smith PetscViewerFormat format; 348121deb67SSatish Balay PetscInt *diag; 34949b5e25fSSatish Balay 35049b5e25fSSatish Balay PetscFunctionBegin; 351b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 352456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 35377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %D\n",bs);CHKERRQ(ierr); 354fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 355d2507d54SMatthew Knepley Mat aij; 356ade3a672SBarry Smith const char *matname; 357ade3a672SBarry Smith 358d5f3da31SBarry Smith if (A->factortype && bs>1) { 35970d5e725SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"Warning: matrix is factored with bs>1. MatView() with PETSC_VIEWER_ASCII_MATLAB is not supported and ignored!\n");CHKERRQ(ierr); 36070d5e725SHong Zhang PetscFunctionReturn(0); 36170d5e725SHong Zhang } 362c9f458caSMatthew Knepley ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&aij);CHKERRQ(ierr); 363ade3a672SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&matname);CHKERRQ(ierr); 364ade3a672SBarry Smith ierr = PetscObjectSetName((PetscObject)aij,matname);CHKERRQ(ierr); 365c9f458caSMatthew Knepley ierr = MatView(aij,viewer);CHKERRQ(ierr); 3666bf464f9SBarry Smith ierr = MatDestroy(&aij);CHKERRQ(ierr); 367fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 368d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 36949b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 37049b5e25fSSatish Balay for (j=0; j<bs; j++) { 37177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i*bs+j);CHKERRQ(ierr); 37249b5e25fSSatish Balay for (k=a->i[i]; k<a->i[i+1]; k++) { 37349b5e25fSSatish Balay for (l=0; l<bs; l++) { 37449b5e25fSSatish Balay #if defined(PETSC_USE_COMPLEX) 37549b5e25fSSatish Balay if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 37657622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",bs*a->j[k]+l, 37757622a8eSBarry Smith (double)PetscRealPart(a->a[bs2*k + l*bs + j]),(double)PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 37849b5e25fSSatish Balay } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 37957622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i) ",bs*a->j[k]+l, 38057622a8eSBarry Smith (double)PetscRealPart(a->a[bs2*k + l*bs + j]),-(double)PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 38149b5e25fSSatish Balay } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 38257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",bs*a->j[k]+l,(double)PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 38349b5e25fSSatish Balay } 38449b5e25fSSatish Balay #else 38549b5e25fSSatish Balay if (a->a[bs2*k + l*bs + j] != 0.0) { 38657622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",bs*a->j[k]+l,(double)a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 38749b5e25fSSatish Balay } 38849b5e25fSSatish Balay #endif 38949b5e25fSSatish Balay } 39049b5e25fSSatish Balay } 391b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 39249b5e25fSSatish Balay } 39349b5e25fSSatish Balay } 394d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 395c1490034SHong Zhang } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 396c1490034SHong Zhang PetscFunctionReturn(0); 39749b5e25fSSatish Balay } else { 398d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 3992c990fa1SHong Zhang if (A->factortype) { /* for factored matrix */ 4002c990fa1SHong Zhang if (bs>1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"matrix is factored with bs>1. Not implemented yet"); 4012c990fa1SHong Zhang 402121deb67SSatish Balay diag=a->diag; 403121deb67SSatish Balay for (i=0; i<a->mbs; i++) { /* for row block i */ 4042c990fa1SHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 4052c990fa1SHong Zhang /* diagonal entry */ 4062c990fa1SHong Zhang #if defined(PETSC_USE_COMPLEX) 4072c990fa1SHong Zhang if (PetscImaginaryPart(a->a[diag[i]]) > 0.0) { 40857622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",a->j[diag[i]],(double)PetscRealPart(1.0/a->a[diag[i]]),(double)PetscImaginaryPart(1.0/a->a[diag[i]]));CHKERRQ(ierr); 4092c990fa1SHong Zhang } else if (PetscImaginaryPart(a->a[diag[i]]) < 0.0) { 41057622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i) ",a->j[diag[i]],(double)PetscRealPart(1.0/a->a[diag[i]]),-(double)PetscImaginaryPart(1.0/a->a[diag[i]]));CHKERRQ(ierr); 4112c990fa1SHong Zhang } else { 41257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[diag[i]],(double)PetscRealPart(1.0/a->a[diag[i]]));CHKERRQ(ierr); 4132c990fa1SHong Zhang } 4142c990fa1SHong Zhang #else 4156712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[diag[i]],(double)(1.0/a->a[diag[i]]));CHKERRQ(ierr); 4162c990fa1SHong Zhang #endif 4172c990fa1SHong Zhang /* off-diagonal entries */ 4182c990fa1SHong Zhang for (k=a->i[i]; k<a->i[i+1]-1; k++) { 4192c990fa1SHong Zhang #if defined(PETSC_USE_COMPLEX) 420ca0704adSBarry Smith if (PetscImaginaryPart(a->a[k]) > 0.0) { 42157622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",bs*a->j[k],(double)PetscRealPart(a->a[k]),(double)PetscImaginaryPart(a->a[k]));CHKERRQ(ierr); 422ca0704adSBarry Smith } else if (PetscImaginaryPart(a->a[k]) < 0.0) { 42357622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i) ",bs*a->j[k],(double)PetscRealPart(a->a[k]),-(double)PetscImaginaryPart(a->a[k]));CHKERRQ(ierr); 4242c990fa1SHong Zhang } else { 42557622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",bs*a->j[k],(double)PetscRealPart(a->a[k]));CHKERRQ(ierr); 4262c990fa1SHong Zhang } 4272c990fa1SHong Zhang #else 42857622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[k],(double)a->a[k]);CHKERRQ(ierr); 4292c990fa1SHong Zhang #endif 4302c990fa1SHong Zhang } 4312c990fa1SHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 4322c990fa1SHong Zhang } 4332c990fa1SHong Zhang 4342c990fa1SHong Zhang } else { /* for non-factored matrix */ 4350c74a584SJed Brown for (i=0; i<a->mbs; i++) { /* for row block i */ 4360c74a584SJed Brown for (j=0; j<bs; j++) { /* for row bs*i + j */ 43777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i*bs+j);CHKERRQ(ierr); 4380c74a584SJed Brown for (k=a->i[i]; k<a->i[i+1]; k++) { /* for column block */ 4390c74a584SJed Brown for (l=0; l<bs; l++) { /* for column */ 44049b5e25fSSatish Balay #if defined(PETSC_USE_COMPLEX) 44149b5e25fSSatish Balay if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 44257622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",bs*a->j[k]+l, 44357622a8eSBarry Smith (double)PetscRealPart(a->a[bs2*k + l*bs + j]),(double)PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 44449b5e25fSSatish Balay } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 44557622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i) ",bs*a->j[k]+l, 44657622a8eSBarry Smith (double)PetscRealPart(a->a[bs2*k + l*bs + j]),-(double)PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 44749b5e25fSSatish Balay } else { 44857622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",bs*a->j[k]+l,(double)PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 44949b5e25fSSatish Balay } 45049b5e25fSSatish Balay #else 45157622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",bs*a->j[k]+l,(double)a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 45249b5e25fSSatish Balay #endif 45349b5e25fSSatish Balay } 45449b5e25fSSatish Balay } 455b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 45649b5e25fSSatish Balay } 45749b5e25fSSatish Balay } 4582c990fa1SHong Zhang } 459d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 46049b5e25fSSatish Balay } 461b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 46249b5e25fSSatish Balay PetscFunctionReturn(0); 46349b5e25fSSatish Balay } 46449b5e25fSSatish Balay 4659804daf3SBarry Smith #include <petscdraw.h> 4666849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 46749b5e25fSSatish Balay { 46849b5e25fSSatish Balay Mat A = (Mat) Aa; 46949b5e25fSSatish Balay Mat_SeqSBAIJ *a=(Mat_SeqSBAIJ*)A->data; 4706849ba73SBarry Smith PetscErrorCode ierr; 471d0f46423SBarry Smith PetscInt row,i,j,k,l,mbs=a->mbs,color,bs=A->rmap->bs,bs2=a->bs2; 47249b5e25fSSatish Balay PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 47349b5e25fSSatish Balay MatScalar *aa; 474b0a32e0cSBarry Smith PetscViewer viewer; 47549b5e25fSSatish Balay 47649b5e25fSSatish Balay PetscFunctionBegin; 47749b5e25fSSatish Balay ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 478b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 47949b5e25fSSatish Balay 48049b5e25fSSatish Balay /* loop over matrix elements drawing boxes */ 481383922c3SLisandro Dalcin 482383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 483383922c3SLisandro Dalcin ierr = PetscDrawString(draw, .3*(xl+xr), .3*(yl+yr), PETSC_DRAW_BLACK, "symmetric");CHKERRQ(ierr); 484383922c3SLisandro Dalcin /* Blue for negative, Cyan for zero and Red for positive */ 485b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 48649b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 48749b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 488d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 48949b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 49049b5e25fSSatish Balay aa = a->a + j*bs2; 49149b5e25fSSatish Balay for (k=0; k<bs; k++) { 49249b5e25fSSatish Balay for (l=0; l<bs; l++) { 49349b5e25fSSatish Balay if (PetscRealPart(*aa++) >= 0.) continue; 494b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 49549b5e25fSSatish Balay } 49649b5e25fSSatish Balay } 49749b5e25fSSatish Balay } 49849b5e25fSSatish Balay } 499b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 50049b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 50149b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 502d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 50349b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 50449b5e25fSSatish Balay aa = a->a + j*bs2; 50549b5e25fSSatish Balay for (k=0; k<bs; k++) { 50649b5e25fSSatish Balay for (l=0; l<bs; l++) { 50749b5e25fSSatish Balay if (PetscRealPart(*aa++) != 0.) continue; 508b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 50949b5e25fSSatish Balay } 51049b5e25fSSatish Balay } 51149b5e25fSSatish Balay } 51249b5e25fSSatish Balay } 513b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 51449b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 51549b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 516d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 51749b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 51849b5e25fSSatish Balay aa = a->a + j*bs2; 51949b5e25fSSatish Balay for (k=0; k<bs; k++) { 52049b5e25fSSatish Balay for (l=0; l<bs; l++) { 52149b5e25fSSatish Balay if (PetscRealPart(*aa++) <= 0.) continue; 522b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 52349b5e25fSSatish Balay } 52449b5e25fSSatish Balay } 52549b5e25fSSatish Balay } 52649b5e25fSSatish Balay } 527383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 52849b5e25fSSatish Balay PetscFunctionReturn(0); 52949b5e25fSSatish Balay } 53049b5e25fSSatish Balay 5316849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_Draw(Mat A,PetscViewer viewer) 53249b5e25fSSatish Balay { 533dfbe8321SBarry Smith PetscErrorCode ierr; 53449b5e25fSSatish Balay PetscReal xl,yl,xr,yr,w,h; 535b0a32e0cSBarry Smith PetscDraw draw; 536ace3abfcSBarry Smith PetscBool isnull; 53749b5e25fSSatish Balay 53849b5e25fSSatish Balay PetscFunctionBegin; 539b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 540383922c3SLisandro Dalcin ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 541383922c3SLisandro Dalcin if (isnull) PetscFunctionReturn(0); 54249b5e25fSSatish Balay 543d0f46423SBarry Smith xr = A->rmap->N; yr = A->rmap->N; h = yr/10.0; w = xr/10.0; 54449b5e25fSSatish Balay xr += w; yr += h; xl = -w; yl = -h; 545b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 546832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 547b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqSBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 5480298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 549832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 55049b5e25fSSatish Balay PetscFunctionReturn(0); 55149b5e25fSSatish Balay } 55249b5e25fSSatish Balay 553dfbe8321SBarry Smith PetscErrorCode MatView_SeqSBAIJ(Mat A,PetscViewer viewer) 55449b5e25fSSatish Balay { 555dfbe8321SBarry Smith PetscErrorCode ierr; 556ace3abfcSBarry Smith PetscBool iascii,isdraw; 55708917f38SBarry Smith FILE *file = 0; 55849b5e25fSSatish Balay 55949b5e25fSSatish Balay PetscFunctionBegin; 560251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 561251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 56232077d6dSBarry Smith if (iascii) { 56349b5e25fSSatish Balay ierr = MatView_SeqSBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 56449b5e25fSSatish Balay } else if (isdraw) { 56549b5e25fSSatish Balay ierr = MatView_SeqSBAIJ_Draw(A,viewer);CHKERRQ(ierr); 56649b5e25fSSatish Balay } else { 567a5e6ed63SBarry Smith Mat B; 568ade3a672SBarry Smith const char *matname; 569ceb03754SKris Buschelman ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 570ade3a672SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&matname);CHKERRQ(ierr); 571ade3a672SBarry Smith ierr = PetscObjectSetName((PetscObject)B,matname);CHKERRQ(ierr); 572a5e6ed63SBarry Smith ierr = MatView(B,viewer);CHKERRQ(ierr); 5736bf464f9SBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 57408917f38SBarry Smith ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 57508917f38SBarry Smith if (file) { 57608917f38SBarry Smith fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs); 57708917f38SBarry Smith } 57849b5e25fSSatish Balay } 57949b5e25fSSatish Balay PetscFunctionReturn(0); 58049b5e25fSSatish Balay } 58149b5e25fSSatish Balay 58249b5e25fSSatish Balay 58313f74950SBarry Smith PetscErrorCode MatGetValues_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 58449b5e25fSSatish Balay { 585045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 58613f74950SBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 58713f74950SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 588d0f46423SBarry Smith PetscInt brow,bcol,ridx,cidx,bs=A->rmap->bs,bs2=a->bs2; 58997e567efSBarry Smith MatScalar *ap,*aa = a->a; 59049b5e25fSSatish Balay 59149b5e25fSSatish Balay PetscFunctionBegin; 59249b5e25fSSatish Balay for (k=0; k<m; k++) { /* loop over rows */ 59349b5e25fSSatish Balay row = im[k]; brow = row/bs; 594e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 595e32f2f54SBarry Smith if (row >= A->rmap->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->N-1); 59649b5e25fSSatish Balay rp = aj + ai[brow]; ap = aa + bs2*ai[brow]; 59749b5e25fSSatish Balay nrow = ailen[brow]; 59849b5e25fSSatish Balay for (l=0; l<n; l++) { /* loop over columns */ 599e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 600e32f2f54SBarry Smith if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1); 60149b5e25fSSatish Balay col = in[l]; 60249b5e25fSSatish Balay bcol = col/bs; 60349b5e25fSSatish Balay cidx = col%bs; 60449b5e25fSSatish Balay ridx = row%bs; 60549b5e25fSSatish Balay high = nrow; 60649b5e25fSSatish Balay low = 0; /* assume unsorted */ 60749b5e25fSSatish Balay while (high-low > 5) { 60849b5e25fSSatish Balay t = (low+high)/2; 60949b5e25fSSatish Balay if (rp[t] > bcol) high = t; 61049b5e25fSSatish Balay else low = t; 61149b5e25fSSatish Balay } 61249b5e25fSSatish Balay for (i=low; i<high; i++) { 61349b5e25fSSatish Balay if (rp[i] > bcol) break; 61449b5e25fSSatish Balay if (rp[i] == bcol) { 61549b5e25fSSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 61649b5e25fSSatish Balay goto finished; 61749b5e25fSSatish Balay } 61849b5e25fSSatish Balay } 61997e567efSBarry Smith *v++ = 0.0; 62049b5e25fSSatish Balay finished:; 62149b5e25fSSatish Balay } 62249b5e25fSSatish Balay } 62349b5e25fSSatish Balay PetscFunctionReturn(0); 62449b5e25fSSatish Balay } 62549b5e25fSSatish Balay 62649b5e25fSSatish Balay 62713f74950SBarry Smith PetscErrorCode MatSetValuesBlocked_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 62849b5e25fSSatish Balay { 6290880e062SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 6306849ba73SBarry Smith PetscErrorCode ierr; 631e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,lastcol = -1; 63213f74950SBarry Smith PetscInt *imax =a->imax,*ai=a->i,*ailen=a->ilen; 633d0f46423SBarry Smith PetscInt *aj =a->j,nonew=a->nonew,bs2=a->bs2,bs=A->rmap->bs,stepval; 634ace3abfcSBarry Smith PetscBool roworiented=a->roworiented; 635dd6ea824SBarry Smith const PetscScalar *value = v; 636f15d580aSBarry Smith MatScalar *ap,*aa = a->a,*bap; 6370880e062SHong Zhang 63849b5e25fSSatish Balay PetscFunctionBegin; 63926fbe8dcSKarl Rupp if (roworiented) stepval = (n-1)*bs; 64026fbe8dcSKarl Rupp else stepval = (m-1)*bs; 64126fbe8dcSKarl Rupp 6420880e062SHong Zhang for (k=0; k<m; k++) { /* loop over added rows */ 6430880e062SHong Zhang row = im[k]; 6440880e062SHong Zhang if (row < 0) continue; 6452515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 6462f7d4af7SBarry Smith if (row >= a->mbs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block index row too large %D max %D",row,a->mbs-1); 6470880e062SHong Zhang #endif 6480880e062SHong Zhang rp = aj + ai[row]; 6490880e062SHong Zhang ap = aa + bs2*ai[row]; 6500880e062SHong Zhang rmax = imax[row]; 6510880e062SHong Zhang nrow = ailen[row]; 6520880e062SHong Zhang low = 0; 653818f2c47SBarry Smith high = nrow; 6540880e062SHong Zhang for (l=0; l<n; l++) { /* loop over added columns */ 6550880e062SHong Zhang if (in[l] < 0) continue; 6560880e062SHong Zhang col = in[l]; 6572515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 6582f7d4af7SBarry Smith if (col >= a->nbs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block index column too large %D max %D",col,a->nbs-1); 659b1823623SSatish Balay #endif 660b98bf0e1SJed Brown if (col < row) { 66126fbe8dcSKarl Rupp if (a->ignore_ltriangular) continue; /* ignore lower triangular block */ 66226fbe8dcSKarl Rupp else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Lower triangular value cannot be set for sbaij format. Ignoring these values, run with -mat_ignore_lower_triangular or call MatSetOption(mat,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_TRUE)"); 663b98bf0e1SJed Brown } 66426fbe8dcSKarl Rupp if (roworiented) value = v + k*(stepval+bs)*bs + l*bs; 66526fbe8dcSKarl Rupp else value = v + l*(stepval+bs)*bs + k*bs; 66626fbe8dcSKarl Rupp 66726fbe8dcSKarl Rupp if (col <= lastcol) low = 0; 66826fbe8dcSKarl Rupp else high = nrow; 66926fbe8dcSKarl Rupp 670e2ee6c50SBarry Smith lastcol = col; 6710880e062SHong Zhang while (high-low > 7) { 6720880e062SHong Zhang t = (low+high)/2; 6730880e062SHong Zhang if (rp[t] > col) high = t; 6740880e062SHong Zhang else low = t; 6750880e062SHong Zhang } 6760880e062SHong Zhang for (i=low; i<high; i++) { 6770880e062SHong Zhang if (rp[i] > col) break; 6780880e062SHong Zhang if (rp[i] == col) { 6790880e062SHong Zhang bap = ap + bs2*i; 6800880e062SHong Zhang if (roworiented) { 6810880e062SHong Zhang if (is == ADD_VALUES) { 6820880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6830880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6840880e062SHong Zhang bap[jj] += *value++; 6850880e062SHong Zhang } 6860880e062SHong Zhang } 6870880e062SHong Zhang } else { 6880880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6890880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6900880e062SHong Zhang bap[jj] = *value++; 6910880e062SHong Zhang } 6920880e062SHong Zhang } 6930880e062SHong Zhang } 6940880e062SHong Zhang } else { 6950880e062SHong Zhang if (is == ADD_VALUES) { 6960880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6970880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6980880e062SHong Zhang *bap++ += *value++; 6990880e062SHong Zhang } 7000880e062SHong Zhang } 7010880e062SHong Zhang } else { 7020880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 7030880e062SHong Zhang for (jj=0; jj<bs; jj++) { 7040880e062SHong Zhang *bap++ = *value++; 7050880e062SHong Zhang } 7060880e062SHong Zhang } 7070880e062SHong Zhang } 7080880e062SHong Zhang } 7090880e062SHong Zhang goto noinsert2; 7100880e062SHong Zhang } 7110880e062SHong Zhang } 7120880e062SHong Zhang if (nonew == 1) goto noinsert2; 7132f7d4af7SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new block index nonzero block (%D, %D) in the matrix", row, col); 714fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,a->mbs,bs2,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 715c03d1d03SSatish Balay N = nrow++ - 1; high++; 7160880e062SHong Zhang /* shift up all the later entries in this row */ 717580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 718580bdb30SBarry Smith ierr = PetscArraymove(ap+bs2*(i+1),ap+bs2*i,bs2*(N-i+1));CHKERRQ(ierr); 719580bdb30SBarry Smith ierr = PetscArrayzero(ap+bs2*i,bs2);CHKERRQ(ierr); 7200880e062SHong Zhang rp[i] = col; 7210880e062SHong Zhang bap = ap + bs2*i; 7220880e062SHong Zhang if (roworiented) { 7230880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 7240880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 7250880e062SHong Zhang bap[jj] = *value++; 7260880e062SHong Zhang } 7270880e062SHong Zhang } 7280880e062SHong Zhang } else { 7290880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 7300880e062SHong Zhang for (jj=0; jj<bs; jj++) { 7310880e062SHong Zhang *bap++ = *value++; 7320880e062SHong Zhang } 7330880e062SHong Zhang } 7340880e062SHong Zhang } 7350880e062SHong Zhang noinsert2:; 7360880e062SHong Zhang low = i; 7370880e062SHong Zhang } 7380880e062SHong Zhang ailen[row] = nrow; 7390880e062SHong Zhang } 7400880e062SHong Zhang PetscFunctionReturn(0); 74149b5e25fSSatish Balay } 74249b5e25fSSatish Balay 74364831d72SBarry Smith /* 74464831d72SBarry Smith This is not yet used 74564831d72SBarry Smith */ 7464108e4d5SBarry Smith PetscErrorCode MatAssemblyEnd_SeqSBAIJ_SeqAIJ_Inode(Mat A) 7470def2e27SBarry Smith { 7480def2e27SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 7490def2e27SBarry Smith PetscErrorCode ierr; 7500def2e27SBarry Smith const PetscInt *ai = a->i, *aj = a->j,*cols; 7510def2e27SBarry Smith PetscInt i = 0,j,blk_size,m = A->rmap->n,node_count = 0,nzx,nzy,*ns,row,nz,cnt,cnt2,*counts; 752ace3abfcSBarry Smith PetscBool flag; 7530def2e27SBarry Smith 7540def2e27SBarry Smith PetscFunctionBegin; 755785e854fSJed Brown ierr = PetscMalloc1(m,&ns);CHKERRQ(ierr); 7560def2e27SBarry Smith while (i < m) { 7570def2e27SBarry Smith nzx = ai[i+1] - ai[i]; /* Number of nonzeros */ 7580def2e27SBarry Smith /* Limits the number of elements in a node to 'a->inode.limit' */ 7590def2e27SBarry Smith for (j=i+1,blk_size=1; j<m && blk_size <a->inode.limit; ++j,++blk_size) { 7600def2e27SBarry Smith nzy = ai[j+1] - ai[j]; 7610def2e27SBarry Smith if (nzy != (nzx - j + i)) break; 762580bdb30SBarry Smith ierr = PetscArraycmp(aj + ai[i] + j - i,aj + ai[j],nzy,&flag);CHKERRQ(ierr); 7630def2e27SBarry Smith if (!flag) break; 7640def2e27SBarry Smith } 7650def2e27SBarry Smith ns[node_count++] = blk_size; 76626fbe8dcSKarl Rupp 7670def2e27SBarry Smith i = j; 7680def2e27SBarry Smith } 7690def2e27SBarry Smith if (!a->inode.size && m && node_count > .9*m) { 7700def2e27SBarry Smith ierr = PetscFree(ns);CHKERRQ(ierr); 7710def2e27SBarry Smith ierr = PetscInfo2(A,"Found %D nodes out of %D rows. Not using Inode routines\n",node_count,m);CHKERRQ(ierr); 7720def2e27SBarry Smith } else { 7730def2e27SBarry Smith a->inode.node_count = node_count; 77426fbe8dcSKarl Rupp 775785e854fSJed Brown ierr = PetscMalloc1(node_count,&a->inode.size);CHKERRQ(ierr); 7763bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,node_count*sizeof(PetscInt));CHKERRQ(ierr); 777580bdb30SBarry Smith ierr = PetscArraycpy(a->inode.size,ns,node_count);CHKERRQ(ierr); 7780def2e27SBarry Smith ierr = PetscFree(ns);CHKERRQ(ierr); 7790def2e27SBarry Smith ierr = PetscInfo3(A,"Found %D nodes of %D. Limit used: %D. Using Inode routines\n",node_count,m,a->inode.limit);CHKERRQ(ierr); 7800def2e27SBarry Smith 7810def2e27SBarry Smith /* count collections of adjacent columns in each inode */ 7820def2e27SBarry Smith row = 0; 7830def2e27SBarry Smith cnt = 0; 7840def2e27SBarry Smith for (i=0; i<node_count; i++) { 7850def2e27SBarry Smith cols = aj + ai[row] + a->inode.size[i]; 7860def2e27SBarry Smith nz = ai[row+1] - ai[row] - a->inode.size[i]; 7870def2e27SBarry Smith for (j=1; j<nz; j++) { 78826fbe8dcSKarl Rupp if (cols[j] != cols[j-1]+1) cnt++; 7890def2e27SBarry Smith } 7900def2e27SBarry Smith cnt++; 7910def2e27SBarry Smith row += a->inode.size[i]; 7920def2e27SBarry Smith } 793785e854fSJed Brown ierr = PetscMalloc1(2*cnt,&counts);CHKERRQ(ierr); 7940def2e27SBarry Smith cnt = 0; 7950def2e27SBarry Smith row = 0; 7960def2e27SBarry Smith for (i=0; i<node_count; i++) { 7970def2e27SBarry Smith cols = aj + ai[row] + a->inode.size[i]; 7980def2e27SBarry Smith counts[2*cnt] = cols[0]; 7990def2e27SBarry Smith nz = ai[row+1] - ai[row] - a->inode.size[i]; 8000def2e27SBarry Smith cnt2 = 1; 8010def2e27SBarry Smith for (j=1; j<nz; j++) { 8020def2e27SBarry Smith if (cols[j] != cols[j-1]+1) { 8030def2e27SBarry Smith counts[2*(cnt++)+1] = cnt2; 8040def2e27SBarry Smith counts[2*cnt] = cols[j]; 8050def2e27SBarry Smith cnt2 = 1; 8060def2e27SBarry Smith } else cnt2++; 8070def2e27SBarry Smith } 8080def2e27SBarry Smith counts[2*(cnt++)+1] = cnt2; 8090def2e27SBarry Smith row += a->inode.size[i]; 8100def2e27SBarry Smith } 81122d28d08SBarry Smith ierr = PetscIntView(2*cnt,counts,0);CHKERRQ(ierr); 8120def2e27SBarry Smith } 81338702af4SBarry Smith PetscFunctionReturn(0); 81438702af4SBarry Smith } 81538702af4SBarry Smith 816dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqSBAIJ(Mat A,MatAssemblyType mode) 81749b5e25fSSatish Balay { 81849b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 8196849ba73SBarry Smith PetscErrorCode ierr; 8208f8f2f0dSBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 821d0f46423SBarry Smith PetscInt m = A->rmap->N,*ip,N,*ailen = a->ilen; 82213f74950SBarry Smith PetscInt mbs = a->mbs,bs2 = a->bs2,rmax = 0; 82349b5e25fSSatish Balay MatScalar *aa = a->a,*ap; 82449b5e25fSSatish Balay 82549b5e25fSSatish Balay PetscFunctionBegin; 82649b5e25fSSatish Balay if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 82749b5e25fSSatish Balay 82849b5e25fSSatish Balay if (m) rmax = ailen[0]; 82949b5e25fSSatish Balay for (i=1; i<mbs; i++) { 83049b5e25fSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 83149b5e25fSSatish Balay fshift += imax[i-1] - ailen[i-1]; 83249b5e25fSSatish Balay rmax = PetscMax(rmax,ailen[i]); 83349b5e25fSSatish Balay if (fshift) { 834580bdb30SBarry Smith ip = aj + ai[i]; 835580bdb30SBarry Smith ap = aa + bs2*ai[i]; 83649b5e25fSSatish Balay N = ailen[i]; 837580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 838580bdb30SBarry Smith ierr = PetscArraymove(ap-bs2*fshift,ap,bs2*N);CHKERRQ(ierr); 83949b5e25fSSatish Balay } 84049b5e25fSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 84149b5e25fSSatish Balay } 84249b5e25fSSatish Balay if (mbs) { 84349b5e25fSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 84449b5e25fSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 84549b5e25fSSatish Balay } 84649b5e25fSSatish Balay /* reset ilen and imax for each row */ 84749b5e25fSSatish Balay for (i=0; i<mbs; i++) { 84849b5e25fSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 84949b5e25fSSatish Balay } 8506c6c5352SBarry Smith a->nz = ai[mbs]; 85149b5e25fSSatish Balay 852b424e231SHong Zhang /* diagonals may have moved, reset it */ 853b424e231SHong Zhang if (a->diag) { 854580bdb30SBarry Smith ierr = PetscArraycpy(a->diag,ai,mbs);CHKERRQ(ierr); 85549b5e25fSSatish Balay } 85626fbe8dcSKarl Rupp if (fshift && a->nounused == -1) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D block size %D, %D unneeded", m, A->cmap->n, A->rmap->bs, fshift*bs2); 85726fbe8dcSKarl Rupp 858d0f46423SBarry Smith ierr = PetscInfo5(A,"Matrix size: %D X %D, block size %D; storage space: %D unneeded, %D used\n",m,A->rmap->N,A->rmap->bs,fshift*bs2,a->nz*bs2);CHKERRQ(ierr); 859ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues is %D\n",a->reallocs);CHKERRQ(ierr); 860ae15b995SBarry Smith ierr = PetscInfo1(A,"Most nonzeros blocks in any row is %D\n",rmax);CHKERRQ(ierr); 86126fbe8dcSKarl Rupp 8628e58a170SBarry Smith A->info.mallocs += a->reallocs; 86349b5e25fSSatish Balay a->reallocs = 0; 86449b5e25fSSatish Balay A->info.nz_unneeded = (PetscReal)fshift*bs2; 865061b2667SBarry Smith a->idiagvalid = PETSC_FALSE; 8664dcd73b1SHong Zhang a->rmax = rmax; 86738702af4SBarry Smith 86838702af4SBarry Smith if (A->cmap->n < 65536 && A->cmap->bs == 1) { 86944e1c64aSLisandro Dalcin if (a->jshort && a->free_jshort) { 87017803ae8SHong Zhang /* when matrix data structure is changed, previous jshort must be replaced */ 87117803ae8SHong Zhang ierr = PetscFree(a->jshort);CHKERRQ(ierr); 87217803ae8SHong Zhang } 873785e854fSJed Brown ierr = PetscMalloc1(a->i[A->rmap->n],&a->jshort);CHKERRQ(ierr); 8743bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,a->i[A->rmap->n]*sizeof(unsigned short));CHKERRQ(ierr); 87538702af4SBarry Smith for (i=0; i<a->i[A->rmap->n]; i++) a->jshort[i] = a->j[i]; 87638702af4SBarry Smith A->ops->mult = MatMult_SeqSBAIJ_1_ushort; 87741f059aeSBarry Smith A->ops->sor = MatSOR_SeqSBAIJ_ushort; 8784da8f245SBarry Smith a->free_jshort = PETSC_TRUE; 87938702af4SBarry Smith } 88049b5e25fSSatish Balay PetscFunctionReturn(0); 88149b5e25fSSatish Balay } 88249b5e25fSSatish Balay 88349b5e25fSSatish Balay /* 88449b5e25fSSatish Balay This function returns an array of flags which indicate the locations of contiguous 88549b5e25fSSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 88649b5e25fSSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 88749b5e25fSSatish Balay Assume: sizes should be long enough to hold all the values. 88849b5e25fSSatish Balay */ 88913f74950SBarry Smith PetscErrorCode MatZeroRows_SeqSBAIJ_Check_Blocks(PetscInt idx[],PetscInt n,PetscInt bs,PetscInt sizes[], PetscInt *bs_max) 89049b5e25fSSatish Balay { 89113f74950SBarry Smith PetscInt i,j,k,row; 892ace3abfcSBarry Smith PetscBool flg; 89349b5e25fSSatish Balay 89449b5e25fSSatish Balay PetscFunctionBegin; 89549b5e25fSSatish Balay for (i=0,j=0; i<n; j++) { 89649b5e25fSSatish Balay row = idx[i]; 89749b5e25fSSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 89849b5e25fSSatish Balay sizes[j] = 1; 89949b5e25fSSatish Balay i++; 90049b5e25fSSatish Balay } else if (i+bs > n) { /* Beginning of a block, but complete block doesn't exist (at idx end) */ 90149b5e25fSSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 90249b5e25fSSatish Balay i++; 90349b5e25fSSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 90449b5e25fSSatish Balay flg = PETSC_TRUE; 90549b5e25fSSatish Balay for (k=1; k<bs; k++) { 90649b5e25fSSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 90749b5e25fSSatish Balay flg = PETSC_FALSE; 90849b5e25fSSatish Balay break; 90949b5e25fSSatish Balay } 91049b5e25fSSatish Balay } 911abc0a331SBarry Smith if (flg) { /* No break in the bs */ 91249b5e25fSSatish Balay sizes[j] = bs; 91349b5e25fSSatish Balay i += bs; 91449b5e25fSSatish Balay } else { 91549b5e25fSSatish Balay sizes[j] = 1; 91649b5e25fSSatish Balay i++; 91749b5e25fSSatish Balay } 91849b5e25fSSatish Balay } 91949b5e25fSSatish Balay } 92049b5e25fSSatish Balay *bs_max = j; 92149b5e25fSSatish Balay PetscFunctionReturn(0); 92249b5e25fSSatish Balay } 92349b5e25fSSatish Balay 92449b5e25fSSatish Balay 92549b5e25fSSatish Balay /* Only add/insert a(i,j) with i<=j (blocks). 92649b5e25fSSatish Balay Any a(i,j) with i>j input by user is ingored. 92749b5e25fSSatish Balay */ 92849b5e25fSSatish Balay 92913f74950SBarry Smith PetscErrorCode MatSetValues_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 93049b5e25fSSatish Balay { 93149b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 9326849ba73SBarry Smith PetscErrorCode ierr; 933e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,lastcol = -1; 93413f74950SBarry Smith PetscInt *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 935d0f46423SBarry Smith PetscInt *aj =a->j,nonew=a->nonew,bs=A->rmap->bs,brow,bcol; 93613f74950SBarry Smith PetscInt ridx,cidx,bs2=a->bs2; 93749b5e25fSSatish Balay MatScalar *ap,value,*aa=a->a,*bap; 93849b5e25fSSatish Balay 93949b5e25fSSatish Balay PetscFunctionBegin; 94049b5e25fSSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 94149b5e25fSSatish Balay row = im[k]; /* row number */ 94249b5e25fSSatish Balay brow = row/bs; /* block row number */ 94349b5e25fSSatish Balay if (row < 0) continue; 9442515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 945e32f2f54SBarry Smith if (row >= A->rmap->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->N-1); 94649b5e25fSSatish Balay #endif 94749b5e25fSSatish Balay rp = aj + ai[brow]; /*ptr to beginning of column value of the row block*/ 94849b5e25fSSatish Balay ap = aa + bs2*ai[brow]; /*ptr to beginning of element value of the row block*/ 94949b5e25fSSatish Balay rmax = imax[brow]; /* maximum space allocated for this row */ 95049b5e25fSSatish Balay nrow = ailen[brow]; /* actual length of this row */ 95149b5e25fSSatish Balay low = 0; 9528509e838SStefano Zampini high = nrow; 95349b5e25fSSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 95449b5e25fSSatish Balay if (in[l] < 0) continue; 9552515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 9565ca5a24fSStefano Zampini if (in[l] >= A->cmap->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->N-1); 95749b5e25fSSatish Balay #endif 95849b5e25fSSatish Balay col = in[l]; 95949b5e25fSSatish Balay bcol = col/bs; /* block col number */ 96049b5e25fSSatish Balay 961941593c8SHong Zhang if (brow > bcol) { 96226fbe8dcSKarl Rupp if (a->ignore_ltriangular) continue; /* ignore lower triangular values */ 96326fbe8dcSKarl Rupp else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Lower triangular value cannot be set for sbaij format. Ignoring these values, run with -mat_ignore_lower_triangular or call MatSetOption(mat,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_TRUE)"); 964941593c8SHong Zhang } 965f4989cb3SHong Zhang 96649b5e25fSSatish Balay ridx = row % bs; cidx = col % bs; /*row and col index inside the block */ 9678549e402SHong Zhang if ((brow==bcol && ridx<=cidx) || (brow<bcol)) { 96849b5e25fSSatish Balay /* element value a(k,l) */ 96926fbe8dcSKarl Rupp if (roworiented) value = v[l + k*n]; 97026fbe8dcSKarl Rupp else value = v[k + l*m]; 97149b5e25fSSatish Balay 97249b5e25fSSatish Balay /* move pointer bap to a(k,l) quickly and add/insert value */ 97326fbe8dcSKarl Rupp if (col <= lastcol) low = 0; 9748509e838SStefano Zampini else high = nrow; 9758509e838SStefano Zampini 976e2ee6c50SBarry Smith lastcol = col; 97749b5e25fSSatish Balay while (high-low > 7) { 97849b5e25fSSatish Balay t = (low+high)/2; 97949b5e25fSSatish Balay if (rp[t] > bcol) high = t; 98049b5e25fSSatish Balay else low = t; 98149b5e25fSSatish Balay } 98249b5e25fSSatish Balay for (i=low; i<high; i++) { 98349b5e25fSSatish Balay if (rp[i] > bcol) break; 98449b5e25fSSatish Balay if (rp[i] == bcol) { 98549b5e25fSSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 98649b5e25fSSatish Balay if (is == ADD_VALUES) *bap += value; 98749b5e25fSSatish Balay else *bap = value; 9888549e402SHong Zhang /* for diag block, add/insert its symmetric element a(cidx,ridx) */ 9898549e402SHong Zhang if (brow == bcol && ridx < cidx) { 9908549e402SHong Zhang bap = ap + bs2*i + bs*ridx + cidx; 9918549e402SHong Zhang if (is == ADD_VALUES) *bap += value; 9928549e402SHong Zhang else *bap = value; 9938549e402SHong Zhang } 99449b5e25fSSatish Balay goto noinsert1; 99549b5e25fSSatish Balay } 99649b5e25fSSatish Balay } 99749b5e25fSSatish Balay 99849b5e25fSSatish Balay if (nonew == 1) goto noinsert1; 999e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); 1000fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,a->mbs,bs2,nrow,brow,bcol,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 100149b5e25fSSatish Balay 1002c03d1d03SSatish Balay N = nrow++ - 1; high++; 100349b5e25fSSatish Balay /* shift up all the later entries in this row */ 1004580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 1005580bdb30SBarry Smith ierr = PetscArraymove(ap+bs2*(i+1),ap+bs2*i,bs2*(N-i+1));CHKERRQ(ierr); 1006580bdb30SBarry Smith ierr = PetscArrayzero(ap+bs2*i,bs2);CHKERRQ(ierr); 100749b5e25fSSatish Balay rp[i] = bcol; 100849b5e25fSSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 10098509e838SStefano Zampini /* for diag block, add/insert its symmetric element a(cidx,ridx) */ 10108509e838SStefano Zampini if (brow == bcol && ridx < cidx) { 10118509e838SStefano Zampini ap[bs2*i + bs*ridx + cidx] = value; 10128509e838SStefano Zampini } 1013e56f5c9eSBarry Smith A->nonzerostate++; 101449b5e25fSSatish Balay noinsert1:; 101549b5e25fSSatish Balay low = i; 10168549e402SHong Zhang } 101749b5e25fSSatish Balay } /* end of loop over added columns */ 101849b5e25fSSatish Balay ailen[brow] = nrow; 101949b5e25fSSatish Balay } /* end of loop over added rows */ 102049b5e25fSSatish Balay PetscFunctionReturn(0); 102149b5e25fSSatish Balay } 102249b5e25fSSatish Balay 10230481f469SBarry Smith PetscErrorCode MatICCFactor_SeqSBAIJ(Mat inA,IS row,const MatFactorInfo *info) 102449b5e25fSSatish Balay { 10254ccecd49SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)inA->data; 102649b5e25fSSatish Balay Mat outA; 1027dfbe8321SBarry Smith PetscErrorCode ierr; 1028ace3abfcSBarry Smith PetscBool row_identity; 102949b5e25fSSatish Balay 103049b5e25fSSatish Balay PetscFunctionBegin; 1031e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 is supported for in-place icc"); 1032c84f5b01SHong Zhang ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1033e32f2f54SBarry Smith if (!row_identity) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix reordering is not supported"); 1034e32f2f54SBarry Smith if (inA->rmap->bs != 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix block size %D is not supported",inA->rmap->bs); /* Need to replace MatCholeskyFactorSymbolic_SeqSBAIJ_MSR()! */ 1035c84f5b01SHong Zhang 103649b5e25fSSatish Balay outA = inA; 1037d5f3da31SBarry Smith inA->factortype = MAT_FACTOR_ICC; 1038f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 1039f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 104049b5e25fSSatish Balay 10411a3463dfSHong Zhang ierr = MatMarkDiagonal_SeqSBAIJ(inA);CHKERRQ(ierr); 1042d595f711SHong Zhang ierr = MatSeqSBAIJSetNumericFactorization_inplace(inA,row_identity);CHKERRQ(ierr); 104349b5e25fSSatish Balay 1044c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 10456bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 1046c84f5b01SHong Zhang a->row = row; 1047c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 10486bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 1049c84f5b01SHong Zhang a->col = row; 1050c84f5b01SHong Zhang 1051c84f5b01SHong Zhang /* Create the invert permutation so that it can be used in MatCholeskyFactorNumeric() */ 1052c84f5b01SHong Zhang if (a->icol) {ierr = ISInvertPermutation(row,PETSC_DECIDE, &a->icol);CHKERRQ(ierr);} 10533bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 105449b5e25fSSatish Balay 105549b5e25fSSatish Balay if (!a->solve_work) { 1056854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->N+inA->rmap->bs,&a->solve_work);CHKERRQ(ierr); 10573bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA,(inA->rmap->N+inA->rmap->bs)*sizeof(PetscScalar));CHKERRQ(ierr); 105849b5e25fSSatish Balay } 105949b5e25fSSatish Balay 1060719d5645SBarry Smith ierr = MatCholeskyFactorNumeric(outA,inA,info);CHKERRQ(ierr); 106149b5e25fSSatish Balay PetscFunctionReturn(0); 106249b5e25fSSatish Balay } 1063950f1e5bSHong Zhang 10647087cfbeSBarry Smith PetscErrorCode MatSeqSBAIJSetColumnIndices_SeqSBAIJ(Mat mat,PetscInt *indices) 106549b5e25fSSatish Balay { 1066045c9aa0SHong Zhang Mat_SeqSBAIJ *baij = (Mat_SeqSBAIJ*)mat->data; 106713f74950SBarry Smith PetscInt i,nz,n; 10687827cd58SJed Brown PetscErrorCode ierr; 106949b5e25fSSatish Balay 107049b5e25fSSatish Balay PetscFunctionBegin; 10716c6c5352SBarry Smith nz = baij->maxnz; 1072d0f46423SBarry Smith n = mat->cmap->n; 107326fbe8dcSKarl Rupp for (i=0; i<nz; i++) baij->j[i] = indices[i]; 107426fbe8dcSKarl Rupp 10756c6c5352SBarry Smith baij->nz = nz; 107626fbe8dcSKarl Rupp for (i=0; i<n; i++) baij->ilen[i] = baij->imax[i]; 107726fbe8dcSKarl Rupp 10787827cd58SJed Brown ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 107949b5e25fSSatish Balay PetscFunctionReturn(0); 108049b5e25fSSatish Balay } 108149b5e25fSSatish Balay 108249b5e25fSSatish Balay /*@ 108319585528SSatish Balay MatSeqSBAIJSetColumnIndices - Set the column indices for all the rows 108449b5e25fSSatish Balay in the matrix. 108549b5e25fSSatish Balay 108649b5e25fSSatish Balay Input Parameters: 108719585528SSatish Balay + mat - the SeqSBAIJ matrix 108849b5e25fSSatish Balay - indices - the column indices 108949b5e25fSSatish Balay 109049b5e25fSSatish Balay Level: advanced 109149b5e25fSSatish Balay 109249b5e25fSSatish Balay Notes: 109349b5e25fSSatish Balay This can be called if you have precomputed the nonzero structure of the 109449b5e25fSSatish Balay matrix and want to provide it to the matrix object to improve the performance 109549b5e25fSSatish Balay of the MatSetValues() operation. 109649b5e25fSSatish Balay 109749b5e25fSSatish Balay You MUST have set the correct numbers of nonzeros per row in the call to 1098d1be2dadSMatthew Knepley MatCreateSeqSBAIJ(), and the columns indices MUST be sorted. 109949b5e25fSSatish Balay 1100ab9f2c04SSatish Balay MUST be called before any calls to MatSetValues() 110149b5e25fSSatish Balay 1102ab9f2c04SSatish Balay .seealso: MatCreateSeqSBAIJ 110349b5e25fSSatish Balay @*/ 11047087cfbeSBarry Smith PetscErrorCode MatSeqSBAIJSetColumnIndices(Mat mat,PetscInt *indices) 110549b5e25fSSatish Balay { 11064ac538c5SBarry Smith PetscErrorCode ierr; 110749b5e25fSSatish Balay 110849b5e25fSSatish Balay PetscFunctionBegin; 11090700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11104482741eSBarry Smith PetscValidPointer(indices,2); 11114ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqSBAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 111249b5e25fSSatish Balay PetscFunctionReturn(0); 111349b5e25fSSatish Balay } 111449b5e25fSSatish Balay 11153c896bc6SHong Zhang PetscErrorCode MatCopy_SeqSBAIJ(Mat A,Mat B,MatStructure str) 11163c896bc6SHong Zhang { 11173c896bc6SHong Zhang PetscErrorCode ierr; 11184c7a3774SStefano Zampini PetscBool isbaij; 11193c896bc6SHong Zhang 11203c896bc6SHong Zhang PetscFunctionBegin; 11214c7a3774SStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)B,&isbaij,MATSEQSBAIJ,MATMPISBAIJ,"");CHKERRQ(ierr); 11224c7a3774SStefano Zampini if (!isbaij) SETERRQ1(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)B)->type_name); 11234c7a3774SStefano Zampini /* If the two matrices have the same copy implementation and nonzero pattern, use fast copy. */ 11244c7a3774SStefano Zampini if (str == SAME_NONZERO_PATTERN && A->ops->copy == B->ops->copy) { 11253c896bc6SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 11263c896bc6SHong Zhang Mat_SeqSBAIJ *b = (Mat_SeqSBAIJ*)B->data; 11273c896bc6SHong Zhang 11284c7a3774SStefano Zampini if (a->i[a->mbs] != b->i[b->mbs]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 11294c7a3774SStefano Zampini if (a->mbs != b->mbs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of rows in two matrices are different"); 11304c7a3774SStefano Zampini if (a->bs2 != b->bs2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Different block size"); 1131580bdb30SBarry Smith ierr = PetscArraycpy(b->a,a->a,a->bs2*a->i[a->mbs]);CHKERRQ(ierr); 1132cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 11333c896bc6SHong Zhang } else { 1134f5edf698SHong Zhang ierr = MatGetRowUpperTriangular(A);CHKERRQ(ierr); 11353c896bc6SHong Zhang ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1136f5edf698SHong Zhang ierr = MatRestoreRowUpperTriangular(A);CHKERRQ(ierr); 11373c896bc6SHong Zhang } 11383c896bc6SHong Zhang PetscFunctionReturn(0); 11393c896bc6SHong Zhang } 11403c896bc6SHong Zhang 11414994cf47SJed Brown PetscErrorCode MatSetUp_SeqSBAIJ(Mat A) 1142273d9f13SBarry Smith { 1143dfbe8321SBarry Smith PetscErrorCode ierr; 1144273d9f13SBarry Smith 1145273d9f13SBarry Smith PetscFunctionBegin; 1146367daffbSBarry Smith ierr = MatSeqSBAIJSetPreallocation(A,A->rmap->bs,PETSC_DEFAULT,0);CHKERRQ(ierr); 1147273d9f13SBarry Smith PetscFunctionReturn(0); 1148273d9f13SBarry Smith } 1149273d9f13SBarry Smith 1150cda14afcSprj- static PetscErrorCode MatSeqSBAIJGetArray_SeqSBAIJ(Mat A,PetscScalar *array[]) 1151a6ece127SHong Zhang { 1152a6ece127SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 11535fd66863SKarl Rupp 1154a6ece127SHong Zhang PetscFunctionBegin; 1155a6ece127SHong Zhang *array = a->a; 1156a6ece127SHong Zhang PetscFunctionReturn(0); 1157a6ece127SHong Zhang } 1158a6ece127SHong Zhang 1159cda14afcSprj- static PetscErrorCode MatSeqSBAIJRestoreArray_SeqSBAIJ(Mat A,PetscScalar *array[]) 1160a6ece127SHong Zhang { 1161a6ece127SHong Zhang PetscFunctionBegin; 1162cda14afcSprj- *array = NULL; 1163a6ece127SHong Zhang PetscFunctionReturn(0); 1164a6ece127SHong Zhang } 1165a6ece127SHong Zhang 116652768537SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqSBAIJ(Mat Y,Mat X,PetscInt *nnz) 116752768537SHong Zhang { 1168b264fe52SHong Zhang PetscInt bs = Y->rmap->bs,mbs = Y->rmap->N/bs; 116952768537SHong Zhang Mat_SeqSBAIJ *x = (Mat_SeqSBAIJ*)X->data; 117052768537SHong Zhang Mat_SeqSBAIJ *y = (Mat_SeqSBAIJ*)Y->data; 1171b264fe52SHong Zhang PetscErrorCode ierr; 117252768537SHong Zhang 117352768537SHong Zhang PetscFunctionBegin; 117452768537SHong Zhang /* Set the number of nonzeros in the new matrix */ 1175b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(mbs,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 117652768537SHong Zhang PetscFunctionReturn(0); 117752768537SHong Zhang } 117852768537SHong Zhang 1179f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqSBAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 118042ee4b1aSHong Zhang { 118142ee4b1aSHong Zhang Mat_SeqSBAIJ *x=(Mat_SeqSBAIJ*)X->data, *y=(Mat_SeqSBAIJ*)Y->data; 1182dfbe8321SBarry Smith PetscErrorCode ierr; 118331ce2d13SHong Zhang PetscInt bs=Y->rmap->bs,bs2=bs*bs; 1184e838b9e7SJed Brown PetscBLASInt one = 1; 118542ee4b1aSHong Zhang 118642ee4b1aSHong Zhang PetscFunctionBegin; 118742ee4b1aSHong Zhang if (str == SAME_NONZERO_PATTERN) { 1188f4df32b1SMatthew Knepley PetscScalar alpha = a; 1189c5df96a5SBarry Smith PetscBLASInt bnz; 1190c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz*bs2,&bnz);CHKERRQ(ierr); 11918b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 1192a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 1193ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 1194ab784542SHong Zhang ierr = MatSetOption(X,MAT_GETROW_UPPERTRIANGULAR,PETSC_TRUE);CHKERRQ(ierr); 1195ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 1196ab784542SHong Zhang ierr = MatSetOption(X,MAT_GETROW_UPPERTRIANGULAR,PETSC_FALSE);CHKERRQ(ierr); 119742ee4b1aSHong Zhang } else { 119852768537SHong Zhang Mat B; 119952768537SHong Zhang PetscInt *nnz; 120052768537SHong Zhang if (bs != X->rmap->bs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Matrices must have same block size"); 1201f5edf698SHong Zhang ierr = MatGetRowUpperTriangular(X);CHKERRQ(ierr); 120252768537SHong Zhang ierr = MatGetRowUpperTriangular(Y);CHKERRQ(ierr); 120352768537SHong Zhang ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 120452768537SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 120552768537SHong Zhang ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 120652768537SHong Zhang ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 120752768537SHong Zhang ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr); 12084c7a3774SStefano Zampini ierr = MatSetType(B,((PetscObject)Y)->type_name);CHKERRQ(ierr); 120952768537SHong Zhang ierr = MatAXPYGetPreallocation_SeqSBAIJ(Y,X,nnz);CHKERRQ(ierr); 121052768537SHong Zhang ierr = MatSeqSBAIJSetPreallocation(B,bs,0,nnz);CHKERRQ(ierr); 121152768537SHong Zhang 121252768537SHong Zhang ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 121352768537SHong Zhang 121428be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 121552768537SHong Zhang ierr = PetscFree(nnz);CHKERRQ(ierr); 1216f5edf698SHong Zhang ierr = MatRestoreRowUpperTriangular(X);CHKERRQ(ierr); 121752768537SHong Zhang ierr = MatRestoreRowUpperTriangular(Y);CHKERRQ(ierr); 121842ee4b1aSHong Zhang } 121942ee4b1aSHong Zhang PetscFunctionReturn(0); 122042ee4b1aSHong Zhang } 122142ee4b1aSHong Zhang 1222ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqSBAIJ(Mat A,PetscReal tol,PetscBool *flg) 1223efcf0fc3SBarry Smith { 1224efcf0fc3SBarry Smith PetscFunctionBegin; 1225efcf0fc3SBarry Smith *flg = PETSC_TRUE; 1226efcf0fc3SBarry Smith PetscFunctionReturn(0); 1227efcf0fc3SBarry Smith } 1228efcf0fc3SBarry Smith 1229ace3abfcSBarry Smith PetscErrorCode MatIsStructurallySymmetric_SeqSBAIJ(Mat A,PetscBool *flg) 1230efcf0fc3SBarry Smith { 1231efcf0fc3SBarry Smith PetscFunctionBegin; 1232efcf0fc3SBarry Smith *flg = PETSC_TRUE; 1233efcf0fc3SBarry Smith PetscFunctionReturn(0); 1234efcf0fc3SBarry Smith } 1235efcf0fc3SBarry Smith 1236ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqSBAIJ(Mat A,PetscReal tol,PetscBool *flg) 1237efcf0fc3SBarry Smith { 1238efcf0fc3SBarry Smith PetscFunctionBegin; 1239efcf0fc3SBarry Smith *flg = PETSC_FALSE; 1240efcf0fc3SBarry Smith PetscFunctionReturn(0); 1241efcf0fc3SBarry Smith } 1242efcf0fc3SBarry Smith 124399cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqSBAIJ(Mat A) 124499cafbc1SBarry Smith { 124599cafbc1SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 124699cafbc1SBarry Smith PetscInt i,nz = a->bs2*a->i[a->mbs]; 1247dd6ea824SBarry Smith MatScalar *aa = a->a; 124899cafbc1SBarry Smith 124999cafbc1SBarry Smith PetscFunctionBegin; 125099cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 125199cafbc1SBarry Smith PetscFunctionReturn(0); 125299cafbc1SBarry Smith } 125399cafbc1SBarry Smith 125499cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqSBAIJ(Mat A) 125599cafbc1SBarry Smith { 125699cafbc1SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 125799cafbc1SBarry Smith PetscInt i,nz = a->bs2*a->i[a->mbs]; 1258dd6ea824SBarry Smith MatScalar *aa = a->a; 125999cafbc1SBarry Smith 126099cafbc1SBarry Smith PetscFunctionBegin; 126199cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 126299cafbc1SBarry Smith PetscFunctionReturn(0); 126399cafbc1SBarry Smith } 126499cafbc1SBarry Smith 12653bededecSBarry Smith PetscErrorCode MatZeroRowsColumns_SeqSBAIJ(Mat A,PetscInt is_n,const PetscInt is_idx[],PetscScalar diag,Vec x, Vec b) 12663bededecSBarry Smith { 12673bededecSBarry Smith Mat_SeqSBAIJ *baij=(Mat_SeqSBAIJ*)A->data; 12683bededecSBarry Smith PetscErrorCode ierr; 12693bededecSBarry Smith PetscInt i,j,k,count; 12703bededecSBarry Smith PetscInt bs =A->rmap->bs,bs2=baij->bs2,row,col; 12713bededecSBarry Smith PetscScalar zero = 0.0; 12723bededecSBarry Smith MatScalar *aa; 12733bededecSBarry Smith const PetscScalar *xx; 12743bededecSBarry Smith PetscScalar *bb; 127556777dd2SBarry Smith PetscBool *zeroed,vecs = PETSC_FALSE; 12763bededecSBarry Smith 12773bededecSBarry Smith PetscFunctionBegin; 12783bededecSBarry Smith /* fix right hand side if needed */ 12793bededecSBarry Smith if (x && b) { 12803bededecSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 12813bededecSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 128256777dd2SBarry Smith vecs = PETSC_TRUE; 12833bededecSBarry Smith } 12843bededecSBarry Smith 12853bededecSBarry Smith /* zero the columns */ 12861795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 12873bededecSBarry Smith for (i=0; i<is_n; i++) { 12883bededecSBarry Smith if (is_idx[i] < 0 || is_idx[i] >= A->rmap->N) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range",is_idx[i]); 12893bededecSBarry Smith zeroed[is_idx[i]] = PETSC_TRUE; 12903bededecSBarry Smith } 129156777dd2SBarry Smith if (vecs) { 129256777dd2SBarry Smith for (i=0; i<A->rmap->N; i++) { 129356777dd2SBarry Smith row = i/bs; 129456777dd2SBarry Smith for (j=baij->i[row]; j<baij->i[row+1]; j++) { 129556777dd2SBarry Smith for (k=0; k<bs; k++) { 129656777dd2SBarry Smith col = bs*baij->j[j] + k; 129756777dd2SBarry Smith if (col <= i) continue; 129856777dd2SBarry Smith aa = ((MatScalar*)(baij->a)) + j*bs2 + (i%bs) + bs*k; 129926fbe8dcSKarl Rupp if (!zeroed[i] && zeroed[col]) bb[i] -= aa[0]*xx[col]; 130026fbe8dcSKarl Rupp if (zeroed[i] && !zeroed[col]) bb[col] -= aa[0]*xx[i]; 130156777dd2SBarry Smith } 130256777dd2SBarry Smith } 130356777dd2SBarry Smith } 130426fbe8dcSKarl Rupp for (i=0; i<is_n; i++) bb[is_idx[i]] = diag*xx[is_idx[i]]; 130556777dd2SBarry Smith } 130656777dd2SBarry Smith 13073bededecSBarry Smith for (i=0; i<A->rmap->N; i++) { 13083bededecSBarry Smith if (!zeroed[i]) { 13093bededecSBarry Smith row = i/bs; 13103bededecSBarry Smith for (j=baij->i[row]; j<baij->i[row+1]; j++) { 13113bededecSBarry Smith for (k=0; k<bs; k++) { 13123bededecSBarry Smith col = bs*baij->j[j] + k; 13133bededecSBarry Smith if (zeroed[col]) { 13143bededecSBarry Smith aa = ((MatScalar*)(baij->a)) + j*bs2 + (i%bs) + bs*k; 13153bededecSBarry Smith aa[0] = 0.0; 13163bededecSBarry Smith } 13173bededecSBarry Smith } 13183bededecSBarry Smith } 13193bededecSBarry Smith } 13203bededecSBarry Smith } 13213bededecSBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 132256777dd2SBarry Smith if (vecs) { 132356777dd2SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 132456777dd2SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 132556777dd2SBarry Smith } 13263bededecSBarry Smith 13273bededecSBarry Smith /* zero the rows */ 13283bededecSBarry Smith for (i=0; i<is_n; i++) { 13293bededecSBarry Smith row = is_idx[i]; 13303bededecSBarry Smith count = (baij->i[row/bs +1] - baij->i[row/bs])*bs; 13313bededecSBarry Smith aa = ((MatScalar*)(baij->a)) + baij->i[row/bs]*bs2 + (row%bs); 13323bededecSBarry Smith for (k=0; k<count; k++) { 13333bededecSBarry Smith aa[0] = zero; 13343bededecSBarry Smith aa += bs; 13353bededecSBarry Smith } 13363bededecSBarry Smith if (diag != 0.0) { 13373bededecSBarry Smith ierr = (*A->ops->setvalues)(A,1,&row,1,&row,&diag,INSERT_VALUES);CHKERRQ(ierr); 13383bededecSBarry Smith } 13393bededecSBarry Smith } 13403bededecSBarry Smith ierr = MatAssemblyEnd_SeqSBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13413bededecSBarry Smith PetscFunctionReturn(0); 13423bededecSBarry Smith } 13433bededecSBarry Smith 13447d68702bSBarry Smith PetscErrorCode MatShift_SeqSBAIJ(Mat Y,PetscScalar a) 13457d68702bSBarry Smith { 13467d68702bSBarry Smith PetscErrorCode ierr; 13477d68702bSBarry Smith Mat_SeqSBAIJ *aij = (Mat_SeqSBAIJ*)Y->data; 13487d68702bSBarry Smith 13497d68702bSBarry Smith PetscFunctionBegin; 13506f33a894SBarry Smith if (!Y->preallocated || !aij->nz) { 13517d68702bSBarry Smith ierr = MatSeqSBAIJSetPreallocation(Y,Y->rmap->bs,1,NULL);CHKERRQ(ierr); 13527d68702bSBarry Smith } 13537d68702bSBarry Smith ierr = MatShift_Basic(Y,a);CHKERRQ(ierr); 13547d68702bSBarry Smith PetscFunctionReturn(0); 13557d68702bSBarry Smith } 13567d68702bSBarry Smith 135749b5e25fSSatish Balay /* -------------------------------------------------------------------*/ 13583964eb88SJed Brown static struct _MatOps MatOps_Values = {MatSetValues_SeqSBAIJ, 135949b5e25fSSatish Balay MatGetRow_SeqSBAIJ, 136049b5e25fSSatish Balay MatRestoreRow_SeqSBAIJ, 136149b5e25fSSatish Balay MatMult_SeqSBAIJ_N, 136297304618SKris Buschelman /* 4*/ MatMultAdd_SeqSBAIJ_N, 1363431c96f7SBarry Smith MatMult_SeqSBAIJ_N, /* transpose versions are same as non-transpose versions */ 1364e005ede5SBarry Smith MatMultAdd_SeqSBAIJ_N, 1365db4efbfdSBarry Smith 0, 136649b5e25fSSatish Balay 0, 136749b5e25fSSatish Balay 0, 136897304618SKris Buschelman /* 10*/ 0, 136949b5e25fSSatish Balay 0, 1370c078aec8SLisandro Dalcin MatCholeskyFactor_SeqSBAIJ, 137141f059aeSBarry Smith MatSOR_SeqSBAIJ, 137249b5e25fSSatish Balay MatTranspose_SeqSBAIJ, 137397304618SKris Buschelman /* 15*/ MatGetInfo_SeqSBAIJ, 137449b5e25fSSatish Balay MatEqual_SeqSBAIJ, 137549b5e25fSSatish Balay MatGetDiagonal_SeqSBAIJ, 137649b5e25fSSatish Balay MatDiagonalScale_SeqSBAIJ, 137749b5e25fSSatish Balay MatNorm_SeqSBAIJ, 137897304618SKris Buschelman /* 20*/ 0, 137949b5e25fSSatish Balay MatAssemblyEnd_SeqSBAIJ, 138049b5e25fSSatish Balay MatSetOption_SeqSBAIJ, 138149b5e25fSSatish Balay MatZeroEntries_SeqSBAIJ, 1382d519adbfSMatthew Knepley /* 24*/ 0, 138349b5e25fSSatish Balay 0, 138449b5e25fSSatish Balay 0, 1385db4efbfdSBarry Smith 0, 1386db4efbfdSBarry Smith 0, 13874994cf47SJed Brown /* 29*/ MatSetUp_SeqSBAIJ, 1388c464158bSHong Zhang 0, 1389db4efbfdSBarry Smith 0, 13908c778c55SBarry Smith 0, 13918c778c55SBarry Smith 0, 1392d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqSBAIJ, 1393719d5645SBarry Smith 0, 1394719d5645SBarry Smith 0, 139549b5e25fSSatish Balay 0, 1396c84f5b01SHong Zhang MatICCFactor_SeqSBAIJ, 1397d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqSBAIJ, 13987dae84e0SHong Zhang MatCreateSubMatrices_SeqSBAIJ, 139949b5e25fSSatish Balay MatIncreaseOverlap_SeqSBAIJ, 140049b5e25fSSatish Balay MatGetValues_SeqSBAIJ, 14013c896bc6SHong Zhang MatCopy_SeqSBAIJ, 1402d519adbfSMatthew Knepley /* 44*/ 0, 140349b5e25fSSatish Balay MatScale_SeqSBAIJ, 14047d68702bSBarry Smith MatShift_SeqSBAIJ, 140549b5e25fSSatish Balay 0, 14063bededecSBarry Smith MatZeroRowsColumns_SeqSBAIJ, 1407f73d5cc4SBarry Smith /* 49*/ 0, 140849b5e25fSSatish Balay MatGetRowIJ_SeqSBAIJ, 140949b5e25fSSatish Balay MatRestoreRowIJ_SeqSBAIJ, 141049b5e25fSSatish Balay 0, 141149b5e25fSSatish Balay 0, 1412d519adbfSMatthew Knepley /* 54*/ 0, 141349b5e25fSSatish Balay 0, 141449b5e25fSSatish Balay 0, 141549b5e25fSSatish Balay 0, 141649b5e25fSSatish Balay MatSetValuesBlocked_SeqSBAIJ, 14177dae84e0SHong Zhang /* 59*/ MatCreateSubMatrix_SeqSBAIJ, 141849b5e25fSSatish Balay 0, 141949b5e25fSSatish Balay 0, 1420357abbc8SBarry Smith 0, 1421d959ec07SHong Zhang 0, 1422d519adbfSMatthew Knepley /* 64*/ 0, 1423d959ec07SHong Zhang 0, 1424d959ec07SHong Zhang 0, 1425d959ec07SHong Zhang 0, 1426d959ec07SHong Zhang 0, 1427d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqSBAIJ, 14283e0d88b5SBarry Smith 0, 142928d58a37SPierre Jolivet MatConvert_MPISBAIJ_Basic, 14303e0d88b5SBarry Smith 0, 14313e0d88b5SBarry Smith 0, 1432d519adbfSMatthew Knepley /* 74*/ 0, 14333e0d88b5SBarry Smith 0, 14343e0d88b5SBarry Smith 0, 14353e0d88b5SBarry Smith 0, 14363e0d88b5SBarry Smith 0, 1437d519adbfSMatthew Knepley /* 79*/ 0, 14383e0d88b5SBarry Smith 0, 14393e0d88b5SBarry Smith 0, 144097304618SKris Buschelman MatGetInertia_SeqSBAIJ, 14415bba2384SShri Abhyankar MatLoad_SeqSBAIJ, 1442d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqSBAIJ, 1443865e5f61SKris Buschelman MatIsHermitian_SeqSBAIJ, 1444efcf0fc3SBarry Smith MatIsStructurallySymmetric_SeqSBAIJ, 1445865e5f61SKris Buschelman 0, 1446865e5f61SKris Buschelman 0, 1447d519adbfSMatthew Knepley /* 89*/ 0, 1448865e5f61SKris Buschelman 0, 1449865e5f61SKris Buschelman 0, 1450865e5f61SKris Buschelman 0, 1451865e5f61SKris Buschelman 0, 1452d519adbfSMatthew Knepley /* 94*/ 0, 1453865e5f61SKris Buschelman 0, 1454865e5f61SKris Buschelman 0, 145599cafbc1SBarry Smith 0, 145699cafbc1SBarry Smith 0, 1457d519adbfSMatthew Knepley /* 99*/ 0, 145899cafbc1SBarry Smith 0, 145999cafbc1SBarry Smith 0, 146099cafbc1SBarry Smith 0, 146199cafbc1SBarry Smith 0, 1462d519adbfSMatthew Knepley /*104*/ 0, 146399cafbc1SBarry Smith MatRealPart_SeqSBAIJ, 1464f5edf698SHong Zhang MatImaginaryPart_SeqSBAIJ, 1465f5edf698SHong Zhang MatGetRowUpperTriangular_SeqSBAIJ, 14662af78befSBarry Smith MatRestoreRowUpperTriangular_SeqSBAIJ, 1467d519adbfSMatthew Knepley /*109*/ 0, 14682af78befSBarry Smith 0, 14692af78befSBarry Smith 0, 14702af78befSBarry Smith 0, 1471547795f9SHong Zhang MatMissingDiagonal_SeqSBAIJ, 1472547795f9SHong Zhang /*114*/ 0, 1473547795f9SHong Zhang 0, 1474547795f9SHong Zhang 0, 1475547795f9SHong Zhang 0, 1476547795f9SHong Zhang 0, 1477547795f9SHong Zhang /*119*/ 0, 1478547795f9SHong Zhang 0, 14792f480046SShri Abhyankar 0, 14803964eb88SJed Brown 0, 14813964eb88SJed Brown 0, 14823964eb88SJed Brown /*124*/ 0, 14833964eb88SJed Brown 0, 14843964eb88SJed Brown 0, 14853964eb88SJed Brown 0, 14863964eb88SJed Brown 0, 14873964eb88SJed Brown /*129*/ 0, 14883964eb88SJed Brown 0, 14893964eb88SJed Brown 0, 14903964eb88SJed Brown 0, 14913964eb88SJed Brown 0, 14923964eb88SJed Brown /*134*/ 0, 14933964eb88SJed Brown 0, 14943964eb88SJed Brown 0, 14953964eb88SJed Brown 0, 14963964eb88SJed Brown 0, 149746533700Sstefano_zampini /*139*/ MatSetBlockSizes_Default, 1498f9426fe0SMark Adams 0, 149959f5e6ceSHong Zhang 0, 150059f5e6ceSHong Zhang 0, 150159f5e6ceSHong Zhang 0, 150259f5e6ceSHong Zhang /*144*/MatCreateMPIMatConcatenateSeqMat_SeqSBAIJ 150399cafbc1SBarry Smith }; 1504be1d678aSKris Buschelman 15057087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqSBAIJ(Mat mat) 150649b5e25fSSatish Balay { 15074afc71dfSHong Zhang Mat_SeqSBAIJ *aij = (Mat_SeqSBAIJ*)mat->data; 1508d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->N]*mat->rmap->bs*aij->bs2; 1509dfbe8321SBarry Smith PetscErrorCode ierr; 151049b5e25fSSatish Balay 151149b5e25fSSatish Balay PetscFunctionBegin; 1512e7e72b3dSBarry Smith if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 151349b5e25fSSatish Balay 151449b5e25fSSatish Balay /* allocate space for values if not already there */ 151549b5e25fSSatish Balay if (!aij->saved_values) { 1516854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 151749b5e25fSSatish Balay } 151849b5e25fSSatish Balay 151949b5e25fSSatish Balay /* copy values over */ 1520580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 152149b5e25fSSatish Balay PetscFunctionReturn(0); 152249b5e25fSSatish Balay } 152349b5e25fSSatish Balay 15247087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqSBAIJ(Mat mat) 152549b5e25fSSatish Balay { 15264afc71dfSHong Zhang Mat_SeqSBAIJ *aij = (Mat_SeqSBAIJ*)mat->data; 15276849ba73SBarry Smith PetscErrorCode ierr; 1528d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->N]*mat->rmap->bs*aij->bs2; 152949b5e25fSSatish Balay 153049b5e25fSSatish Balay PetscFunctionBegin; 1531e7e72b3dSBarry Smith if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 1532e7e72b3dSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 153349b5e25fSSatish Balay 153449b5e25fSSatish Balay /* copy values over */ 1535580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 153649b5e25fSSatish Balay PetscFunctionReturn(0); 153749b5e25fSSatish Balay } 153849b5e25fSSatish Balay 1539367daffbSBarry Smith static PetscErrorCode MatSeqSBAIJSetPreallocation_SeqSBAIJ(Mat B,PetscInt bs,PetscInt nz,PetscInt *nnz) 154049b5e25fSSatish Balay { 1541c464158bSHong Zhang Mat_SeqSBAIJ *b = (Mat_SeqSBAIJ*)B->data; 15426849ba73SBarry Smith PetscErrorCode ierr; 15434dcd73b1SHong Zhang PetscInt i,mbs,nbs,bs2; 15442576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,flg = PETSC_FALSE,realalloc = PETSC_FALSE; 154549b5e25fSSatish Balay 154649b5e25fSSatish Balay PetscFunctionBegin; 15472576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 1548db4efbfdSBarry Smith 154933d57670SJed Brown ierr = MatSetBlockSize(B,PetscAbs(bs));CHKERRQ(ierr); 155026283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 155126283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 1552476417e5SBarry Smith if (B->rmap->N > B->cmap->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"SEQSBAIJ matrix cannot have more rows %D than columns %D",B->rmap->N,B->cmap->N); 1553e02043d6SBarry Smith ierr = PetscLayoutGetBlockSize(B->rmap,&bs);CHKERRQ(ierr); 1554899cda47SBarry Smith 155521940c7eSstefano_zampini B->preallocated = PETSC_TRUE; 155621940c7eSstefano_zampini 1557d0f46423SBarry Smith mbs = B->rmap->N/bs; 15584dcd73b1SHong Zhang nbs = B->cmap->n/bs; 155949b5e25fSSatish Balay bs2 = bs*bs; 156049b5e25fSSatish Balay 15614dcd73b1SHong Zhang if (mbs*bs != B->rmap->N || nbs*bs!=B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number rows, cols must be divisible by blocksize"); 156249b5e25fSSatish Balay 1563ab93d7beSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 1564ab93d7beSBarry Smith skipallocation = PETSC_TRUE; 1565ab93d7beSBarry Smith nz = 0; 1566ab93d7beSBarry Smith } 1567ab93d7beSBarry Smith 1568435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 3; 1569e32f2f54SBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 157049b5e25fSSatish Balay if (nnz) { 157149b5e25fSSatish Balay for (i=0; i<mbs; i++) { 1572e32f2f54SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %D value %D",i,nnz[i]); 1573de64b629SHong Zhang if (nnz[i] > nbs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than block row length: local row %D value %D block rowlength %D",i,nnz[i],nbs); 157449b5e25fSSatish Balay } 157549b5e25fSSatish Balay } 157649b5e25fSSatish Balay 1577db4efbfdSBarry Smith B->ops->mult = MatMult_SeqSBAIJ_N; 1578db4efbfdSBarry Smith B->ops->multadd = MatMultAdd_SeqSBAIJ_N; 1579db4efbfdSBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_N; 1580db4efbfdSBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_N; 158126fbe8dcSKarl Rupp 1582c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)B)->options,((PetscObject)B)->prefix,"-mat_no_unroll",&flg,NULL);CHKERRQ(ierr); 158349b5e25fSSatish Balay if (!flg) { 158449b5e25fSSatish Balay switch (bs) { 158549b5e25fSSatish Balay case 1: 158649b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_1; 158749b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_1; 1588431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_1; 1589431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_1; 159049b5e25fSSatish Balay break; 159149b5e25fSSatish Balay case 2: 159249b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_2; 159349b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_2; 1594431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_2; 1595431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_2; 159649b5e25fSSatish Balay break; 159749b5e25fSSatish Balay case 3: 159849b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_3; 159949b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_3; 1600431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_3; 1601431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_3; 160249b5e25fSSatish Balay break; 160349b5e25fSSatish Balay case 4: 160449b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_4; 160549b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_4; 1606431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_4; 1607431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_4; 160849b5e25fSSatish Balay break; 160949b5e25fSSatish Balay case 5: 161049b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_5; 161149b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_5; 1612431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_5; 1613431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_5; 161449b5e25fSSatish Balay break; 161549b5e25fSSatish Balay case 6: 161649b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_6; 161749b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_6; 1618431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_6; 1619431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_6; 162049b5e25fSSatish Balay break; 162149b5e25fSSatish Balay case 7: 1622de53e5efSHong Zhang B->ops->mult = MatMult_SeqSBAIJ_7; 162349b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_7; 1624431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_7; 1625431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_7; 162649b5e25fSSatish Balay break; 162749b5e25fSSatish Balay } 162849b5e25fSSatish Balay } 162949b5e25fSSatish Balay 163049b5e25fSSatish Balay b->mbs = mbs; 16314dcd73b1SHong Zhang b->nbs = nbs; 1632ab93d7beSBarry Smith if (!skipallocation) { 16332ee49352SLisandro Dalcin if (!b->imax) { 1634dcca6d9dSJed Brown ierr = PetscMalloc2(mbs,&b->imax,mbs,&b->ilen);CHKERRQ(ierr); 163526fbe8dcSKarl Rupp 1636c760cd28SBarry Smith b->free_imax_ilen = PETSC_TRUE; 163726fbe8dcSKarl Rupp 16383bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*mbs*sizeof(PetscInt));CHKERRQ(ierr); 16392ee49352SLisandro Dalcin } 164049b5e25fSSatish Balay if (!nnz) { 1641435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 164249b5e25fSSatish Balay else if (nz <= 0) nz = 1; 16435d2a9ed1SStefano Zampini nz = PetscMin(nbs,nz); 164426fbe8dcSKarl Rupp for (i=0; i<mbs; i++) b->imax[i] = nz; 1645153ea458SHong Zhang nz = nz*mbs; /* total nz */ 164649b5e25fSSatish Balay } else { 1647c73702f5SBarry Smith PetscInt64 nz64 = 0; 1648c73702f5SBarry Smith for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 1649c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 165049b5e25fSSatish Balay } 16512ee49352SLisandro Dalcin /* b->ilen will count nonzeros in each block row so far. */ 165226fbe8dcSKarl Rupp for (i=0; i<mbs; i++) b->ilen[i] = 0; 16536c6c5352SBarry Smith /* nz=(nz+mbs)/2; */ /* total diagonal and superdiagonal nonzero blocks */ 165449b5e25fSSatish Balay 165549b5e25fSSatish Balay /* allocate the matrix space */ 16562ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 1657dcca6d9dSJed Brown ierr = PetscMalloc3(bs2*nz,&b->a,nz,&b->j,B->rmap->N+1,&b->i);CHKERRQ(ierr); 16583bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->N+1)*sizeof(PetscInt)+nz*(bs2*sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 1659580bdb30SBarry Smith ierr = PetscArrayzero(b->a,nz*bs2);CHKERRQ(ierr); 1660580bdb30SBarry Smith ierr = PetscArrayzero(b->j,nz);CHKERRQ(ierr); 166126fbe8dcSKarl Rupp 166249b5e25fSSatish Balay b->singlemalloc = PETSC_TRUE; 166349b5e25fSSatish Balay 166449b5e25fSSatish Balay /* pointer to beginning of each row */ 1665e60cf9a0SBarry Smith b->i[0] = 0; 166626fbe8dcSKarl Rupp for (i=1; i<mbs+1; i++) b->i[i] = b->i[i-1] + b->imax[i-1]; 166726fbe8dcSKarl Rupp 1668e6b907acSBarry Smith b->free_a = PETSC_TRUE; 1669e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 1670e811da20SHong Zhang } else { 1671e6b907acSBarry Smith b->free_a = PETSC_FALSE; 1672e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 1673ab93d7beSBarry Smith } 167449b5e25fSSatish Balay 167549b5e25fSSatish Balay b->bs2 = bs2; 16766c6c5352SBarry Smith b->nz = 0; 1677b32cb4a7SJed Brown b->maxnz = nz; 167816cdd363SHong Zhang b->inew = 0; 167916cdd363SHong Zhang b->jnew = 0; 168016cdd363SHong Zhang b->anew = 0; 168116cdd363SHong Zhang b->a2anew = 0; 16821a3463dfSHong Zhang b->permute = PETSC_FALSE; 1683cb7b82ddSBarry Smith 1684cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 1685cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 16862576faa2SJed Brown if (realalloc) {ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);} 1687c464158bSHong Zhang PetscFunctionReturn(0); 1688c464158bSHong Zhang } 1689153ea458SHong Zhang 169038f409ebSLisandro Dalcin PetscErrorCode MatSeqSBAIJSetPreallocationCSR_SeqSBAIJ(Mat B,PetscInt bs,const PetscInt ii[],const PetscInt jj[], const PetscScalar V[]) 169138f409ebSLisandro Dalcin { 16920cd7f59aSBarry Smith PetscInt i,j,m,nz,anz, nz_max=0,*nnz; 169338f409ebSLisandro Dalcin PetscScalar *values=0; 169438f409ebSLisandro Dalcin PetscBool roworiented = ((Mat_SeqSBAIJ*)B->data)->roworiented; 169538f409ebSLisandro Dalcin PetscErrorCode ierr; 16960cd7f59aSBarry Smith 169738f409ebSLisandro Dalcin PetscFunctionBegin; 169838f409ebSLisandro Dalcin if (bs < 1) SETERRQ1(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_OUTOFRANGE,"Invalid block size specified, must be positive but it is %D",bs); 169938f409ebSLisandro Dalcin ierr = PetscLayoutSetBlockSize(B->rmap,bs);CHKERRQ(ierr); 170038f409ebSLisandro Dalcin ierr = PetscLayoutSetBlockSize(B->cmap,bs);CHKERRQ(ierr); 170138f409ebSLisandro Dalcin ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 170238f409ebSLisandro Dalcin ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 170338f409ebSLisandro Dalcin ierr = PetscLayoutGetBlockSize(B->rmap,&bs);CHKERRQ(ierr); 170438f409ebSLisandro Dalcin m = B->rmap->n/bs; 170538f409ebSLisandro Dalcin 170638f409ebSLisandro Dalcin if (ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"ii[0] must be 0 but it is %D",ii[0]); 1707854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nnz);CHKERRQ(ierr); 170838f409ebSLisandro Dalcin for (i=0; i<m; i++) { 170938f409ebSLisandro Dalcin nz = ii[i+1] - ii[i]; 171038f409ebSLisandro Dalcin if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D has a negative number of columns %D",i,nz); 17110cd7f59aSBarry Smith anz = 0; 17120cd7f59aSBarry Smith for (j=0; j<nz; j++) { 17130cd7f59aSBarry Smith /* count only values on the diagonal or above */ 17140cd7f59aSBarry Smith if (jj[ii[i] + j] >= i) { 17150cd7f59aSBarry Smith anz = nz - j; 17160cd7f59aSBarry Smith break; 17170cd7f59aSBarry Smith } 17180cd7f59aSBarry Smith } 17190cd7f59aSBarry Smith nz_max = PetscMax(nz_max,anz); 17200cd7f59aSBarry Smith nnz[i] = anz; 172138f409ebSLisandro Dalcin } 172238f409ebSLisandro Dalcin ierr = MatSeqSBAIJSetPreallocation(B,bs,0,nnz);CHKERRQ(ierr); 172338f409ebSLisandro Dalcin ierr = PetscFree(nnz);CHKERRQ(ierr); 172438f409ebSLisandro Dalcin 172538f409ebSLisandro Dalcin values = (PetscScalar*)V; 172638f409ebSLisandro Dalcin if (!values) { 17271795a4d1SJed Brown ierr = PetscCalloc1(bs*bs*nz_max,&values);CHKERRQ(ierr); 172838f409ebSLisandro Dalcin } 172938f409ebSLisandro Dalcin for (i=0; i<m; i++) { 173038f409ebSLisandro Dalcin PetscInt ncols = ii[i+1] - ii[i]; 173138f409ebSLisandro Dalcin const PetscInt *icols = jj + ii[i]; 173238f409ebSLisandro Dalcin if (!roworiented || bs == 1) { 173338f409ebSLisandro Dalcin const PetscScalar *svals = values + (V ? (bs*bs*ii[i]) : 0); 173438f409ebSLisandro Dalcin ierr = MatSetValuesBlocked_SeqSBAIJ(B,1,&i,ncols,icols,svals,INSERT_VALUES);CHKERRQ(ierr); 173538f409ebSLisandro Dalcin } else { 173638f409ebSLisandro Dalcin for (j=0; j<ncols; j++) { 173738f409ebSLisandro Dalcin const PetscScalar *svals = values + (V ? (bs*bs*(ii[i]+j)) : 0); 173838f409ebSLisandro Dalcin ierr = MatSetValuesBlocked_SeqSBAIJ(B,1,&i,1,&icols[j],svals,INSERT_VALUES);CHKERRQ(ierr); 173938f409ebSLisandro Dalcin } 174038f409ebSLisandro Dalcin } 174138f409ebSLisandro Dalcin } 174238f409ebSLisandro Dalcin if (!V) { ierr = PetscFree(values);CHKERRQ(ierr); } 174338f409ebSLisandro Dalcin ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 174438f409ebSLisandro Dalcin ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 174538f409ebSLisandro Dalcin ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 174638f409ebSLisandro Dalcin PetscFunctionReturn(0); 174738f409ebSLisandro Dalcin } 174838f409ebSLisandro Dalcin 1749db4efbfdSBarry Smith /* 1750db4efbfdSBarry Smith This is used to set the numeric factorization for both Cholesky and ICC symbolic factorization 1751db4efbfdSBarry Smith */ 1752ace3abfcSBarry Smith PetscErrorCode MatSeqSBAIJSetNumericFactorization_inplace(Mat B,PetscBool natural) 1753db4efbfdSBarry Smith { 1754db4efbfdSBarry Smith PetscErrorCode ierr; 1755ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 1756db4efbfdSBarry Smith PetscInt bs = B->rmap->bs; 1757db4efbfdSBarry Smith 1758db4efbfdSBarry Smith PetscFunctionBegin; 1759c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)B)->options,((PetscObject)B)->prefix,"-mat_no_unroll",&flg,NULL);CHKERRQ(ierr); 1760db4efbfdSBarry Smith if (flg) bs = 8; 1761db4efbfdSBarry Smith 1762db4efbfdSBarry Smith if (!natural) { 1763db4efbfdSBarry Smith switch (bs) { 1764db4efbfdSBarry Smith case 1: 1765d595f711SHong Zhang B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_1_inplace; 1766db4efbfdSBarry Smith break; 1767db4efbfdSBarry Smith case 2: 1768db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_2; 1769db4efbfdSBarry Smith break; 1770db4efbfdSBarry Smith case 3: 1771db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_3; 1772db4efbfdSBarry Smith break; 1773db4efbfdSBarry Smith case 4: 1774db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_4; 1775db4efbfdSBarry Smith break; 1776db4efbfdSBarry Smith case 5: 1777db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_5; 1778db4efbfdSBarry Smith break; 1779db4efbfdSBarry Smith case 6: 1780db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_6; 1781db4efbfdSBarry Smith break; 1782db4efbfdSBarry Smith case 7: 1783db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_7; 1784db4efbfdSBarry Smith break; 1785db4efbfdSBarry Smith default: 1786db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_N; 1787db4efbfdSBarry Smith break; 1788db4efbfdSBarry Smith } 1789db4efbfdSBarry Smith } else { 1790db4efbfdSBarry Smith switch (bs) { 1791db4efbfdSBarry Smith case 1: 1792d595f711SHong Zhang B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_1_NaturalOrdering_inplace; 1793db4efbfdSBarry Smith break; 1794db4efbfdSBarry Smith case 2: 1795db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_2_NaturalOrdering; 1796db4efbfdSBarry Smith break; 1797db4efbfdSBarry Smith case 3: 1798db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_3_NaturalOrdering; 1799db4efbfdSBarry Smith break; 1800db4efbfdSBarry Smith case 4: 1801db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_4_NaturalOrdering; 1802db4efbfdSBarry Smith break; 1803db4efbfdSBarry Smith case 5: 1804db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_5_NaturalOrdering; 1805db4efbfdSBarry Smith break; 1806db4efbfdSBarry Smith case 6: 1807db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_6_NaturalOrdering; 1808db4efbfdSBarry Smith break; 1809db4efbfdSBarry Smith case 7: 1810db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_7_NaturalOrdering; 1811db4efbfdSBarry Smith break; 1812db4efbfdSBarry Smith default: 1813db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_N_NaturalOrdering; 1814db4efbfdSBarry Smith break; 1815db4efbfdSBarry Smith } 1816db4efbfdSBarry Smith } 1817db4efbfdSBarry Smith PetscFunctionReturn(0); 1818db4efbfdSBarry Smith } 1819db4efbfdSBarry Smith 1820cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqSBAIJ_SeqAIJ(Mat, MatType,MatReuse,Mat*); 1821cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqSBAIJ_SeqBAIJ(Mat, MatType,MatReuse,Mat*); 1822d769727bSBarry Smith 1823cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqsbaij_petsc(Mat A,MatFactorType ftype,Mat *B) 18245c9eb25fSBarry Smith { 1825d0f46423SBarry Smith PetscInt n = A->rmap->n; 18265c9eb25fSBarry Smith PetscErrorCode ierr; 18275c9eb25fSBarry Smith 18285c9eb25fSBarry Smith PetscFunctionBegin; 18290e92d65fSHong Zhang #if defined(PETSC_USE_COMPLEX) 1830*eb1ec7c1SStefano Zampini if (A->hermitian && !A->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported"); 18310e92d65fSHong Zhang #endif 1832*eb1ec7c1SStefano Zampini 1833ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 18345c9eb25fSBarry Smith ierr = MatSetSizes(*B,n,n,n,n);CHKERRQ(ierr); 18355c9eb25fSBarry Smith if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 18365c9eb25fSBarry Smith ierr = MatSetType(*B,MATSEQSBAIJ);CHKERRQ(ierr); 18370298fd71SBarry Smith ierr = MatSeqSBAIJSetPreallocation(*B,A->rmap->bs,MAT_SKIP_ALLOCATION,NULL);CHKERRQ(ierr); 183826fbe8dcSKarl Rupp 18397b056e98SHong Zhang (*B)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqSBAIJ; 1840c6d0d4f0SHong Zhang (*B)->ops->iccfactorsymbolic = MatICCFactorSymbolic_SeqSBAIJ; 1841e32f2f54SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Factor type not supported"); 184200c67f3bSHong Zhang 1843d5f3da31SBarry Smith (*B)->factortype = ftype; 184400c67f3bSHong Zhang ierr = PetscFree((*B)->solvertype);CHKERRQ(ierr); 184500c67f3bSHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&(*B)->solvertype);CHKERRQ(ierr); 18465c9eb25fSBarry Smith PetscFunctionReturn(0); 18475c9eb25fSBarry Smith } 18485c9eb25fSBarry Smith 18498397e458SBarry Smith /*@C 18508397e458SBarry Smith MatSeqSBAIJGetArray - gives access to the array where the data for a MATSEQSBAIJ matrix is stored 18518397e458SBarry Smith 18528397e458SBarry Smith Not Collective 18538397e458SBarry Smith 18548397e458SBarry Smith Input Parameter: 18558397e458SBarry Smith . mat - a MATSEQSBAIJ matrix 18568397e458SBarry Smith 18578397e458SBarry Smith Output Parameter: 18588397e458SBarry Smith . array - pointer to the data 18598397e458SBarry Smith 18608397e458SBarry Smith Level: intermediate 18618397e458SBarry Smith 18628397e458SBarry Smith .seealso: MatSeqSBAIJRestoreArray(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray() 18638397e458SBarry Smith @*/ 18648397e458SBarry Smith PetscErrorCode MatSeqSBAIJGetArray(Mat A,PetscScalar **array) 18658397e458SBarry Smith { 18668397e458SBarry Smith PetscErrorCode ierr; 18678397e458SBarry Smith 18688397e458SBarry Smith PetscFunctionBegin; 18698397e458SBarry Smith ierr = PetscUseMethod(A,"MatSeqSBAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 18708397e458SBarry Smith PetscFunctionReturn(0); 18718397e458SBarry Smith } 18728397e458SBarry Smith 18738397e458SBarry Smith /*@C 18748397e458SBarry Smith MatSeqSBAIJRestoreArray - returns access to the array where the data for a MATSEQSBAIJ matrix is stored obtained by MatSeqSBAIJGetArray() 18758397e458SBarry Smith 18768397e458SBarry Smith Not Collective 18778397e458SBarry Smith 18788397e458SBarry Smith Input Parameters: 1879a2b725a8SWilliam Gropp + mat - a MATSEQSBAIJ matrix 1880a2b725a8SWilliam Gropp - array - pointer to the data 18818397e458SBarry Smith 18828397e458SBarry Smith Level: intermediate 18838397e458SBarry Smith 18848397e458SBarry Smith .seealso: MatSeqSBAIJGetArray(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray() 18858397e458SBarry Smith @*/ 18868397e458SBarry Smith PetscErrorCode MatSeqSBAIJRestoreArray(Mat A,PetscScalar **array) 18878397e458SBarry Smith { 18888397e458SBarry Smith PetscErrorCode ierr; 18898397e458SBarry Smith 18908397e458SBarry Smith PetscFunctionBegin; 18918397e458SBarry Smith ierr = PetscUseMethod(A,"MatSeqSBAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 18928397e458SBarry Smith PetscFunctionReturn(0); 18938397e458SBarry Smith } 18948397e458SBarry Smith 18950bad9183SKris Buschelman /*MC 1896fafad747SKris Buschelman MATSEQSBAIJ - MATSEQSBAIJ = "seqsbaij" - A matrix type to be used for sequential symmetric block sparse matrices, 18970bad9183SKris Buschelman based on block compressed sparse row format. Only the upper triangular portion of the matrix is stored. 18980bad9183SKris Buschelman 1899828413b8SBarry Smith For complex numbers by default this matrix is symmetric, NOT Hermitian symmetric. To make it Hermitian symmetric you 1900*eb1ec7c1SStefano Zampini can call MatSetOption(Mat, MAT_HERMITIAN). 1901828413b8SBarry Smith 19020bad9183SKris Buschelman Options Database Keys: 19030bad9183SKris Buschelman . -mat_type seqsbaij - sets the matrix type to "seqsbaij" during a call to MatSetFromOptions() 19040bad9183SKris Buschelman 190595452b02SPatrick Sanan Notes: 190695452b02SPatrick Sanan By default if you insert values into the lower triangular part of the matrix they are simply ignored (since they are not 190771dad5bbSBarry Smith stored and it is assumed they symmetric to the upper triangular). If you call MatSetOption(Mat,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_FALSE) or use 190871dad5bbSBarry Smith the options database -mat_ignore_lower_triangular false it will generate an error if you try to set a value in the lower triangular portion. 190971dad5bbSBarry Smith 1910476417e5SBarry Smith The number of rows in the matrix must be less than or equal to the number of columns 191171dad5bbSBarry Smith 19120bad9183SKris Buschelman Level: beginner 19130bad9183SKris Buschelman 1914476417e5SBarry Smith .seealso: MatCreateSeqSBAIJ(), MatType, MATMPISBAIJ 19150bad9183SKris Buschelman M*/ 19168cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqSBAIJ(Mat B) 1917a23d5eceSKris Buschelman { 1918a23d5eceSKris Buschelman Mat_SeqSBAIJ *b; 1919dfbe8321SBarry Smith PetscErrorCode ierr; 192013f74950SBarry Smith PetscMPIInt size; 1921ace3abfcSBarry Smith PetscBool no_unroll = PETSC_FALSE,no_inode = PETSC_FALSE; 1922a23d5eceSKris Buschelman 1923a23d5eceSKris Buschelman PetscFunctionBegin; 1924ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 1925e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1926a23d5eceSKris Buschelman 1927b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 1928a23d5eceSKris Buschelman B->data = (void*)b; 1929a23d5eceSKris Buschelman ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 193026fbe8dcSKarl Rupp 1931a23d5eceSKris Buschelman B->ops->destroy = MatDestroy_SeqSBAIJ; 1932a23d5eceSKris Buschelman B->ops->view = MatView_SeqSBAIJ; 1933a23d5eceSKris Buschelman b->row = 0; 1934a23d5eceSKris Buschelman b->icol = 0; 1935a23d5eceSKris Buschelman b->reallocs = 0; 1936a23d5eceSKris Buschelman b->saved_values = 0; 19370def2e27SBarry Smith b->inode.limit = 5; 19380def2e27SBarry Smith b->inode.max_limit = 5; 1939a23d5eceSKris Buschelman 1940a23d5eceSKris Buschelman b->roworiented = PETSC_TRUE; 1941a23d5eceSKris Buschelman b->nonew = 0; 1942a23d5eceSKris Buschelman b->diag = 0; 1943a23d5eceSKris Buschelman b->solve_work = 0; 1944a23d5eceSKris Buschelman b->mult_work = 0; 1945a23d5eceSKris Buschelman B->spptr = 0; 1946f2cbd3d5SJed Brown B->info.nz_unneeded = (PetscReal)b->maxnz*b->bs2; 1947a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 1948a23d5eceSKris Buschelman 1949a23d5eceSKris Buschelman b->inew = 0; 1950a23d5eceSKris Buschelman b->jnew = 0; 1951a23d5eceSKris Buschelman b->anew = 0; 1952a23d5eceSKris Buschelman b->a2anew = 0; 1953a23d5eceSKris Buschelman b->permute = PETSC_FALSE; 1954a23d5eceSKris Buschelman 195571dad5bbSBarry Smith b->ignore_ltriangular = PETSC_TRUE; 195626fbe8dcSKarl Rupp 1957c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)B)->options,((PetscObject)B)->prefix,"-mat_ignore_lower_triangular",&b->ignore_ltriangular,NULL);CHKERRQ(ierr); 1958941593c8SHong Zhang 1959f5edf698SHong Zhang b->getrow_utriangular = PETSC_FALSE; 196026fbe8dcSKarl Rupp 1961c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)B)->options,((PetscObject)B)->prefix,"-mat_getrow_uppertriangular",&b->getrow_utriangular,NULL);CHKERRQ(ierr); 1962f5edf698SHong Zhang 19638397e458SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqSBAIJGetArray_C",MatSeqSBAIJGetArray_SeqSBAIJ);CHKERRQ(ierr); 19648397e458SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqSBAIJRestoreArray_C",MatSeqSBAIJRestoreArray_SeqSBAIJ);CHKERRQ(ierr); 1965bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqSBAIJ);CHKERRQ(ierr); 1966bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqSBAIJ);CHKERRQ(ierr); 1967bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqSBAIJSetColumnIndices_C",MatSeqSBAIJSetColumnIndices_SeqSBAIJ);CHKERRQ(ierr); 1968bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqsbaij_seqaij_C",MatConvert_SeqSBAIJ_SeqAIJ);CHKERRQ(ierr); 1969bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqsbaij_seqbaij_C",MatConvert_SeqSBAIJ_SeqBAIJ);CHKERRQ(ierr); 1970bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqSBAIJSetPreallocation_C",MatSeqSBAIJSetPreallocation_SeqSBAIJ);CHKERRQ(ierr); 197138f409ebSLisandro Dalcin ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqSBAIJSetPreallocationCSR_C",MatSeqSBAIJSetPreallocationCSR_SeqSBAIJ);CHKERRQ(ierr); 19726214f412SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 19736214f412SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqsbaij_elemental_C",MatConvert_SeqSBAIJ_Elemental);CHKERRQ(ierr); 19746214f412SHong Zhang #endif 197523ce1328SBarry Smith 197623ce1328SBarry Smith B->symmetric = PETSC_TRUE; 197723ce1328SBarry Smith B->structurally_symmetric = PETSC_TRUE; 197823ce1328SBarry Smith B->symmetric_set = PETSC_TRUE; 197923ce1328SBarry Smith B->structurally_symmetric_set = PETSC_TRUE; 19809899f194SHong Zhang B->symmetric_eternal = PETSC_TRUE; 1981*eb1ec7c1SStefano Zampini #if defined(PETSC_USE_COMPLEX) 198213647f61SHong Zhang B->hermitian = PETSC_FALSE; 198313647f61SHong Zhang B->hermitian_set = PETSC_FALSE; 1984*eb1ec7c1SStefano Zampini #else 1985*eb1ec7c1SStefano Zampini B->hermitian = PETSC_TRUE; 1986*eb1ec7c1SStefano Zampini B->hermitian_set = PETSC_TRUE; 1987*eb1ec7c1SStefano Zampini #endif 198813647f61SHong Zhang 198917667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQSBAIJ);CHKERRQ(ierr); 19900def2e27SBarry Smith 1991ce94432eSBarry Smith ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)B),((PetscObject)B)->prefix,"Options for SEQSBAIJ matrix","Mat");CHKERRQ(ierr); 19920298fd71SBarry Smith ierr = PetscOptionsBool("-mat_no_unroll","Do not optimize for inodes (slower)",NULL,no_unroll,&no_unroll,NULL);CHKERRQ(ierr); 199326fbe8dcSKarl Rupp if (no_unroll) { 199426fbe8dcSKarl Rupp ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_unroll\n");CHKERRQ(ierr); 199526fbe8dcSKarl Rupp } 19960298fd71SBarry Smith ierr = PetscOptionsBool("-mat_no_inode","Do not optimize for inodes (slower)",NULL,no_inode,&no_inode,NULL);CHKERRQ(ierr); 199726fbe8dcSKarl Rupp if (no_inode) { 199826fbe8dcSKarl Rupp ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_inode\n");CHKERRQ(ierr); 199926fbe8dcSKarl Rupp } 20000298fd71SBarry Smith ierr = PetscOptionsInt("-mat_inode_limit","Do not use inodes larger then this value",NULL,b->inode.limit,&b->inode.limit,NULL);CHKERRQ(ierr); 20010def2e27SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 2002ace3abfcSBarry Smith b->inode.use = (PetscBool)(!(no_unroll || no_inode)); 20030def2e27SBarry Smith if (b->inode.limit > b->inode.max_limit) b->inode.limit = b->inode.max_limit; 2004a23d5eceSKris Buschelman PetscFunctionReturn(0); 2005a23d5eceSKris Buschelman } 2006a23d5eceSKris Buschelman 2007a23d5eceSKris Buschelman /*@C 2008a23d5eceSKris Buschelman MatSeqSBAIJSetPreallocation - Creates a sparse symmetric matrix in block AIJ (block 2009a23d5eceSKris Buschelman compressed row) format. For good matrix assembly performance the 2010a23d5eceSKris Buschelman user should preallocate the matrix storage by setting the parameter nz 2011a23d5eceSKris Buschelman (or the array nnz). By setting these parameters accurately, performance 2012a23d5eceSKris Buschelman during matrix assembly can be increased by more than a factor of 50. 2013a23d5eceSKris Buschelman 2014a23d5eceSKris Buschelman Collective on Mat 2015a23d5eceSKris Buschelman 2016a23d5eceSKris Buschelman Input Parameters: 20171c4f3114SJed Brown + B - the symmetric matrix 2018bb7ae925SBarry Smith . bs - size of block, the blocks are ALWAYS square. One can use MatSetBlockSizes() to set a different row and column blocksize but the row 2019bb7ae925SBarry Smith blocksize always defines the size of the blocks. The column blocksize sets the blocksize of the vectors obtained with MatCreateVecs() 2020a23d5eceSKris Buschelman . nz - number of block nonzeros per block row (same for all rows) 2021a23d5eceSKris Buschelman - nnz - array containing the number of block nonzeros in the upper triangular plus 20220298fd71SBarry Smith diagonal portion of each block (possibly different for each block row) or NULL 2023a23d5eceSKris Buschelman 2024a23d5eceSKris Buschelman Options Database Keys: 2025a2b725a8SWilliam Gropp + -mat_no_unroll - uses code that does not unroll the loops in the 2026a23d5eceSKris Buschelman block calculations (much slower) 2027a2b725a8SWilliam Gropp - -mat_block_size - size of the blocks to use (only works if a negative bs is passed in 2028a23d5eceSKris Buschelman 2029a23d5eceSKris Buschelman Level: intermediate 2030a23d5eceSKris Buschelman 2031a23d5eceSKris Buschelman Notes: 2032a23d5eceSKris Buschelman Specify the preallocated storage with either nz or nnz (not both). 20330298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 2034a7f22e61SSatish Balay allocation. See Users-Manual: ch_mat for details. 2035a23d5eceSKris Buschelman 2036aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 2037aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 2038aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 2039aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 2040aa95bbe8SBarry Smith 204149a6f317SBarry Smith If the nnz parameter is given then the nz parameter is ignored 204249a6f317SBarry Smith 204349a6f317SBarry Smith 204469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateSBAIJ() 2045a23d5eceSKris Buschelman @*/ 20467087cfbeSBarry Smith PetscErrorCode MatSeqSBAIJSetPreallocation(Mat B,PetscInt bs,PetscInt nz,const PetscInt nnz[]) 204713f74950SBarry Smith { 20484ac538c5SBarry Smith PetscErrorCode ierr; 2049a23d5eceSKris Buschelman 2050a23d5eceSKris Buschelman PetscFunctionBegin; 20516ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 20526ba663aaSJed Brown PetscValidType(B,1); 20536ba663aaSJed Brown PetscValidLogicalCollectiveInt(B,bs,2); 20544ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqSBAIJSetPreallocation_C",(Mat,PetscInt,PetscInt,const PetscInt[]),(B,bs,nz,nnz));CHKERRQ(ierr); 2055a23d5eceSKris Buschelman PetscFunctionReturn(0); 2056a23d5eceSKris Buschelman } 205749b5e25fSSatish Balay 205838f409ebSLisandro Dalcin /*@C 2059664954b6SBarry Smith MatSeqSBAIJSetPreallocationCSR - Creates a sparse parallel matrix in SBAIJ format using the given nonzero structure and (optional) numerical values 206038f409ebSLisandro Dalcin 206138f409ebSLisandro Dalcin Input Parameters: 20621c4f3114SJed Brown + B - the matrix 2063eab78319SHong Zhang . bs - size of block, the blocks are ALWAYS square. 206438f409ebSLisandro Dalcin . i - the indices into j for the start of each local row (starts with zero) 206538f409ebSLisandro Dalcin . j - the column indices for each local row (starts with zero) these must be sorted for each row 206638f409ebSLisandro Dalcin - v - optional values in the matrix 206738f409ebSLisandro Dalcin 2068664954b6SBarry Smith Level: advanced 206938f409ebSLisandro Dalcin 207038f409ebSLisandro Dalcin Notes: 207138f409ebSLisandro Dalcin The order of the entries in values is specified by the MatOption MAT_ROW_ORIENTED. For example, C programs 207238f409ebSLisandro Dalcin may want to use the default MAT_ROW_ORIENTED=PETSC_TRUE and use an array v[nnz][bs][bs] where the second index is 207338f409ebSLisandro Dalcin over rows within a block and the last index is over columns within a block row. Fortran programs will likely set 207438f409ebSLisandro Dalcin MAT_ROW_ORIENTED=PETSC_FALSE and use a Fortran array v(bs,bs,nnz) in which the first index is over rows within a 207538f409ebSLisandro Dalcin block column and the second index is over columns within a block. 207638f409ebSLisandro Dalcin 207750c5228eSBarry Smith Any entries below the diagonal are ignored 20780cd7f59aSBarry Smith 20790cd7f59aSBarry Smith Though this routine has Preallocation() in the name it also sets the exact nonzero locations of the matrix entries 20800cd7f59aSBarry Smith and usually the numerical values as well 2081664954b6SBarry Smith 208238f409ebSLisandro Dalcin .seealso: MatCreate(), MatCreateSeqSBAIJ(), MatSetValuesBlocked(), MatSeqSBAIJSetPreallocation(), MATSEQSBAIJ 208338f409ebSLisandro Dalcin @*/ 208438f409ebSLisandro Dalcin PetscErrorCode MatSeqSBAIJSetPreallocationCSR(Mat B,PetscInt bs,const PetscInt i[],const PetscInt j[], const PetscScalar v[]) 208538f409ebSLisandro Dalcin { 208638f409ebSLisandro Dalcin PetscErrorCode ierr; 208738f409ebSLisandro Dalcin 208838f409ebSLisandro Dalcin PetscFunctionBegin; 208938f409ebSLisandro Dalcin PetscValidHeaderSpecific(B,MAT_CLASSID,1); 209038f409ebSLisandro Dalcin PetscValidType(B,1); 209138f409ebSLisandro Dalcin PetscValidLogicalCollectiveInt(B,bs,2); 209238f409ebSLisandro Dalcin ierr = PetscTryMethod(B,"MatSeqSBAIJSetPreallocationCSR_C",(Mat,PetscInt,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,bs,i,j,v));CHKERRQ(ierr); 209338f409ebSLisandro Dalcin PetscFunctionReturn(0); 209438f409ebSLisandro Dalcin } 209538f409ebSLisandro Dalcin 2096c464158bSHong Zhang /*@C 2097c464158bSHong Zhang MatCreateSeqSBAIJ - Creates a sparse symmetric matrix in block AIJ (block 2098c464158bSHong Zhang compressed row) format. For good matrix assembly performance the 2099c464158bSHong Zhang user should preallocate the matrix storage by setting the parameter nz 2100c464158bSHong Zhang (or the array nnz). By setting these parameters accurately, performance 2101c464158bSHong Zhang during matrix assembly can be increased by more than a factor of 50. 210249b5e25fSSatish Balay 2103d083f849SBarry Smith Collective 2104c464158bSHong Zhang 2105c464158bSHong Zhang Input Parameters: 2106c464158bSHong Zhang + comm - MPI communicator, set to PETSC_COMM_SELF 2107bb7ae925SBarry Smith . bs - size of block, the blocks are ALWAYS square. One can use MatSetBlockSizes() to set a different row and column blocksize but the row 2108bb7ae925SBarry Smith blocksize always defines the size of the blocks. The column blocksize sets the blocksize of the vectors obtained with MatCreateVecs() 2109c464158bSHong Zhang . m - number of rows, or number of columns 2110c464158bSHong Zhang . nz - number of block nonzeros per block row (same for all rows) 2111744e8345SSatish Balay - nnz - array containing the number of block nonzeros in the upper triangular plus 21120298fd71SBarry Smith diagonal portion of each block (possibly different for each block row) or NULL 2113c464158bSHong Zhang 2114c464158bSHong Zhang Output Parameter: 2115c464158bSHong Zhang . A - the symmetric matrix 2116c464158bSHong Zhang 2117c464158bSHong Zhang Options Database Keys: 2118a2b725a8SWilliam Gropp + -mat_no_unroll - uses code that does not unroll the loops in the 2119c464158bSHong Zhang block calculations (much slower) 2120a2b725a8SWilliam Gropp - -mat_block_size - size of the blocks to use 2121c464158bSHong Zhang 2122c464158bSHong Zhang Level: intermediate 2123c464158bSHong Zhang 2124175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 2125f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 2126175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 2127175b88e8SBarry Smith 2128c464158bSHong Zhang Notes: 21296d6d819aSHong Zhang The number of rows and columns must be divisible by blocksize. 21306d6d819aSHong Zhang This matrix type does not support complex Hermitian operation. 2131c464158bSHong Zhang 2132c464158bSHong Zhang Specify the preallocated storage with either nz or nnz (not both). 21330298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 2134a7f22e61SSatish Balay allocation. See Users-Manual: ch_mat for details. 2135c464158bSHong Zhang 213649a6f317SBarry Smith If the nnz parameter is given then the nz parameter is ignored 213749a6f317SBarry Smith 213869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateSBAIJ() 2139c464158bSHong Zhang @*/ 21407087cfbeSBarry Smith PetscErrorCode MatCreateSeqSBAIJ(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 2141c464158bSHong Zhang { 2142dfbe8321SBarry Smith PetscErrorCode ierr; 2143c464158bSHong Zhang 2144c464158bSHong Zhang PetscFunctionBegin; 2145f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 2146f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 2147c464158bSHong Zhang ierr = MatSetType(*A,MATSEQSBAIJ);CHKERRQ(ierr); 2148367daffbSBarry Smith ierr = MatSeqSBAIJSetPreallocation(*A,bs,nz,(PetscInt*)nnz);CHKERRQ(ierr); 214949b5e25fSSatish Balay PetscFunctionReturn(0); 215049b5e25fSSatish Balay } 215149b5e25fSSatish Balay 2152dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqSBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 215349b5e25fSSatish Balay { 215449b5e25fSSatish Balay Mat C; 215549b5e25fSSatish Balay Mat_SeqSBAIJ *c,*a = (Mat_SeqSBAIJ*)A->data; 21566849ba73SBarry Smith PetscErrorCode ierr; 2157b40805acSSatish Balay PetscInt i,mbs = a->mbs,nz = a->nz,bs2 =a->bs2; 215849b5e25fSSatish Balay 215949b5e25fSSatish Balay PetscFunctionBegin; 2160e32f2f54SBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Corrupt matrix"); 216149b5e25fSSatish Balay 216249b5e25fSSatish Balay *B = 0; 2163ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2164d0f46423SBarry Smith ierr = MatSetSizes(C,A->rmap->N,A->cmap->n,A->rmap->N,A->cmap->n);CHKERRQ(ierr); 21654c7a3774SStefano Zampini ierr = MatSetBlockSizesFromMats(C,A,A);CHKERRQ(ierr); 21668e9a0fb8SHong Zhang ierr = MatSetType(C,MATSEQSBAIJ);CHKERRQ(ierr); 2167692f9cbeSHong Zhang c = (Mat_SeqSBAIJ*)C->data; 2168692f9cbeSHong Zhang 2169273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 2170d5f3da31SBarry Smith C->factortype = A->factortype; 217149b5e25fSSatish Balay c->row = 0; 217249b5e25fSSatish Balay c->icol = 0; 217349b5e25fSSatish Balay c->saved_values = 0; 2174a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 217549b5e25fSSatish Balay C->assembled = PETSC_TRUE; 217649b5e25fSSatish Balay 21771e1e43feSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 21781e1e43feSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 217949b5e25fSSatish Balay c->bs2 = a->bs2; 218049b5e25fSSatish Balay c->mbs = a->mbs; 218149b5e25fSSatish Balay c->nbs = a->nbs; 218249b5e25fSSatish Balay 2183c760cd28SBarry Smith if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { 2184c760cd28SBarry Smith c->imax = a->imax; 2185c760cd28SBarry Smith c->ilen = a->ilen; 2186c760cd28SBarry Smith c->free_imax_ilen = PETSC_FALSE; 2187c760cd28SBarry Smith } else { 2188dcca6d9dSJed Brown ierr = PetscMalloc2((mbs+1),&c->imax,(mbs+1),&c->ilen);CHKERRQ(ierr); 21893bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,2*(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 219049b5e25fSSatish Balay for (i=0; i<mbs; i++) { 219149b5e25fSSatish Balay c->imax[i] = a->imax[i]; 219249b5e25fSSatish Balay c->ilen[i] = a->ilen[i]; 219349b5e25fSSatish Balay } 2194c760cd28SBarry Smith c->free_imax_ilen = PETSC_TRUE; 2195c760cd28SBarry Smith } 219649b5e25fSSatish Balay 219749b5e25fSSatish Balay /* allocate the matrix space */ 21984da8f245SBarry Smith if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { 2199785e854fSJed Brown ierr = PetscMalloc1(bs2*nz,&c->a);CHKERRQ(ierr); 22003bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 220144e1c64aSLisandro Dalcin c->i = a->i; 220244e1c64aSLisandro Dalcin c->j = a->j; 22034da8f245SBarry Smith c->singlemalloc = PETSC_FALSE; 220444e1c64aSLisandro Dalcin c->free_a = PETSC_TRUE; 22054da8f245SBarry Smith c->free_ij = PETSC_FALSE; 22064da8f245SBarry Smith c->parent = A; 22074da8f245SBarry Smith ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22084da8f245SBarry Smith ierr = MatSetOption(A,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 22094da8f245SBarry Smith ierr = MatSetOption(C,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 22104da8f245SBarry Smith } else { 2211dcca6d9dSJed Brown ierr = PetscMalloc3(bs2*nz,&c->a,nz,&c->j,mbs+1,&c->i);CHKERRQ(ierr); 2212580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,mbs+1);CHKERRQ(ierr); 22133bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(mbs+1)*sizeof(PetscInt) + nz*(bs2*sizeof(MatScalar) + sizeof(PetscInt)));CHKERRQ(ierr); 22144da8f245SBarry Smith c->singlemalloc = PETSC_TRUE; 221544e1c64aSLisandro Dalcin c->free_a = PETSC_TRUE; 22164da8f245SBarry Smith c->free_ij = PETSC_TRUE; 22174da8f245SBarry Smith } 221849b5e25fSSatish Balay if (mbs > 0) { 22194da8f245SBarry Smith if (cpvalues != MAT_SHARE_NONZERO_PATTERN) { 2220580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,nz);CHKERRQ(ierr); 22214da8f245SBarry Smith } 222249b5e25fSSatish Balay if (cpvalues == MAT_COPY_VALUES) { 2223580bdb30SBarry Smith ierr = PetscArraycpy(c->a,a->a,bs2*nz);CHKERRQ(ierr); 222449b5e25fSSatish Balay } else { 2225580bdb30SBarry Smith ierr = PetscArrayzero(c->a,bs2*nz);CHKERRQ(ierr); 222649b5e25fSSatish Balay } 2227a1c3900fSBarry Smith if (a->jshort) { 222844e1c64aSLisandro Dalcin /* cannot share jshort, it is reallocated in MatAssemblyEnd_SeqSBAIJ() */ 222944e1c64aSLisandro Dalcin /* if the parent matrix is reassembled, this child matrix will never notice */ 2230785e854fSJed Brown ierr = PetscMalloc1(nz,&c->jshort);CHKERRQ(ierr); 22313bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,nz*sizeof(unsigned short));CHKERRQ(ierr); 2232580bdb30SBarry Smith ierr = PetscArraycpy(c->jshort,a->jshort,nz);CHKERRQ(ierr); 223326fbe8dcSKarl Rupp 22344da8f245SBarry Smith c->free_jshort = PETSC_TRUE; 22354da8f245SBarry Smith } 2236a1c3900fSBarry Smith } 223749b5e25fSSatish Balay 223849b5e25fSSatish Balay c->roworiented = a->roworiented; 223949b5e25fSSatish Balay c->nonew = a->nonew; 224049b5e25fSSatish Balay 224149b5e25fSSatish Balay if (a->diag) { 2242c760cd28SBarry Smith if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { 2243c760cd28SBarry Smith c->diag = a->diag; 2244c760cd28SBarry Smith c->free_diag = PETSC_FALSE; 2245c760cd28SBarry Smith } else { 2246785e854fSJed Brown ierr = PetscMalloc1(mbs,&c->diag);CHKERRQ(ierr); 22473bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,mbs*sizeof(PetscInt));CHKERRQ(ierr); 224826fbe8dcSKarl Rupp for (i=0; i<mbs; i++) c->diag[i] = a->diag[i]; 2249c760cd28SBarry Smith c->free_diag = PETSC_TRUE; 2250c760cd28SBarry Smith } 225144e1c64aSLisandro Dalcin } 22526c6c5352SBarry Smith c->nz = a->nz; 2253f2cbd3d5SJed Brown c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 225449b5e25fSSatish Balay c->solve_work = 0; 225549b5e25fSSatish Balay c->mult_work = 0; 225626fbe8dcSKarl Rupp 225749b5e25fSSatish Balay *B = C; 2258140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 225949b5e25fSSatish Balay PetscFunctionReturn(0); 226049b5e25fSSatish Balay } 226149b5e25fSSatish Balay 2262112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqSBAIJ(Mat newmat,PetscViewer viewer) 22632f480046SShri Abhyankar { 22642f480046SShri Abhyankar Mat_SeqSBAIJ *a; 22652f480046SShri Abhyankar PetscErrorCode ierr; 22662f480046SShri Abhyankar int fd; 22672f480046SShri Abhyankar PetscMPIInt size; 22683059b6faSBarry Smith PetscInt i,nz,header[4],*rowlengths=0,M,N,bs = newmat->rmap->bs; 22692f480046SShri Abhyankar PetscInt *mask,mbs,*jj,j,rowcount,nzcount,k,*s_browlengths,maskcount; 22702f480046SShri Abhyankar PetscInt kmax,jcount,block,idx,point,nzcountb,extra_rows,rows,cols; 22712f480046SShri Abhyankar PetscInt *masked,nmask,tmp,bs2,ishift; 22722f480046SShri Abhyankar PetscScalar *aa; 2273ce94432eSBarry Smith MPI_Comm comm; 22747f489da9SVaclav Hapla PetscBool isbinary; 22752f480046SShri Abhyankar 22762f480046SShri Abhyankar PetscFunctionBegin; 22777f489da9SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 22787f489da9SVaclav Hapla if (!isbinary) SETERRQ2(PetscObjectComm((PetscObject)newmat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newmat)->type_name); 22797f489da9SVaclav Hapla 2280c98fd787SBarry Smith /* force binary viewer to load .info file if it has not yet done so */ 2281c98fd787SBarry Smith ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 2282ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2283c5929fdfSBarry Smith ierr = PetscOptionsGetInt(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_block_size",&bs,NULL);CHKERRQ(ierr); 22843059b6faSBarry Smith if (bs < 0) bs = 1; 22852f480046SShri Abhyankar bs2 = bs*bs; 22862f480046SShri Abhyankar 22872f480046SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 22882f480046SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor"); 22892f480046SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 22909860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 22912f480046SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 22922f480046SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 22932f480046SShri Abhyankar 22942f480046SShri Abhyankar if (header[3] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqSBAIJ"); 22952f480046SShri Abhyankar 22962f480046SShri Abhyankar if (M != N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only do square matrices"); 22972f480046SShri Abhyankar 22982f480046SShri Abhyankar /* 22992f480046SShri Abhyankar This code adds extra rows to make sure the number of rows is 23002f480046SShri Abhyankar divisible by the blocksize 23012f480046SShri Abhyankar */ 23022f480046SShri Abhyankar mbs = M/bs; 23032f480046SShri Abhyankar extra_rows = bs - M + bs*(mbs); 23042f480046SShri Abhyankar if (extra_rows == bs) extra_rows = 0; 23052f480046SShri Abhyankar else mbs++; 23062f480046SShri Abhyankar if (extra_rows) { 23072f480046SShri Abhyankar ierr = PetscInfo(viewer,"Padding loaded matrix to match blocksize\n");CHKERRQ(ierr); 23082f480046SShri Abhyankar } 23092f480046SShri Abhyankar 23102f480046SShri Abhyankar /* Set global sizes if not already set */ 23112f480046SShri Abhyankar if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) { 23122f480046SShri Abhyankar ierr = MatSetSizes(newmat,PETSC_DECIDE,PETSC_DECIDE,M+extra_rows,N+extra_rows);CHKERRQ(ierr); 23132f480046SShri Abhyankar } else { /* Check if the matrix global sizes are correct */ 23142f480046SShri Abhyankar ierr = MatGetSize(newmat,&rows,&cols);CHKERRQ(ierr); 23152f480046SShri Abhyankar if (M != rows || N != cols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix in file of different length (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols); 23162f480046SShri Abhyankar } 23172f480046SShri Abhyankar 23182f480046SShri Abhyankar /* read in row lengths */ 2319854ce69bSBarry Smith ierr = PetscMalloc1(M+extra_rows,&rowlengths);CHKERRQ(ierr); 23209860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,rowlengths,M,NULL,PETSC_INT);CHKERRQ(ierr); 23212f480046SShri Abhyankar for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 23222f480046SShri Abhyankar 23232f480046SShri Abhyankar /* read in column indices */ 2324854ce69bSBarry Smith ierr = PetscMalloc1(nz+extra_rows,&jj);CHKERRQ(ierr); 23259860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,jj,nz,NULL,PETSC_INT);CHKERRQ(ierr); 23262f480046SShri Abhyankar for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 23272f480046SShri Abhyankar 23282f480046SShri Abhyankar /* loop over row lengths determining block row lengths */ 2329071fcb05SBarry Smith ierr = PetscCalloc2(mbs,&s_browlengths,mbs,&mask);CHKERRQ(ierr); 2330071fcb05SBarry Smith ierr = PetscMalloc1(mbs,&masked);CHKERRQ(ierr); 23312f480046SShri Abhyankar rowcount = 0; 23322f480046SShri Abhyankar nzcount = 0; 23332f480046SShri Abhyankar for (i=0; i<mbs; i++) { 23342f480046SShri Abhyankar nmask = 0; 23352f480046SShri Abhyankar for (j=0; j<bs; j++) { 23362f480046SShri Abhyankar kmax = rowlengths[rowcount]; 23372f480046SShri Abhyankar for (k=0; k<kmax; k++) { 23382f480046SShri Abhyankar tmp = jj[nzcount++]/bs; /* block col. index */ 23392f480046SShri Abhyankar if (!mask[tmp] && tmp >= i) {masked[nmask++] = tmp; mask[tmp] = 1;} 23402f480046SShri Abhyankar } 23412f480046SShri Abhyankar rowcount++; 23422f480046SShri Abhyankar } 23432f480046SShri Abhyankar s_browlengths[i] += nmask; 23442f480046SShri Abhyankar 23452f480046SShri Abhyankar /* zero out the mask elements we set */ 23462f480046SShri Abhyankar for (j=0; j<nmask; j++) mask[masked[j]] = 0; 23472f480046SShri Abhyankar } 23482f480046SShri Abhyankar 23492f480046SShri Abhyankar /* Do preallocation */ 2350367daffbSBarry Smith ierr = MatSeqSBAIJSetPreallocation(newmat,bs,0,s_browlengths);CHKERRQ(ierr); 23512f480046SShri Abhyankar a = (Mat_SeqSBAIJ*)newmat->data; 23522f480046SShri Abhyankar 23532f480046SShri Abhyankar /* set matrix "i" values */ 23542f480046SShri Abhyankar a->i[0] = 0; 23552f480046SShri Abhyankar for (i=1; i<= mbs; i++) { 23562f480046SShri Abhyankar a->i[i] = a->i[i-1] + s_browlengths[i-1]; 23572f480046SShri Abhyankar a->ilen[i-1] = s_browlengths[i-1]; 23582f480046SShri Abhyankar } 23592f480046SShri Abhyankar a->nz = a->i[mbs]; 23602f480046SShri Abhyankar 23612f480046SShri Abhyankar /* read in nonzero values */ 2362854ce69bSBarry Smith ierr = PetscMalloc1(nz+extra_rows,&aa);CHKERRQ(ierr); 23639860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,aa,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 23642f480046SShri Abhyankar for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 23652f480046SShri Abhyankar 23662f480046SShri Abhyankar /* set "a" and "j" values into matrix */ 23672f480046SShri Abhyankar nzcount = 0; jcount = 0; 23682f480046SShri Abhyankar for (i=0; i<mbs; i++) { 23692f480046SShri Abhyankar nzcountb = nzcount; 23702f480046SShri Abhyankar nmask = 0; 23712f480046SShri Abhyankar for (j=0; j<bs; j++) { 23722f480046SShri Abhyankar kmax = rowlengths[i*bs+j]; 23732f480046SShri Abhyankar for (k=0; k<kmax; k++) { 23742f480046SShri Abhyankar tmp = jj[nzcount++]/bs; /* block col. index */ 23752f480046SShri Abhyankar if (!mask[tmp] && tmp >= i) { masked[nmask++] = tmp; mask[tmp] = 1;} 23762f480046SShri Abhyankar } 23772f480046SShri Abhyankar } 23782f480046SShri Abhyankar /* sort the masked values */ 23792f480046SShri Abhyankar ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 23802f480046SShri Abhyankar 23812f480046SShri Abhyankar /* set "j" values into matrix */ 23822f480046SShri Abhyankar maskcount = 1; 23832f480046SShri Abhyankar for (j=0; j<nmask; j++) { 23842f480046SShri Abhyankar a->j[jcount++] = masked[j]; 23852f480046SShri Abhyankar mask[masked[j]] = maskcount++; 23862f480046SShri Abhyankar } 23872f480046SShri Abhyankar 23882f480046SShri Abhyankar /* set "a" values into matrix */ 23892f480046SShri Abhyankar ishift = bs2*a->i[i]; 23902f480046SShri Abhyankar for (j=0; j<bs; j++) { 23912f480046SShri Abhyankar kmax = rowlengths[i*bs+j]; 23922f480046SShri Abhyankar for (k=0; k<kmax; k++) { 23932f480046SShri Abhyankar tmp = jj[nzcountb]/bs; /* block col. index */ 23942f480046SShri Abhyankar if (tmp >= i) { 23952f480046SShri Abhyankar block = mask[tmp] - 1; 23962f480046SShri Abhyankar point = jj[nzcountb] - bs*tmp; 23972f480046SShri Abhyankar idx = ishift + bs2*block + j + bs*point; 23982f480046SShri Abhyankar a->a[idx] = aa[nzcountb]; 23992f480046SShri Abhyankar } 24002f480046SShri Abhyankar nzcountb++; 24012f480046SShri Abhyankar } 24022f480046SShri Abhyankar } 24032f480046SShri Abhyankar /* zero out the mask elements we set */ 24042f480046SShri Abhyankar for (j=0; j<nmask; j++) mask[masked[j]] = 0; 24052f480046SShri Abhyankar } 24062f480046SShri Abhyankar if (jcount != a->nz) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 24072f480046SShri Abhyankar 24082f480046SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 2409071fcb05SBarry Smith ierr = PetscFree2(s_browlengths,mask);CHKERRQ(ierr); 24102f480046SShri Abhyankar ierr = PetscFree(aa);CHKERRQ(ierr); 24112f480046SShri Abhyankar ierr = PetscFree(jj);CHKERRQ(ierr); 2412071fcb05SBarry Smith ierr = PetscFree(masked);CHKERRQ(ierr); 24132f480046SShri Abhyankar 24142f480046SShri Abhyankar ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24152f480046SShri Abhyankar ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24162f480046SShri Abhyankar PetscFunctionReturn(0); 24172f480046SShri Abhyankar } 24182f480046SShri Abhyankar 2419c75a6043SHong Zhang /*@ 2420c75a6043SHong Zhang MatCreateSeqSBAIJWithArrays - Creates an sequential SBAIJ matrix using matrix elements 2421c75a6043SHong Zhang (upper triangular entries in CSR format) provided by the user. 2422c75a6043SHong Zhang 2423d083f849SBarry Smith Collective 2424c75a6043SHong Zhang 2425c75a6043SHong Zhang Input Parameters: 2426c75a6043SHong Zhang + comm - must be an MPI communicator of size 1 2427c75a6043SHong Zhang . bs - size of block 2428c75a6043SHong Zhang . m - number of rows 2429c75a6043SHong Zhang . n - number of columns 2430483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of block elements in that row block row of the matrix 2431c75a6043SHong Zhang . j - column indices 2432c75a6043SHong Zhang - a - matrix values 2433c75a6043SHong Zhang 2434c75a6043SHong Zhang Output Parameter: 2435c75a6043SHong Zhang . mat - the matrix 2436c75a6043SHong Zhang 2437dfb205c3SBarry Smith Level: advanced 2438c75a6043SHong Zhang 2439c75a6043SHong Zhang Notes: 2440c75a6043SHong Zhang The i, j, and a arrays are not copied by this routine, the user must free these arrays 2441c75a6043SHong Zhang once the matrix is destroyed 2442c75a6043SHong Zhang 2443c75a6043SHong Zhang You cannot set new nonzero locations into this matrix, that will generate an error. 2444c75a6043SHong Zhang 2445c75a6043SHong Zhang The i and j indices are 0 based 2446c75a6043SHong Zhang 2447dfb205c3SBarry Smith When block size is greater than 1 the matrix values must be stored using the SBAIJ storage format (see the SBAIJ code to determine this). For block size of 1 2448dfb205c3SBarry Smith it is the regular CSR format excluding the lower triangular elements. 2449dfb205c3SBarry Smith 245069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateSBAIJ(), MatCreateSeqSBAIJ() 2451c75a6043SHong Zhang 2452c75a6043SHong Zhang @*/ 2453c3c607ccSBarry Smith PetscErrorCode MatCreateSeqSBAIJWithArrays(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 2454c75a6043SHong Zhang { 2455c75a6043SHong Zhang PetscErrorCode ierr; 2456c75a6043SHong Zhang PetscInt ii; 2457c75a6043SHong Zhang Mat_SeqSBAIJ *sbaij; 2458c75a6043SHong Zhang 2459c75a6043SHong Zhang PetscFunctionBegin; 2460e32f2f54SBarry Smith if (bs != 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"block size %D > 1 is not supported yet",bs); 246141096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 2462c75a6043SHong Zhang 2463c75a6043SHong Zhang ierr = MatCreate(comm,mat);CHKERRQ(ierr); 2464c75a6043SHong Zhang ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 2465c75a6043SHong Zhang ierr = MatSetType(*mat,MATSEQSBAIJ);CHKERRQ(ierr); 2466367daffbSBarry Smith ierr = MatSeqSBAIJSetPreallocation(*mat,bs,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 2467c75a6043SHong Zhang sbaij = (Mat_SeqSBAIJ*)(*mat)->data; 2468dcca6d9dSJed Brown ierr = PetscMalloc2(m,&sbaij->imax,m,&sbaij->ilen);CHKERRQ(ierr); 24693bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)*mat,2*m*sizeof(PetscInt));CHKERRQ(ierr); 2470c75a6043SHong Zhang 2471c75a6043SHong Zhang sbaij->i = i; 2472c75a6043SHong Zhang sbaij->j = j; 2473c75a6043SHong Zhang sbaij->a = a; 247426fbe8dcSKarl Rupp 2475c75a6043SHong Zhang sbaij->singlemalloc = PETSC_FALSE; 2476c75a6043SHong Zhang sbaij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 2477e6b907acSBarry Smith sbaij->free_a = PETSC_FALSE; 2478e6b907acSBarry Smith sbaij->free_ij = PETSC_FALSE; 2479ddf7884eSMatthew Knepley sbaij->free_imax_ilen = PETSC_TRUE; 2480c75a6043SHong Zhang 2481c75a6043SHong Zhang for (ii=0; ii<m; ii++) { 2482c75a6043SHong Zhang sbaij->ilen[ii] = sbaij->imax[ii] = i[ii+1] - i[ii]; 2483c75a6043SHong Zhang #if defined(PETSC_USE_DEBUG) 2484e32f2f54SBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 2485c75a6043SHong Zhang #endif 2486c75a6043SHong Zhang } 2487c75a6043SHong Zhang #if defined(PETSC_USE_DEBUG) 2488c75a6043SHong Zhang for (ii=0; ii<sbaij->i[m]; ii++) { 2489e32f2f54SBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 2490e32f2f54SBarry Smith if (j[ii] > n - 1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 2491c75a6043SHong Zhang } 2492c75a6043SHong Zhang #endif 2493c75a6043SHong Zhang 2494c75a6043SHong Zhang ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2495c75a6043SHong Zhang ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2496c75a6043SHong Zhang PetscFunctionReturn(0); 2497c75a6043SHong Zhang } 2498d06b337dSHong Zhang 249959f5e6ceSHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqSBAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 250059f5e6ceSHong Zhang { 250159f5e6ceSHong Zhang PetscErrorCode ierr; 25028761c3d6SHong Zhang PetscMPIInt size; 250359f5e6ceSHong Zhang 250459f5e6ceSHong Zhang PetscFunctionBegin; 25058761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 25068761c3d6SHong Zhang if (size == 1 && scall == MAT_REUSE_MATRIX) { 25078761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 25088761c3d6SHong Zhang } else { 250959f5e6ceSHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPISBAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 25108761c3d6SHong Zhang } 251159f5e6ceSHong Zhang PetscFunctionReturn(0); 251259f5e6ceSHong Zhang } 2513