1b377110cSBarry Smith 2d5d45c9bSBarry Smith /* 33369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 4d5d45c9bSBarry Smith matrix storage format. 5d5d45c9bSBarry Smith */ 63369ce9aSBarry Smith 77c4f633dSBarry Smith 8c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 9c6db04a5SJed Brown #include <petscblaslapack.h> 10c6db04a5SJed Brown #include <petscbt.h> 11af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h> 120716a85fSBarry Smith 134099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetTypeFromOptions(Mat A) 144099cc6bSBarry Smith { 154099cc6bSBarry Smith PetscErrorCode ierr; 164099cc6bSBarry Smith PetscBool flg; 174099cc6bSBarry Smith char type[256]; 184099cc6bSBarry Smith 194099cc6bSBarry Smith PetscFunctionBegin; 204099cc6bSBarry Smith ierr = PetscObjectOptionsBegin((PetscObject)A); 214099cc6bSBarry Smith ierr = PetscOptionsFList("-mat_seqaij_type","Matrix SeqAIJ type","MatSeqAIJSetType",MatSeqAIJList,"seqaij",type,256,&flg);CHKERRQ(ierr); 224099cc6bSBarry Smith if (flg) { 234099cc6bSBarry Smith ierr = MatSeqAIJSetType(A,type);CHKERRQ(ierr); 244099cc6bSBarry Smith } 254099cc6bSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 264099cc6bSBarry Smith PetscFunctionReturn(0); 274099cc6bSBarry Smith } 284099cc6bSBarry Smith 290716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms) 300716a85fSBarry Smith { 310716a85fSBarry Smith PetscErrorCode ierr; 320716a85fSBarry Smith PetscInt i,m,n; 330716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 340716a85fSBarry Smith 350716a85fSBarry Smith PetscFunctionBegin; 360716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 37580bdb30SBarry Smith ierr = PetscArrayzero(norms,n);CHKERRQ(ierr); 380716a85fSBarry Smith if (type == NORM_2) { 390716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 400716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 410716a85fSBarry Smith } 420716a85fSBarry Smith } else if (type == NORM_1) { 430716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 440716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]); 450716a85fSBarry Smith } 460716a85fSBarry Smith } else if (type == NORM_INFINITY) { 470716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 480716a85fSBarry Smith norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]); 490716a85fSBarry Smith } 500716a85fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType"); 510716a85fSBarry Smith 520716a85fSBarry Smith if (type == NORM_2) { 538f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 540716a85fSBarry Smith } 550716a85fSBarry Smith PetscFunctionReturn(0); 560716a85fSBarry Smith } 570716a85fSBarry Smith 583a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 593a062f41SBarry Smith { 603a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 613a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 623a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 633a062f41SBarry Smith PetscInt *rows; 643a062f41SBarry Smith PetscErrorCode ierr; 653a062f41SBarry Smith 663a062f41SBarry Smith PetscFunctionBegin; 673a062f41SBarry Smith for (i=0; i<m; i++) { 683a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 693a062f41SBarry Smith cnt++; 703a062f41SBarry Smith } 713a062f41SBarry Smith } 723a062f41SBarry Smith ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 733a062f41SBarry Smith cnt = 0; 743a062f41SBarry Smith for (i=0; i<m; i++) { 753a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 763a062f41SBarry Smith rows[cnt] = i; 773a062f41SBarry Smith cnt++; 783a062f41SBarry Smith } 793a062f41SBarry Smith } 803a062f41SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr); 813a062f41SBarry Smith PetscFunctionReturn(0); 823a062f41SBarry Smith } 833a062f41SBarry Smith 84f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 856ce1633cSBarry Smith { 866ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 876ce1633cSBarry Smith const MatScalar *aa = a->a; 886ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 89b2db7409Sstefano_zampini const PetscInt *ii = a->i,*jj = a->j,*diag; 906ce1633cSBarry Smith PetscInt *rows; 916ce1633cSBarry Smith PetscErrorCode ierr; 926ce1633cSBarry Smith 936ce1633cSBarry Smith PetscFunctionBegin; 946ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 956ce1633cSBarry Smith diag = a->diag; 966ce1633cSBarry Smith for (i=0; i<m; i++) { 97b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 986ce1633cSBarry Smith cnt++; 996ce1633cSBarry Smith } 1006ce1633cSBarry Smith } 101785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 1026ce1633cSBarry Smith cnt = 0; 1036ce1633cSBarry Smith for (i=0; i<m; i++) { 104b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1056ce1633cSBarry Smith rows[cnt++] = i; 1066ce1633cSBarry Smith } 1076ce1633cSBarry Smith } 108f1f41ecbSJed Brown *nrows = cnt; 109f1f41ecbSJed Brown *zrows = rows; 110f1f41ecbSJed Brown PetscFunctionReturn(0); 111f1f41ecbSJed Brown } 112f1f41ecbSJed Brown 113f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 114f1f41ecbSJed Brown { 115f1f41ecbSJed Brown PetscInt nrows,*rows; 116f1f41ecbSJed Brown PetscErrorCode ierr; 117f1f41ecbSJed Brown 118f1f41ecbSJed Brown PetscFunctionBegin; 1190298fd71SBarry Smith *zrows = NULL; 120f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 121ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1226ce1633cSBarry Smith PetscFunctionReturn(0); 1236ce1633cSBarry Smith } 1246ce1633cSBarry Smith 125b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 126b3a44c85SBarry Smith { 127b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 128b3a44c85SBarry Smith const MatScalar *aa; 129b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 130b3a44c85SBarry Smith const PetscInt *ii; 131b3a44c85SBarry Smith PetscInt n,i,j,*rows; 132b3a44c85SBarry Smith PetscErrorCode ierr; 133b3a44c85SBarry Smith 134b3a44c85SBarry Smith PetscFunctionBegin; 135b3a44c85SBarry Smith *keptrows = 0; 136b3a44c85SBarry Smith ii = a->i; 137b3a44c85SBarry Smith for (i=0; i<m; i++) { 138b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 139b3a44c85SBarry Smith if (!n) { 140b3a44c85SBarry Smith cnt++; 141b3a44c85SBarry Smith goto ok1; 142b3a44c85SBarry Smith } 143b3a44c85SBarry Smith aa = a->a + ii[i]; 144b3a44c85SBarry Smith for (j=0; j<n; j++) { 145b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 146b3a44c85SBarry Smith } 147b3a44c85SBarry Smith cnt++; 148b3a44c85SBarry Smith ok1:; 149b3a44c85SBarry Smith } 150b3a44c85SBarry Smith if (!cnt) PetscFunctionReturn(0); 151854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr); 152b3a44c85SBarry Smith cnt = 0; 153b3a44c85SBarry Smith for (i=0; i<m; i++) { 154b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 155b3a44c85SBarry Smith if (!n) continue; 156b3a44c85SBarry Smith aa = a->a + ii[i]; 157b3a44c85SBarry Smith for (j=0; j<n; j++) { 158b3a44c85SBarry Smith if (aa[j] != 0.0) { 159b3a44c85SBarry Smith rows[cnt++] = i; 160b3a44c85SBarry Smith break; 161b3a44c85SBarry Smith } 162b3a44c85SBarry Smith } 163b3a44c85SBarry Smith } 164b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 165b3a44c85SBarry Smith PetscFunctionReturn(0); 166b3a44c85SBarry Smith } 167b3a44c85SBarry Smith 1687087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 16979299369SBarry Smith { 17079299369SBarry Smith PetscErrorCode ierr; 17179299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 17299e65526SBarry Smith PetscInt i,m = Y->rmap->n; 17399e65526SBarry Smith const PetscInt *diag; 17454f21887SBarry Smith MatScalar *aa = aij->a; 17599e65526SBarry Smith const PetscScalar *v; 176ace3abfcSBarry Smith PetscBool missing; 177837a59e1SRichard Tran Mills #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 178837a59e1SRichard Tran Mills PetscBool inserted = PETSC_FALSE; 179837a59e1SRichard Tran Mills #endif 18079299369SBarry Smith 18179299369SBarry Smith PetscFunctionBegin; 18209f38230SBarry Smith if (Y->assembled) { 1830298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 18409f38230SBarry Smith if (!missing) { 18579299369SBarry Smith diag = aij->diag; 18699e65526SBarry Smith ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr); 18779299369SBarry Smith if (is == INSERT_VALUES) { 188837a59e1SRichard Tran Mills #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 189837a59e1SRichard Tran Mills inserted = PETSC_TRUE; 190837a59e1SRichard Tran Mills #endif 19179299369SBarry Smith for (i=0; i<m; i++) { 19279299369SBarry Smith aa[diag[i]] = v[i]; 19379299369SBarry Smith } 19479299369SBarry Smith } else { 19579299369SBarry Smith for (i=0; i<m; i++) { 196837a59e1SRichard Tran Mills #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 197837a59e1SRichard Tran Mills if (v[i] != 0.0) inserted = PETSC_TRUE; 198837a59e1SRichard Tran Mills #endif 19979299369SBarry Smith aa[diag[i]] += v[i]; 20079299369SBarry Smith } 20179299369SBarry Smith } 202837a59e1SRichard Tran Mills #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 203837a59e1SRichard Tran Mills if (inserted) Y->offloadmask = PETSC_OFFLOAD_CPU; 204837a59e1SRichard Tran Mills #endif 20599e65526SBarry Smith ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr); 20679299369SBarry Smith PetscFunctionReturn(0); 20779299369SBarry Smith } 208acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 20909f38230SBarry Smith } 21009f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 21109f38230SBarry Smith PetscFunctionReturn(0); 21209f38230SBarry Smith } 21379299369SBarry Smith 2141a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 21517ab2063SBarry Smith { 216416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 217dfbe8321SBarry Smith PetscErrorCode ierr; 21897f1f81fSBarry Smith PetscInt i,ishift; 21917ab2063SBarry Smith 2203a40ed3dSBarry Smith PetscFunctionBegin; 221d0f46423SBarry Smith *m = A->rmap->n; 2223a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 223bfeeae90SHong Zhang ishift = 0; 22453e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 2252462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 226bfeeae90SHong Zhang } else if (oshift == 1) { 2271a83f524SJed Brown PetscInt *tia; 228d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2293b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 230854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr); 2311a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2321a83f524SJed Brown *ia = tia; 233ecc77c7aSBarry Smith if (ja) { 2341a83f524SJed Brown PetscInt *tja; 235854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr); 2361a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2371a83f524SJed Brown *ja = tja; 238ecc77c7aSBarry Smith } 2396945ee14SBarry Smith } else { 240ecc77c7aSBarry Smith *ia = a->i; 241ecc77c7aSBarry Smith if (ja) *ja = a->j; 242a2ce50c7SBarry Smith } 2433a40ed3dSBarry Smith PetscFunctionReturn(0); 244a2744918SBarry Smith } 245a2744918SBarry Smith 2461a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2476945ee14SBarry Smith { 248dfbe8321SBarry Smith PetscErrorCode ierr; 2496945ee14SBarry Smith 2503a40ed3dSBarry Smith PetscFunctionBegin; 2513a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 252bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 253606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 254ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 255bcd2baecSBarry Smith } 2563a40ed3dSBarry Smith PetscFunctionReturn(0); 25717ab2063SBarry Smith } 25817ab2063SBarry Smith 2591a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2603b2fbd54SBarry Smith { 2613b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 262dfbe8321SBarry Smith PetscErrorCode ierr; 263d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 26497f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2653b2fbd54SBarry Smith 2663a40ed3dSBarry Smith PetscFunctionBegin; 267899cda47SBarry Smith *nn = n; 2683a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2693b2fbd54SBarry Smith if (symmetric) { 2702462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2713b2fbd54SBarry Smith } else { 272b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 273854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 274b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 2753b2fbd54SBarry Smith jj = a->j; 2763b2fbd54SBarry Smith for (i=0; i<nz; i++) { 277bfeeae90SHong Zhang collengths[jj[i]]++; 2783b2fbd54SBarry Smith } 2793b2fbd54SBarry Smith cia[0] = oshift; 2803b2fbd54SBarry Smith for (i=0; i<n; i++) { 2813b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2823b2fbd54SBarry Smith } 283580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 2843b2fbd54SBarry Smith jj = a->j; 285a93ec695SBarry Smith for (row=0; row<m; row++) { 286a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 287a93ec695SBarry Smith for (i=0; i<mr; i++) { 288bfeeae90SHong Zhang col = *jj++; 2892205254eSKarl Rupp 2903b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2913b2fbd54SBarry Smith } 2923b2fbd54SBarry Smith } 293606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2943b2fbd54SBarry Smith *ia = cia; *ja = cja; 2953b2fbd54SBarry Smith } 2963a40ed3dSBarry Smith PetscFunctionReturn(0); 2973b2fbd54SBarry Smith } 2983b2fbd54SBarry Smith 2991a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 3003b2fbd54SBarry Smith { 301dfbe8321SBarry Smith PetscErrorCode ierr; 302606d414cSSatish Balay 3033a40ed3dSBarry Smith PetscFunctionBegin; 3043a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 3053b2fbd54SBarry Smith 306606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 307606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 3083a40ed3dSBarry Smith PetscFunctionReturn(0); 3093b2fbd54SBarry Smith } 3103b2fbd54SBarry Smith 3117cee066cSHong Zhang /* 3127cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 3137cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 314040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 3157cee066cSHong Zhang */ 3167cee066cSHong Zhang PetscErrorCode MatGetColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool *done) 3177cee066cSHong Zhang { 3187cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3197cee066cSHong Zhang PetscErrorCode ierr; 3207cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 321071fcb05SBarry Smith PetscInt nz = a->i[m],row,mr,col,tmp; 3227cee066cSHong Zhang PetscInt *cspidx; 323071fcb05SBarry Smith const PetscInt *jj; 3247cee066cSHong Zhang 3257cee066cSHong Zhang PetscFunctionBegin; 3267cee066cSHong Zhang *nn = n; 3277cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 328625f6d37SHong Zhang 329b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 330854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 331b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 332b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cspidx);CHKERRQ(ierr); 3337cee066cSHong Zhang jj = a->j; 3347cee066cSHong Zhang for (i=0; i<nz; i++) { 3357cee066cSHong Zhang collengths[jj[i]]++; 3367cee066cSHong Zhang } 3377cee066cSHong Zhang cia[0] = oshift; 3387cee066cSHong Zhang for (i=0; i<n; i++) { 3397cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3407cee066cSHong Zhang } 341580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 3427cee066cSHong Zhang jj = a->j; 3437cee066cSHong Zhang for (row=0; row<m; row++) { 3447cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3457cee066cSHong Zhang for (i=0; i<mr; i++) { 3467cee066cSHong Zhang col = *jj++; 347071fcb05SBarry Smith tmp = cia[col] + collengths[col]++ - oshift; 348071fcb05SBarry Smith cspidx[tmp] = a->i[row] + i; /* index of a->j */ 349071fcb05SBarry Smith cja[tmp] = row + oshift; 3507cee066cSHong Zhang } 3517cee066cSHong Zhang } 3527cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 353071fcb05SBarry Smith *ia = cia; 354071fcb05SBarry Smith *ja = cja; 3557cee066cSHong Zhang *spidx = cspidx; 3567cee066cSHong Zhang PetscFunctionReturn(0); 3577cee066cSHong Zhang } 3587cee066cSHong Zhang 3597cee066cSHong Zhang PetscErrorCode MatRestoreColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool *done) 3607cee066cSHong Zhang { 3617cee066cSHong Zhang PetscErrorCode ierr; 3627cee066cSHong Zhang 3637cee066cSHong Zhang PetscFunctionBegin; 3645243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3657cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3667cee066cSHong Zhang PetscFunctionReturn(0); 3677cee066cSHong Zhang } 3687cee066cSHong Zhang 36987d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 37087d4246cSBarry Smith { 37187d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 37287d4246cSBarry Smith PetscInt *ai = a->i; 37387d4246cSBarry Smith PetscErrorCode ierr; 37487d4246cSBarry Smith 37587d4246cSBarry Smith PetscFunctionBegin; 376580bdb30SBarry Smith ierr = PetscArraycpy(a->a+ai[row],v,ai[row+1]-ai[row]);CHKERRQ(ierr); 377e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 378c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && ai[row+1]-ai[row]) A->offloadmask = PETSC_OFFLOAD_CPU; 379e2cf4d64SStefano Zampini #endif 38087d4246cSBarry Smith PetscFunctionReturn(0); 38187d4246cSBarry Smith } 38287d4246cSBarry Smith 383bd04181cSBarry Smith /* 384bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 385bd04181cSBarry Smith 386bd04181cSBarry Smith - a single row of values is set with each call 387bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 388bd04181cSBarry Smith - the values are always added to the matrix, not set 389bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 390bd04181cSBarry Smith 3911f763a69SBarry Smith This does NOT assume the global column indices are sorted 392bd04181cSBarry Smith 3931f763a69SBarry Smith */ 394bd04181cSBarry Smith 395af0996ceSBarry Smith #include <petsc/private/isimpl.h> 396189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 397189e4007SBarry Smith { 398189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3991f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 4001f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 4011f763a69SBarry Smith PetscInt lastcol = -1; 402189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 403189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 404189e4007SBarry Smith 405f38dd0b8SBarry Smith row = ridx[im[0]]; 4061f763a69SBarry Smith rp = aj + ai[row]; 4071f763a69SBarry Smith ap = aa + ai[row]; 4081f763a69SBarry Smith nrow = ailen[row]; 409189e4007SBarry Smith low = 0; 410189e4007SBarry Smith high = nrow; 411189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 412189e4007SBarry Smith col = cidx[in[l]]; 413f38dd0b8SBarry Smith value = v[l]; 414189e4007SBarry Smith 415189e4007SBarry Smith if (col <= lastcol) low = 0; 416189e4007SBarry Smith else high = nrow; 417189e4007SBarry Smith lastcol = col; 418189e4007SBarry Smith while (high-low > 5) { 419189e4007SBarry Smith t = (low+high)/2; 420189e4007SBarry Smith if (rp[t] > col) high = t; 421189e4007SBarry Smith else low = t; 422189e4007SBarry Smith } 423189e4007SBarry Smith for (i=low; i<high; i++) { 424189e4007SBarry Smith if (rp[i] == col) { 4251f763a69SBarry Smith ap[i] += value; 426189e4007SBarry Smith low = i + 1; 4271f763a69SBarry Smith break; 428189e4007SBarry Smith } 429189e4007SBarry Smith } 430189e4007SBarry Smith } 431e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 432c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 433e2cf4d64SStefano Zampini #endif 434f38dd0b8SBarry Smith return 0; 435189e4007SBarry Smith } 436189e4007SBarry Smith 43797f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 43817ab2063SBarry Smith { 439416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 440e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 44197f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 4426849ba73SBarry Smith PetscErrorCode ierr; 443e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 444d8cdefa3SHong Zhang MatScalar *ap=NULL,value=0.0,*aa = a->a; 445ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 446ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 447e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 448e2cf4d64SStefano Zampini PetscBool inserted = PETSC_FALSE; 449e2cf4d64SStefano Zampini #endif 45017ab2063SBarry Smith 4513a40ed3dSBarry Smith PetscFunctionBegin; 45217ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 453416022c9SBarry Smith row = im[k]; 4545ef9f2a5SBarry Smith if (row < 0) continue; 4552515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 456e32f2f54SBarry 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); 4573b2fbd54SBarry Smith #endif 458720833daSHong Zhang rp = aj + ai[row]; 459876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 46017ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 461416022c9SBarry Smith low = 0; 462c71e6ed7SBarry Smith high = nrow; 46317ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4645ef9f2a5SBarry Smith if (in[l] < 0) continue; 4652515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 466e32f2f54SBarry 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); 4673b2fbd54SBarry Smith #endif 468bfeeae90SHong Zhang col = in[l]; 469071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 470071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 47136db0b34SBarry Smith 4722205254eSKarl Rupp if (col <= lastcol) low = 0; 4732205254eSKarl Rupp else high = nrow; 474e2ee6c50SBarry Smith lastcol = col; 475416022c9SBarry Smith while (high-low > 5) { 476416022c9SBarry Smith t = (low+high)/2; 477416022c9SBarry Smith if (rp[t] > col) high = t; 478416022c9SBarry Smith else low = t; 47917ab2063SBarry Smith } 480416022c9SBarry Smith for (i=low; i<high; i++) { 48117ab2063SBarry Smith if (rp[i] > col) break; 48217ab2063SBarry Smith if (rp[i] == col) { 483876c6284SHong Zhang if (!A->structure_only) { 4840c0d7e18SFande Kong if (is == ADD_VALUES) { 4850c0d7e18SFande Kong ap[i] += value; 4860c0d7e18SFande Kong (void)PetscLogFlops(1.0); 4870c0d7e18SFande Kong } 48817ab2063SBarry Smith else ap[i] = value; 489e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 490e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 491e2cf4d64SStefano Zampini #endif 492720833daSHong Zhang } 493e44c0bd4SBarry Smith low = i + 1; 49417ab2063SBarry Smith goto noinsert; 49517ab2063SBarry Smith } 49617ab2063SBarry Smith } 497dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 498c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 499e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 500720833daSHong Zhang if (A->structure_only) { 501876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 502720833daSHong Zhang } else { 503fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 504720833daSHong Zhang } 505c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 506416022c9SBarry Smith /* shift up all the later entries in this row */ 507580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 50817ab2063SBarry Smith rp[i] = col; 509580bdb30SBarry Smith if (!A->structure_only){ 510580bdb30SBarry Smith ierr = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr); 511580bdb30SBarry Smith ap[i] = value; 512580bdb30SBarry Smith } 513416022c9SBarry Smith low = i + 1; 514e56f5c9eSBarry Smith A->nonzerostate++; 515e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 516e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 517e2cf4d64SStefano Zampini #endif 518e44c0bd4SBarry Smith noinsert:; 51917ab2063SBarry Smith } 52017ab2063SBarry Smith ailen[row] = nrow; 52117ab2063SBarry Smith } 522e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 523c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && inserted) A->offloadmask = PETSC_OFFLOAD_CPU; 524e2cf4d64SStefano Zampini #endif 5253a40ed3dSBarry Smith PetscFunctionReturn(0); 52617ab2063SBarry Smith } 52717ab2063SBarry Smith 528071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 529071fcb05SBarry Smith { 530071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 531071fcb05SBarry Smith PetscInt *rp,k,row; 532071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 533071fcb05SBarry Smith PetscErrorCode ierr; 534071fcb05SBarry Smith PetscInt *aj = a->j; 535071fcb05SBarry Smith MatScalar *aa = a->a,*ap; 536071fcb05SBarry Smith 537071fcb05SBarry Smith PetscFunctionBegin; 538071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 539071fcb05SBarry Smith row = im[k]; 540071fcb05SBarry Smith rp = aj + ai[row]; 541071fcb05SBarry Smith ap = aa + ai[row]; 542071fcb05SBarry Smith if (!A->was_assembled) { 543071fcb05SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 544071fcb05SBarry Smith } 545071fcb05SBarry Smith if (!A->structure_only) { 546071fcb05SBarry Smith if (v) { 547071fcb05SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 548071fcb05SBarry Smith v += n; 549071fcb05SBarry Smith } else { 550071fcb05SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 551071fcb05SBarry Smith } 552071fcb05SBarry Smith } 553071fcb05SBarry Smith ailen[row] = n; 554071fcb05SBarry Smith a->nz += n; 555071fcb05SBarry Smith } 556e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 557c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 558e2cf4d64SStefano Zampini #endif 559071fcb05SBarry Smith PetscFunctionReturn(0); 560071fcb05SBarry Smith } 561071fcb05SBarry Smith 56281824310SBarry Smith 563a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 5647eb43aa7SLois Curfman McInnes { 5657eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 56697f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 56797f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 56854f21887SBarry Smith MatScalar *ap,*aa = a->a; 5697eb43aa7SLois Curfman McInnes 5703a40ed3dSBarry Smith PetscFunctionBegin; 5717eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 5727eb43aa7SLois Curfman McInnes row = im[k]; 573e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 574e32f2f54SBarry 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); 575bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 5767eb43aa7SLois Curfman McInnes nrow = ailen[row]; 5777eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 578e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 579e32f2f54SBarry 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); 580bfeeae90SHong Zhang col = in[l]; 5817eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 5827eb43aa7SLois Curfman McInnes while (high-low > 5) { 5837eb43aa7SLois Curfman McInnes t = (low+high)/2; 5847eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 5857eb43aa7SLois Curfman McInnes else low = t; 5867eb43aa7SLois Curfman McInnes } 5877eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 5887eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 5897eb43aa7SLois Curfman McInnes if (rp[i] == col) { 590b49de8d1SLois Curfman McInnes *v++ = ap[i]; 5917eb43aa7SLois Curfman McInnes goto finished; 5927eb43aa7SLois Curfman McInnes } 5937eb43aa7SLois Curfman McInnes } 59497e567efSBarry Smith *v++ = 0.0; 5957eb43aa7SLois Curfman McInnes finished:; 5967eb43aa7SLois Curfman McInnes } 5977eb43aa7SLois Curfman McInnes } 5983a40ed3dSBarry Smith PetscFunctionReturn(0); 5997eb43aa7SLois Curfman McInnes } 6007eb43aa7SLois Curfman McInnes 6013ea6fe3dSLisandro Dalcin PetscErrorCode MatView_SeqAIJ_Binary(Mat mat,PetscViewer viewer) 60217ab2063SBarry Smith { 6033ea6fe3dSLisandro Dalcin Mat_SeqAIJ *A = (Mat_SeqAIJ*)mat->data; 6043ea6fe3dSLisandro Dalcin PetscInt header[4],M,N,m,nz,i; 6053ea6fe3dSLisandro Dalcin PetscInt *rowlens; 6066849ba73SBarry Smith PetscErrorCode ierr; 60717ab2063SBarry Smith 6083a40ed3dSBarry Smith PetscFunctionBegin; 6093ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 6102205254eSKarl Rupp 6113ea6fe3dSLisandro Dalcin M = mat->rmap->N; 6123ea6fe3dSLisandro Dalcin N = mat->cmap->N; 6133ea6fe3dSLisandro Dalcin m = mat->rmap->n; 6143ea6fe3dSLisandro Dalcin nz = A->nz; 615416022c9SBarry Smith 6163ea6fe3dSLisandro Dalcin /* write matrix header */ 6173ea6fe3dSLisandro Dalcin header[0] = MAT_FILE_CLASSID; 6183ea6fe3dSLisandro Dalcin header[1] = M; header[2] = N; header[3] = nz; 6193ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr); 620416022c9SBarry Smith 6213ea6fe3dSLisandro Dalcin /* fill in and store row lengths */ 6223ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(m,&rowlens);CHKERRQ(ierr); 6233ea6fe3dSLisandro Dalcin for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i]; 6243ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT);CHKERRQ(ierr); 6253ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 6263ea6fe3dSLisandro Dalcin /* store column indices */ 6273ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT);CHKERRQ(ierr); 628416022c9SBarry Smith /* store nonzero values */ 6293ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 630b37d52dbSMark F. Adams 6313ea6fe3dSLisandro Dalcin /* write block size option to the viewer's .info file */ 6323ea6fe3dSLisandro Dalcin ierr = MatView_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 6333a40ed3dSBarry Smith PetscFunctionReturn(0); 63417ab2063SBarry Smith } 635416022c9SBarry Smith 6367dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 6377dc0baabSHong Zhang { 6387dc0baabSHong Zhang PetscErrorCode ierr; 6397dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 6407dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 6417dc0baabSHong Zhang 6427dc0baabSHong Zhang PetscFunctionBegin; 6437dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 6447dc0baabSHong Zhang for (i=0; i<m; i++) { 6457dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 6467dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 6477dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 6487dc0baabSHong Zhang } 6497dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 6507dc0baabSHong Zhang } 6517dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6527dc0baabSHong Zhang PetscFunctionReturn(0); 6537dc0baabSHong Zhang } 6547dc0baabSHong Zhang 65509573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 656cd155464SBarry Smith 657dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 658416022c9SBarry Smith { 659416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 660dfbe8321SBarry Smith PetscErrorCode ierr; 66160e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 662e060cb09SBarry Smith const char *name; 663f3ef73ceSBarry Smith PetscViewerFormat format; 66417ab2063SBarry Smith 6653a40ed3dSBarry Smith PetscFunctionBegin; 6667dc0baabSHong Zhang if (A->structure_only) { 6677dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 6687dc0baabSHong Zhang PetscFunctionReturn(0); 6697dc0baabSHong Zhang } 67043e49210SHong Zhang 671b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 67271c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 67397f1f81fSBarry Smith PetscInt nofinalvalue = 0; 67460e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 675c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 676d00d2cf4SBarry Smith nofinalvalue = 1; 677d00d2cf4SBarry Smith } 678d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 679d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 68077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 681fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 682fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 683fbfe6fa7SJed Brown #else 68477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 685fbfe6fa7SJed Brown #endif 686b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 68717ab2063SBarry Smith 68817ab2063SBarry Smith for (i=0; i<m; i++) { 68960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 690aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 691a9bf72d8SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 69217ab2063SBarry Smith #else 69360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 69417ab2063SBarry Smith #endif 69517ab2063SBarry Smith } 69617ab2063SBarry Smith } 697d00d2cf4SBarry Smith if (nofinalvalue) { 698c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 699c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 700c337ccceSJed Brown #else 701d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 702c337ccceSJed Brown #endif 703d00d2cf4SBarry Smith } 704317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 705fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 706d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7072950ac48SStefano Zampini } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 708cd155464SBarry Smith PetscFunctionReturn(0); 709fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 710d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 71144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 71277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 71360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 714aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 71536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 71660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 71736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 71860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 71936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 72060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 7216831982aSBarry Smith } 72244cd7ae7SLois Curfman McInnes #else 72360e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 72444cd7ae7SLois Curfman McInnes #endif 72544cd7ae7SLois Curfman McInnes } 726b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 72744cd7ae7SLois Curfman McInnes } 728d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 729fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 73097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 731d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 732854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 733496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 734496be53dSLois Curfman McInnes sptr[i] = nzd+1; 73560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 736496be53dSLois Curfman McInnes if (a->j[j] >= i) { 737aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 73836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 739496be53dSLois Curfman McInnes #else 740496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 741496be53dSLois Curfman McInnes #endif 742496be53dSLois Curfman McInnes } 743496be53dSLois Curfman McInnes } 744496be53dSLois Curfman McInnes } 7452e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 74677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 7472e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 7482205254eSKarl Rupp if (i+4<m) { 7492205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr); 7502205254eSKarl Rupp } else if (i+3<m) { 7512205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr); 7522205254eSKarl Rupp } else if (i+2<m) { 7532205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 7542205254eSKarl Rupp } else if (i+1<m) { 7552205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 7562205254eSKarl Rupp } else if (i<m) { 7572205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 7582205254eSKarl Rupp } else { 7592205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 7602205254eSKarl Rupp } 761496be53dSLois Curfman McInnes } 762b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 763606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 764496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 76560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 76677431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 767496be53dSLois Curfman McInnes } 768b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 769496be53dSLois Curfman McInnes } 770b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 771496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 77260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 773496be53dSLois Curfman McInnes if (a->j[j] >= i) { 774aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 77536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 77660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7776831982aSBarry Smith } 778496be53dSLois Curfman McInnes #else 77960e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 780496be53dSLois Curfman McInnes #endif 781496be53dSLois Curfman McInnes } 782496be53dSLois Curfman McInnes } 783b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 784496be53dSLois Curfman McInnes } 785d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 786fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 78797f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 78887828ca2SBarry Smith PetscScalar value; 78968f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 79068f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 79168f1ed48SBarry Smith 79268f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 79368f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 79468f1ed48SBarry Smith realonly = PETSC_FALSE; 79568f1ed48SBarry Smith break; 79668f1ed48SBarry Smith } 79768f1ed48SBarry Smith } 79868f1ed48SBarry Smith #endif 79902594712SBarry Smith 800d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 80102594712SBarry Smith for (i=0; i<m; i++) { 80202594712SBarry Smith jcnt = 0; 803d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 804e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 80502594712SBarry Smith value = a->a[cnt++]; 806e24b481bSBarry Smith jcnt++; 80702594712SBarry Smith } else { 80802594712SBarry Smith value = 0.0; 80902594712SBarry Smith } 810aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 81168f1ed48SBarry Smith if (realonly) { 81260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 81368f1ed48SBarry Smith } else { 81460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 81568f1ed48SBarry Smith } 81602594712SBarry Smith #else 81760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 81802594712SBarry Smith #endif 81902594712SBarry Smith } 820b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 82102594712SBarry Smith } 822d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 8233c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 824150b93efSMatthew G. Knepley PetscInt fshift=1; 825d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 8263c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 82719303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 8283c215bfdSMatthew Knepley #else 82919303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 8303c215bfdSMatthew Knepley #endif 831d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 8323c215bfdSMatthew Knepley for (i=0; i<m; i++) { 83360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 8343c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 835a9a0e077SKarl Rupp ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8363c215bfdSMatthew Knepley #else 837150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 8383c215bfdSMatthew Knepley #endif 8393c215bfdSMatthew Knepley } 8403c215bfdSMatthew Knepley } 841d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 8423a40ed3dSBarry Smith } else { 843d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 844d5f3da31SBarry Smith if (A->factortype) { 84516cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 84616cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 84716cd7e1dSShri Abhyankar /* L part */ 84860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 84916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 85016cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 85160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 85216cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 8536712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 85416cd7e1dSShri Abhyankar } else { 85560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 85616cd7e1dSShri Abhyankar } 85716cd7e1dSShri Abhyankar #else 85860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 85916cd7e1dSShri Abhyankar #endif 86016cd7e1dSShri Abhyankar } 86116cd7e1dSShri Abhyankar /* diagonal */ 86216cd7e1dSShri Abhyankar j = a->diag[i]; 86316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 86416cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 86560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr); 86616cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 8676712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])));CHKERRQ(ierr); 86816cd7e1dSShri Abhyankar } else { 86960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 87016cd7e1dSShri Abhyankar } 87116cd7e1dSShri Abhyankar #else 87260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 87316cd7e1dSShri Abhyankar #endif 87416cd7e1dSShri Abhyankar 87516cd7e1dSShri Abhyankar /* U part */ 87660e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 87716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 87816cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 87960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 88016cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 88122ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 88216cd7e1dSShri Abhyankar } else { 88360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 88416cd7e1dSShri Abhyankar } 88516cd7e1dSShri Abhyankar #else 88660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 88716cd7e1dSShri Abhyankar #endif 88816cd7e1dSShri Abhyankar } 88916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 89016cd7e1dSShri Abhyankar } 89116cd7e1dSShri Abhyankar } else { 89217ab2063SBarry Smith for (i=0; i<m; i++) { 89377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 89460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 895aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 89636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 89760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 89836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 89960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 9003a40ed3dSBarry Smith } else { 90160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 90217ab2063SBarry Smith } 90317ab2063SBarry Smith #else 90460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 90517ab2063SBarry Smith #endif 90617ab2063SBarry Smith } 907b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 90817ab2063SBarry Smith } 90916cd7e1dSShri Abhyankar } 910d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 91117ab2063SBarry Smith } 912b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9133a40ed3dSBarry Smith PetscFunctionReturn(0); 914416022c9SBarry Smith } 915416022c9SBarry Smith 9169804daf3SBarry Smith #include <petscdraw.h> 917dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 918416022c9SBarry Smith { 919480ef9eaSBarry Smith Mat A = (Mat) Aa; 920416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 921dfbe8321SBarry Smith PetscErrorCode ierr; 922383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 923383922c3SLisandro Dalcin int color; 924b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 925b0a32e0cSBarry Smith PetscViewer viewer; 926f3ef73ceSBarry Smith PetscViewerFormat format; 927cddf8d76SBarry Smith 9283a40ed3dSBarry Smith PetscFunctionBegin; 929480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 930b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 931b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 932383922c3SLisandro Dalcin 933416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 9340513a670SBarry Smith 935fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 936383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 9370513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 938b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 939416022c9SBarry Smith for (i=0; i<m; i++) { 940cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 941bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 942bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 94336db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 944b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 945cddf8d76SBarry Smith } 946cddf8d76SBarry Smith } 947b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 948cddf8d76SBarry Smith for (i=0; i<m; i++) { 949cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 950bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 951bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 952cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 953b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 954cddf8d76SBarry Smith } 955cddf8d76SBarry Smith } 956b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 957cddf8d76SBarry Smith for (i=0; i<m; i++) { 958cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 959bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 960bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 96136db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 962b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 963416022c9SBarry Smith } 964416022c9SBarry Smith } 965383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 9660513a670SBarry Smith } else { 9670513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 9680513a670SBarry Smith /* first determine max of all nonzero values */ 969b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 970383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 971b0a32e0cSBarry Smith PetscDraw popup; 9720513a670SBarry Smith 9730513a670SBarry Smith for (i=0; i<nz; i++) { 9740513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 9750513a670SBarry Smith } 976383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 977b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 97845f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 979383922c3SLisandro Dalcin 980383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 9810513a670SBarry Smith for (i=0; i<m; i++) { 982383922c3SLisandro Dalcin y_l = m - i - 1.0; 983383922c3SLisandro Dalcin y_r = y_l + 1.0; 984bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 985383922c3SLisandro Dalcin x_l = a->j[j]; 986383922c3SLisandro Dalcin x_r = x_l + 1.0; 987b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 988b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 9890513a670SBarry Smith count++; 9900513a670SBarry Smith } 9910513a670SBarry Smith } 992383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 9930513a670SBarry Smith } 994480ef9eaSBarry Smith PetscFunctionReturn(0); 995480ef9eaSBarry Smith } 996cddf8d76SBarry Smith 9979804daf3SBarry Smith #include <petscdraw.h> 998dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 999480ef9eaSBarry Smith { 1000dfbe8321SBarry Smith PetscErrorCode ierr; 1001b0a32e0cSBarry Smith PetscDraw draw; 100236db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1003ace3abfcSBarry Smith PetscBool isnull; 1004480ef9eaSBarry Smith 1005480ef9eaSBarry Smith PetscFunctionBegin; 1006b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1007b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1008480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1009480ef9eaSBarry Smith 1010d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1011480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1012b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1013832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1014b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 10150298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1016832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 10173a40ed3dSBarry Smith PetscFunctionReturn(0); 1018416022c9SBarry Smith } 1019416022c9SBarry Smith 1020dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1021416022c9SBarry Smith { 1022dfbe8321SBarry Smith PetscErrorCode ierr; 1023ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1024416022c9SBarry Smith 10253a40ed3dSBarry Smith PetscFunctionBegin; 1026251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1027251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1028251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1029c45a1595SBarry Smith if (iascii) { 10303a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 10310f5bd95cSBarry Smith } else if (isbinary) { 10323a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 10330f5bd95cSBarry Smith } else if (isdraw) { 10343a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 103511aeaf0aSBarry Smith } 10364108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 10373a40ed3dSBarry Smith PetscFunctionReturn(0); 103817ab2063SBarry Smith } 103919bcc07fSBarry Smith 1040dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 104117ab2063SBarry Smith { 1042416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10436849ba73SBarry Smith PetscErrorCode ierr; 1044580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1045d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 104654f21887SBarry Smith MatScalar *aa = a->a,*ap; 10473447b6efSHong Zhang PetscReal ratio = 0.6; 104817ab2063SBarry Smith 10493a40ed3dSBarry Smith PetscFunctionBegin; 10503a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1051071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1052071fcb05SBarry Smith if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) PetscFunctionReturn(0); 105317ab2063SBarry Smith 105443ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 105517ab2063SBarry Smith for (i=1; i<m; i++) { 1056416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 105717ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 105894a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 105917ab2063SBarry Smith if (fshift) { 1060bfeeae90SHong Zhang ip = aj + ai[i]; 1061bfeeae90SHong Zhang ap = aa + ai[i]; 106217ab2063SBarry Smith N = ailen[i]; 1063580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1064580bdb30SBarry Smith if (!A->structure_only) { 1065580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 106617ab2063SBarry Smith } 106717ab2063SBarry Smith } 106817ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 106917ab2063SBarry Smith } 107017ab2063SBarry Smith if (m) { 107117ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 107217ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 107317ab2063SBarry Smith } 10747b083b7cSBarry Smith 107517ab2063SBarry Smith /* reset ilen and imax for each row */ 10767b083b7cSBarry Smith a->nonzerorowcnt = 0; 1077396832f4SHong Zhang if (A->structure_only) { 1078071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1079071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1080396832f4SHong Zhang } else { /* !A->structure_only */ 108117ab2063SBarry Smith for (i=0; i<m; i++) { 108217ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 10837b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 108417ab2063SBarry Smith } 1085396832f4SHong Zhang } 1086bfeeae90SHong Zhang a->nz = ai[m]; 108765e19b50SBarry Smith if (fshift && a->nounused == -1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D, %D unneeded", m, A->cmap->n, fshift); 108817ab2063SBarry Smith 108909f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1090d0f46423SBarry Smith ierr = PetscInfo4(A,"Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->cmap->n,fshift,a->nz);CHKERRQ(ierr); 1091ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1092ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 10932205254eSKarl Rupp 10948e58a170SBarry Smith A->info.mallocs += a->reallocs; 1095dd5f02e7SSatish Balay a->reallocs = 0; 10966712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 109736db0b34SBarry Smith a->rmax = rmax; 10984e220ebcSLois Curfman McInnes 1099396832f4SHong Zhang if (!A->structure_only) { 110011e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1101396832f4SHong Zhang } 11024108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 11033a40ed3dSBarry Smith PetscFunctionReturn(0); 110417ab2063SBarry Smith } 110517ab2063SBarry Smith 110699cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 110799cafbc1SBarry Smith { 110899cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 110999cafbc1SBarry Smith PetscInt i,nz = a->nz; 111054f21887SBarry Smith MatScalar *aa = a->a; 1111acf2f550SJed Brown PetscErrorCode ierr; 111299cafbc1SBarry Smith 111399cafbc1SBarry Smith PetscFunctionBegin; 111499cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1115acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1116e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1117c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1118e2cf4d64SStefano Zampini #endif 111999cafbc1SBarry Smith PetscFunctionReturn(0); 112099cafbc1SBarry Smith } 112199cafbc1SBarry Smith 112299cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 112399cafbc1SBarry Smith { 112499cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 112599cafbc1SBarry Smith PetscInt i,nz = a->nz; 112654f21887SBarry Smith MatScalar *aa = a->a; 1127acf2f550SJed Brown PetscErrorCode ierr; 112899cafbc1SBarry Smith 112999cafbc1SBarry Smith PetscFunctionBegin; 113099cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1131acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1132e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1133c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1134e2cf4d64SStefano Zampini #endif 113599cafbc1SBarry Smith PetscFunctionReturn(0); 113699cafbc1SBarry Smith } 113799cafbc1SBarry Smith 1138dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 113917ab2063SBarry Smith { 1140416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1141dfbe8321SBarry Smith PetscErrorCode ierr; 11423a40ed3dSBarry Smith 11433a40ed3dSBarry Smith PetscFunctionBegin; 1144580bdb30SBarry Smith ierr = PetscArrayzero(a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 1145acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1146e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1147c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1148e2cf4d64SStefano Zampini #endif 11493a40ed3dSBarry Smith PetscFunctionReturn(0); 115017ab2063SBarry Smith } 1151416022c9SBarry Smith 1152dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 115317ab2063SBarry Smith { 1154416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1155dfbe8321SBarry Smith PetscErrorCode ierr; 1156d5d45c9bSBarry Smith 11573a40ed3dSBarry Smith PetscFunctionBegin; 1158aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1159d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 116017ab2063SBarry Smith #endif 1161e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 11626bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 11636bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 116405b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1165d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1166071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1167071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1168846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 116971f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 117005b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 11716bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 117205b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 11736bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 1174cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 11750b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1176a30b2313SHong Zhang 11774108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1178bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1179901853e0SKris Buschelman 1180dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1181bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1182bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1183bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1184bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1185bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1186bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1187*4222ddf1SHong Zhang 1188*4222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA) 1189*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 1190*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatSetFromOptions_seqaijcusparse_seqaij_C",NULL);CHKERRQ(ierr); 1191*4222ddf1SHong Zhang #endif 1192*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL);CHKERRQ(ierr); 1193af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1194af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1195af8000cdSHong Zhang #endif 119663c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 119763c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 1198*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 119963c07aadSStefano Zampini #endif 1200b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1201c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1202c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1203bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1204bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1205846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1206bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1207bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 1208*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL);CHKERRQ(ierr); 1209*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 1210*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 12113a40ed3dSBarry Smith PetscFunctionReturn(0); 121217ab2063SBarry Smith } 121317ab2063SBarry Smith 1214ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 121517ab2063SBarry Smith { 1216416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12174846f1f5SKris Buschelman PetscErrorCode ierr; 12183a40ed3dSBarry Smith 12193a40ed3dSBarry Smith PetscFunctionBegin; 1220a65d3064SKris Buschelman switch (op) { 1221a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 12224e0d8c25SBarry Smith a->roworiented = flg; 1223a65d3064SKris Buschelman break; 1224a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1225a9817697SBarry Smith a->keepnonzeropattern = flg; 1226a65d3064SKris Buschelman break; 1227512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1228512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1229a65d3064SKris Buschelman break; 1230a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 12314e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1232a65d3064SKris Buschelman break; 1233a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 12344e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1235a65d3064SKris Buschelman break; 123628b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 123728b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 123828b2fa4aSMatthew Knepley break; 1239a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 12404e0d8c25SBarry Smith a->ignorezeroentries = flg; 12410df259c2SBarry Smith break; 12423d472b54SHong Zhang case MAT_SPD: 1243b1646e73SJed Brown case MAT_SYMMETRIC: 1244b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1245b1646e73SJed Brown case MAT_HERMITIAN: 1246b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1247957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 12485021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 12495021d80fSJed Brown break; 12504e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1251a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1252a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1253290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1254a65d3064SKris Buschelman break; 1255b87ac2d8SJed Brown case MAT_USE_INODES: 1256b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1257b87ac2d8SJed Brown break; 1258c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1259c10200c1SHong Zhang A->submat_singleis = flg; 1260c10200c1SHong Zhang break; 1261071fcb05SBarry Smith case MAT_SORTED_FULL: 1262071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1263071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1264071fcb05SBarry Smith break; 1265a65d3064SKris Buschelman default: 1266e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1267a65d3064SKris Buschelman } 12684108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 12693a40ed3dSBarry Smith PetscFunctionReturn(0); 127017ab2063SBarry Smith } 127117ab2063SBarry Smith 1272dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 127317ab2063SBarry Smith { 1274416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12756849ba73SBarry Smith PetscErrorCode ierr; 1276fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1277fdc842d1SBarry Smith PetscScalar *aa=a->a,*x; 127817ab2063SBarry Smith 12793a40ed3dSBarry Smith PetscFunctionBegin; 1280d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1281e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 128235e7444dSHong Zhang 1283d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1284d3e70bfaSHong Zhang PetscInt *diag=a->diag; 1285fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 12862c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 1287fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 128835e7444dSHong Zhang PetscFunctionReturn(0); 128935e7444dSHong Zhang } 129035e7444dSHong Zhang 1291fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 129235e7444dSHong Zhang for (i=0; i<n; i++) { 1293fdc842d1SBarry Smith x[i] = 0.0; 129435e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 129535e7444dSHong Zhang if (aj[j] == i) { 129635e7444dSHong Zhang x[i] = aa[j]; 129717ab2063SBarry Smith break; 129817ab2063SBarry Smith } 129917ab2063SBarry Smith } 130017ab2063SBarry Smith } 1301fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 13023a40ed3dSBarry Smith PetscFunctionReturn(0); 130317ab2063SBarry Smith } 130417ab2063SBarry Smith 1305c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1306dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 130717ab2063SBarry Smith { 1308416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1309d9ca1df4SBarry Smith PetscScalar *y; 1310d9ca1df4SBarry Smith const PetscScalar *x; 1311dfbe8321SBarry Smith PetscErrorCode ierr; 1312d0f46423SBarry Smith PetscInt m = A->rmap->n; 13135c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1314d9ca1df4SBarry Smith const MatScalar *v; 1315a77337e4SBarry Smith PetscScalar alpha; 1316d9ca1df4SBarry Smith PetscInt n,i,j; 1317d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 13183447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1319ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 13205c897100SBarry Smith #endif 132117ab2063SBarry Smith 13223a40ed3dSBarry Smith PetscFunctionBegin; 13232e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1324d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 13251ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 13265c897100SBarry Smith 13275c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1328bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 13295c897100SBarry Smith #else 13303447b6efSHong Zhang if (usecprow) { 13313447b6efSHong Zhang m = cprow.nrows; 13323447b6efSHong Zhang ii = cprow.i; 13337b2bb3b9SHong Zhang ridx = cprow.rindex; 13343447b6efSHong Zhang } else { 13353447b6efSHong Zhang ii = a->i; 13363447b6efSHong Zhang } 133717ab2063SBarry Smith for (i=0; i<m; i++) { 13383447b6efSHong Zhang idx = a->j + ii[i]; 13393447b6efSHong Zhang v = a->a + ii[i]; 13403447b6efSHong Zhang n = ii[i+1] - ii[i]; 13413447b6efSHong Zhang if (usecprow) { 13427b2bb3b9SHong Zhang alpha = x[ridx[i]]; 13433447b6efSHong Zhang } else { 134417ab2063SBarry Smith alpha = x[i]; 13453447b6efSHong Zhang } 134604fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 134717ab2063SBarry Smith } 13485c897100SBarry Smith #endif 1349dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1350d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 13511ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13523a40ed3dSBarry Smith PetscFunctionReturn(0); 135317ab2063SBarry Smith } 135417ab2063SBarry Smith 1355dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 13565c897100SBarry Smith { 1357dfbe8321SBarry Smith PetscErrorCode ierr; 13585c897100SBarry Smith 13595c897100SBarry Smith PetscFunctionBegin; 1360170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 13615c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 13625c897100SBarry Smith PetscFunctionReturn(0); 13635c897100SBarry Smith } 13645c897100SBarry Smith 1365c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 136678b84d54SShri Abhyankar 1367dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 136817ab2063SBarry Smith { 1369416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1370d9fead3dSBarry Smith PetscScalar *y; 137154f21887SBarry Smith const PetscScalar *x; 137254f21887SBarry Smith const MatScalar *aa; 1373dfbe8321SBarry Smith PetscErrorCode ierr; 1374003131ecSBarry Smith PetscInt m=A->rmap->n; 13750298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 13767b083b7cSBarry Smith PetscInt n,i; 1377362ced78SSatish Balay PetscScalar sum; 1378ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 137917ab2063SBarry Smith 1380b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 138197952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1382fee21e36SBarry Smith #endif 1383fee21e36SBarry Smith 13843a40ed3dSBarry Smith PetscFunctionBegin; 13853649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 13861ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1387416022c9SBarry Smith ii = a->i; 13884eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1389580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 139097952fefSHong Zhang m = a->compressedrow.nrows; 139197952fefSHong Zhang ii = a->compressedrow.i; 139297952fefSHong Zhang ridx = a->compressedrow.rindex; 139397952fefSHong Zhang for (i=0; i<m; i++) { 139497952fefSHong Zhang n = ii[i+1] - ii[i]; 139597952fefSHong Zhang aj = a->j + ii[i]; 139697952fefSHong Zhang aa = a->a + ii[i]; 139797952fefSHong Zhang sum = 0.0; 1398003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1399003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 140097952fefSHong Zhang y[*ridx++] = sum; 140197952fefSHong Zhang } 140297952fefSHong Zhang } else { /* do not use compressed row format */ 1403b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 14043d3eaba7SBarry Smith aj = a->j; 14053d3eaba7SBarry Smith aa = a->a; 1406b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1407b05257ddSBarry Smith #else 140817ab2063SBarry Smith for (i=0; i<m; i++) { 1409003131ecSBarry Smith n = ii[i+1] - ii[i]; 1410003131ecSBarry Smith aj = a->j + ii[i]; 1411003131ecSBarry Smith aa = a->a + ii[i]; 141217ab2063SBarry Smith sum = 0.0; 1413003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 141417ab2063SBarry Smith y[i] = sum; 141517ab2063SBarry Smith } 14168d195f9aSBarry Smith #endif 1417b05257ddSBarry Smith } 14187b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 14193649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14201ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14213a40ed3dSBarry Smith PetscFunctionReturn(0); 142217ab2063SBarry Smith } 142317ab2063SBarry Smith 1424b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1425b434eb95SMatthew G. Knepley { 1426b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1427b434eb95SMatthew G. Knepley PetscScalar *y; 1428b434eb95SMatthew G. Knepley const PetscScalar *x; 1429b434eb95SMatthew G. Knepley const MatScalar *aa; 1430b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1431b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1432b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1433b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1434b434eb95SMatthew G. Knepley PetscScalar sum; 1435b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1436b434eb95SMatthew G. Knepley 1437b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1438b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1439b434eb95SMatthew G. Knepley #endif 1440b434eb95SMatthew G. Knepley 1441b434eb95SMatthew G. Knepley PetscFunctionBegin; 1442b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1443b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1444b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1445b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1446b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1447b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1448b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1449b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1450b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1451b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1452b434eb95SMatthew G. Knepley sum = 0.0; 1453b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1454b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1455b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1456b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1457b434eb95SMatthew G. Knepley } 1458b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 14593d3eaba7SBarry Smith ii = a->i; 1460b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1461b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1462b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1463b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1464b434eb95SMatthew G. Knepley sum = 0.0; 1465b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1466b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1467b434eb95SMatthew G. Knepley y[i] = sum; 1468b434eb95SMatthew G. Knepley } 1469b434eb95SMatthew G. Knepley } 1470b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1471b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1472b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1473b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1474b434eb95SMatthew G. Knepley } 1475b434eb95SMatthew G. Knepley 1476b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1477b434eb95SMatthew G. Knepley { 1478b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1479b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1480b434eb95SMatthew G. Knepley const PetscScalar *x; 1481b434eb95SMatthew G. Knepley const MatScalar *aa; 1482b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1483b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1484b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1485b434eb95SMatthew G. Knepley PetscScalar sum; 1486b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1487b434eb95SMatthew G. Knepley 1488b434eb95SMatthew G. Knepley PetscFunctionBegin; 1489b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1490d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1491b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1492b434eb95SMatthew G. Knepley if (zz != yy) { 1493580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1494b434eb95SMatthew G. Knepley } 1495b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1496b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1497b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1498b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1499b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1500b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1501b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1502b434eb95SMatthew G. Knepley sum = y[*ridx]; 1503b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1504b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1505b434eb95SMatthew G. Knepley } 1506b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 15073d3eaba7SBarry Smith ii = a->i; 1508b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1509b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1510b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1511b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1512b434eb95SMatthew G. Knepley sum = y[i]; 1513b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1514b434eb95SMatthew G. Knepley z[i] = sum; 1515b434eb95SMatthew G. Knepley } 1516b434eb95SMatthew G. Knepley } 1517b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1518b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1519d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1520b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1521b434eb95SMatthew G. Knepley } 1522b434eb95SMatthew G. Knepley 1523c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1524dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 152517ab2063SBarry Smith { 1526416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1527f15663dcSBarry Smith PetscScalar *y,*z; 1528f15663dcSBarry Smith const PetscScalar *x; 152954f21887SBarry Smith const MatScalar *aa; 1530dfbe8321SBarry Smith PetscErrorCode ierr; 1531d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1532d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1533362ced78SSatish Balay PetscScalar sum; 1534ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 15359ea0dfa2SSatish Balay 15363a40ed3dSBarry Smith PetscFunctionBegin; 1537f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1538d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 15394eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 15404eb6d288SHong Zhang if (zz != yy) { 1541580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 15424eb6d288SHong Zhang } 154397952fefSHong Zhang m = a->compressedrow.nrows; 154497952fefSHong Zhang ii = a->compressedrow.i; 154597952fefSHong Zhang ridx = a->compressedrow.rindex; 154697952fefSHong Zhang for (i=0; i<m; i++) { 154797952fefSHong Zhang n = ii[i+1] - ii[i]; 154897952fefSHong Zhang aj = a->j + ii[i]; 154997952fefSHong Zhang aa = a->a + ii[i]; 155097952fefSHong Zhang sum = y[*ridx]; 1551f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 155297952fefSHong Zhang z[*ridx++] = sum; 155397952fefSHong Zhang } 155497952fefSHong Zhang } else { /* do not use compressed row format */ 15553d3eaba7SBarry Smith ii = a->i; 1556f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 15573d3eaba7SBarry Smith aj = a->j; 15583d3eaba7SBarry Smith aa = a->a; 1559f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1560f15663dcSBarry Smith #else 156117ab2063SBarry Smith for (i=0; i<m; i++) { 1562f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1563f15663dcSBarry Smith aj = a->j + ii[i]; 1564f15663dcSBarry Smith aa = a->a + ii[i]; 156517ab2063SBarry Smith sum = y[i]; 1566f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 156717ab2063SBarry Smith z[i] = sum; 156817ab2063SBarry Smith } 156902ab625aSSatish Balay #endif 1570f15663dcSBarry Smith } 1571dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1572f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1573d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 15743a40ed3dSBarry Smith PetscFunctionReturn(0); 157517ab2063SBarry Smith } 157617ab2063SBarry Smith 157717ab2063SBarry Smith /* 157817ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 157917ab2063SBarry Smith */ 1580dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 158117ab2063SBarry Smith { 1582416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15836849ba73SBarry Smith PetscErrorCode ierr; 1584d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 158517ab2063SBarry Smith 15863a40ed3dSBarry Smith PetscFunctionBegin; 158709f38230SBarry Smith if (!a->diag) { 1588785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 15893bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 159009f38230SBarry Smith } 1591d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 159209f38230SBarry Smith a->diag[i] = a->i[i+1]; 1593bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1594bfeeae90SHong Zhang if (a->j[j] == i) { 159509f38230SBarry Smith a->diag[i] = j; 159617ab2063SBarry Smith break; 159717ab2063SBarry Smith } 159817ab2063SBarry Smith } 159917ab2063SBarry Smith } 16003a40ed3dSBarry Smith PetscFunctionReturn(0); 160117ab2063SBarry Smith } 160217ab2063SBarry Smith 160361ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 160461ecd0c6SBarry Smith { 160561ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 160661ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 160761ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 160861ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 160961ecd0c6SBarry Smith PetscErrorCode ierr; 161061ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 161161ecd0c6SBarry Smith 161261ecd0c6SBarry Smith PetscFunctionBegin; 161361ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 161461ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 161561ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 161661ecd0c6SBarry Smith PetscFunctionReturn(0); 161761ecd0c6SBarry Smith } 161861ecd0c6SBarry Smith 161961ecd0c6SBarry Smith if (a->diagonaldense) { 162061ecd0c6SBarry Smith cnt = 0; 162161ecd0c6SBarry Smith } else { 162261ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 162361ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 162461ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 162561ecd0c6SBarry Smith cnt++; 162661ecd0c6SBarry Smith mdiag[i] = 1; 162761ecd0c6SBarry Smith } 162861ecd0c6SBarry Smith } 162961ecd0c6SBarry Smith } 163061ecd0c6SBarry Smith if (!cnt) { 163161ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 163261ecd0c6SBarry Smith } else { 1633b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1634b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 163561ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 163661ecd0c6SBarry Smith 163761ecd0c6SBarry Smith a->a = NULL; 163861ecd0c6SBarry Smith a->j = NULL; 163961ecd0c6SBarry Smith a->i = NULL; 164061ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 164161ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 164261ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1643447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 164461ecd0c6SBarry Smith } 164561ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 164661ecd0c6SBarry Smith 164761ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 164861ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 164961ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1650447d62f5SStefano Zampini if (i < A->cmap->n) { 165161ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 165261ecd0c6SBarry Smith } 1653447d62f5SStefano Zampini } 165461ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 165561ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 165661ecd0c6SBarry Smith if (singlemalloc) { 165761ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 165861ecd0c6SBarry Smith } else { 165961ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 166061ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 166161ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 166261ecd0c6SBarry Smith } 166361ecd0c6SBarry Smith } 166461ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 166561ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 166661ecd0c6SBarry Smith PetscFunctionReturn(0); 166761ecd0c6SBarry Smith } 166861ecd0c6SBarry Smith 1669be5855fcSBarry Smith /* 1670be5855fcSBarry Smith Checks for missing diagonals 1671be5855fcSBarry Smith */ 1672ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1673be5855fcSBarry Smith { 1674be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 16757734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1676994fe344SLisandro Dalcin PetscErrorCode ierr; 1677be5855fcSBarry Smith 1678be5855fcSBarry Smith PetscFunctionBegin; 167909f38230SBarry Smith *missing = PETSC_FALSE; 16807734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 168109f38230SBarry Smith *missing = PETSC_TRUE; 168209f38230SBarry Smith if (d) *d = 0; 1683994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 168409f38230SBarry Smith } else { 168501445905SHong Zhang PetscInt n; 168601445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1687f1e2ffcdSBarry Smith diag = a->diag; 168801445905SHong Zhang for (i=0; i<n; i++) { 16897734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 169009f38230SBarry Smith *missing = PETSC_TRUE; 169109f38230SBarry Smith if (d) *d = i; 1692994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1693358d2f5dSShri Abhyankar break; 169409f38230SBarry Smith } 1695be5855fcSBarry Smith } 1696be5855fcSBarry Smith } 1697be5855fcSBarry Smith PetscFunctionReturn(0); 1698be5855fcSBarry Smith } 1699be5855fcSBarry Smith 17000da83c2eSBarry Smith #include <petscblaslapack.h> 17010da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 17020da83c2eSBarry Smith 17030da83c2eSBarry Smith /* 17040da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 17050da83c2eSBarry Smith */ 17060da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 17070da83c2eSBarry Smith { 17080da83c2eSBarry Smith PetscErrorCode ierr; 17090da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 17100da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 17110da83c2eSBarry Smith const PetscReal shift = 0.0; 17120da83c2eSBarry Smith PetscInt ipvt[5]; 17130da83c2eSBarry Smith PetscScalar work[25],*v_work; 17140da83c2eSBarry Smith 17150da83c2eSBarry Smith PetscFunctionBegin; 17160da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 17170da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 17180da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 17190da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 17200da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 17210da83c2eSBarry Smith } 17220da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 17230da83c2eSBarry Smith if (bsizemax > 7) { 17240da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 17250da83c2eSBarry Smith } 17260da83c2eSBarry Smith ncnt = 0; 17270da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 17280da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 17290da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 17300da83c2eSBarry Smith switch (bsizes[i]) { 17310da83c2eSBarry Smith case 1: 17320da83c2eSBarry Smith *diag = 1.0/(*diag); 17330da83c2eSBarry Smith break; 17340da83c2eSBarry Smith case 2: 17350da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17360da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17370da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 17380da83c2eSBarry Smith break; 17390da83c2eSBarry Smith case 3: 17400da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17410da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17420da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 17430da83c2eSBarry Smith break; 17440da83c2eSBarry Smith case 4: 17450da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17460da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17470da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 17480da83c2eSBarry Smith break; 17490da83c2eSBarry Smith case 5: 17500da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17510da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17520da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 17530da83c2eSBarry Smith break; 17540da83c2eSBarry Smith case 6: 17550da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17560da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17570da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 17580da83c2eSBarry Smith break; 17590da83c2eSBarry Smith case 7: 17600da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17610da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17620da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 17630da83c2eSBarry Smith break; 17640da83c2eSBarry Smith default: 17650da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17660da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17670da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 17680da83c2eSBarry Smith } 17690da83c2eSBarry Smith ncnt += bsizes[i]; 17700da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 17710da83c2eSBarry Smith } 17720da83c2eSBarry Smith if (bsizemax > 7) { 17730da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 17740da83c2eSBarry Smith } 17750da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 17760da83c2eSBarry Smith PetscFunctionReturn(0); 17770da83c2eSBarry Smith } 17780da83c2eSBarry Smith 1779422a814eSBarry Smith /* 1780422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1781422a814eSBarry Smith */ 17827087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 178371f1c65dSBarry Smith { 178471f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 178571f1c65dSBarry Smith PetscErrorCode ierr; 1786d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 178754f21887SBarry Smith MatScalar *v = a->a; 178854f21887SBarry Smith PetscScalar *idiag,*mdiag; 178971f1c65dSBarry Smith 179071f1c65dSBarry Smith PetscFunctionBegin; 179171f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 179271f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 179371f1c65dSBarry Smith diag = a->diag; 179471f1c65dSBarry Smith if (!a->idiag) { 1795dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 17963bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 179771f1c65dSBarry Smith v = a->a; 179871f1c65dSBarry Smith } 179971f1c65dSBarry Smith mdiag = a->mdiag; 180071f1c65dSBarry Smith idiag = a->idiag; 180171f1c65dSBarry Smith 1802422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 180371f1c65dSBarry Smith for (i=0; i<m; i++) { 180471f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1805899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1806899639b0SHong Zhang if (PetscRealPart(fshift)) { 1807899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 18087b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18097b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 18107b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1811a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1812899639b0SHong Zhang } 181371f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 181471f1c65dSBarry Smith } 181571f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 181671f1c65dSBarry Smith } else { 181771f1c65dSBarry Smith for (i=0; i<m; i++) { 181871f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 181971f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 182071f1c65dSBarry Smith } 1821dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 182271f1c65dSBarry Smith } 182371f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 182471f1c65dSBarry Smith PetscFunctionReturn(0); 182571f1c65dSBarry Smith } 182671f1c65dSBarry Smith 1827c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 182841f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 182917ab2063SBarry Smith { 1830416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1831e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 18323d3eaba7SBarry Smith const MatScalar *v,*idiag=0,*mdiag; 183354f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1834dfbe8321SBarry Smith PetscErrorCode ierr; 18353d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 183697f1f81fSBarry Smith const PetscInt *idx,*diag; 183717ab2063SBarry Smith 18383a40ed3dSBarry Smith PetscFunctionBegin; 1839b965ef7fSBarry Smith its = its*lits; 184091723122SBarry Smith 184171f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 184271f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 184371f1c65dSBarry Smith a->fshift = fshift; 184471f1c65dSBarry Smith a->omega = omega; 1845ed480e8bSBarry Smith 184671f1c65dSBarry Smith diag = a->diag; 184771f1c65dSBarry Smith t = a->ssor_work; 1848ed480e8bSBarry Smith idiag = a->idiag; 184971f1c65dSBarry Smith mdiag = a->mdiag; 1850ed480e8bSBarry Smith 18511ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 18523649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1853ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 185417ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 185517ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1856ed480e8bSBarry Smith bs = b; 185717ab2063SBarry Smith for (i=0; i<m; i++) { 185871f1c65dSBarry Smith d = fshift + mdiag[i]; 1859416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1860ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1861ed480e8bSBarry Smith v = a->a + diag[i] + 1; 186217ab2063SBarry Smith sum = b[i]*d/omega; 1863003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 186417ab2063SBarry Smith x[i] = sum; 186517ab2063SBarry Smith } 18661ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 18673649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1868efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 18693a40ed3dSBarry Smith PetscFunctionReturn(0); 187017ab2063SBarry Smith } 1871c783ea89SBarry Smith 18722205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 18732205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 18744c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 1875887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 187617ab2063SBarry Smith 187717ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 187817ab2063SBarry Smith 1879887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 188017ab2063SBarry Smith */ 188117ab2063SBarry Smith scale = (2.0/omega) - 1.0; 188217ab2063SBarry Smith 188317ab2063SBarry Smith /* x = (E + U)^{-1} b */ 188417ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1885416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1886ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1887ed480e8bSBarry Smith v = a->a + diag[i] + 1; 188817ab2063SBarry Smith sum = b[i]; 1889e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1890ed480e8bSBarry Smith x[i] = sum*idiag[i]; 189117ab2063SBarry Smith } 189217ab2063SBarry Smith 189317ab2063SBarry Smith /* t = b - (2*E - D)x */ 1894416022c9SBarry Smith v = a->a; 18952205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 189617ab2063SBarry Smith 189717ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1898ed480e8bSBarry Smith ts = t; 1899416022c9SBarry Smith diag = a->diag; 190017ab2063SBarry Smith for (i=0; i<m; i++) { 1901416022c9SBarry Smith n = diag[i] - a->i[i]; 1902ed480e8bSBarry Smith idx = a->j + a->i[i]; 1903ed480e8bSBarry Smith v = a->a + a->i[i]; 190417ab2063SBarry Smith sum = t[i]; 1905003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1906ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1907733d66baSBarry Smith /* x = x + t */ 1908733d66baSBarry Smith x[i] += t[i]; 190917ab2063SBarry Smith } 191017ab2063SBarry Smith 1911dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 19121ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 19133649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 19143a40ed3dSBarry Smith PetscFunctionReturn(0); 191517ab2063SBarry Smith } 191617ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 191717ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 191817ab2063SBarry Smith for (i=0; i<m; i++) { 1919416022c9SBarry Smith n = diag[i] - a->i[i]; 1920ed480e8bSBarry Smith idx = a->j + a->i[i]; 1921ed480e8bSBarry Smith v = a->a + a->i[i]; 192217ab2063SBarry Smith sum = b[i]; 1923e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 19245c99c7daSBarry Smith t[i] = sum; 1925ed480e8bSBarry Smith x[i] = sum*idiag[i]; 192617ab2063SBarry Smith } 19275c99c7daSBarry Smith xb = t; 1928efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 19293a40ed3dSBarry Smith } else xb = b; 193017ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 193117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1932416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1933ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1934ed480e8bSBarry Smith v = a->a + diag[i] + 1; 193517ab2063SBarry Smith sum = xb[i]; 1936e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 19375c99c7daSBarry Smith if (xb == b) { 1938ed480e8bSBarry Smith x[i] = sum*idiag[i]; 19395c99c7daSBarry Smith } else { 1940b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 194117ab2063SBarry Smith } 19425c99c7daSBarry Smith } 1943b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 194417ab2063SBarry Smith } 194517ab2063SBarry Smith its--; 194617ab2063SBarry Smith } 194717ab2063SBarry Smith while (its--) { 194817ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 194917ab2063SBarry Smith for (i=0; i<m; i++) { 1950b19a5dc2SMark Adams /* lower */ 1951b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1952ed480e8bSBarry Smith idx = a->j + a->i[i]; 1953ed480e8bSBarry Smith v = a->a + a->i[i]; 195417ab2063SBarry Smith sum = b[i]; 1955e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1956b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1957b19a5dc2SMark Adams /* upper */ 1958b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1959b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1960b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1961b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1962b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 196317ab2063SBarry Smith } 1964b19a5dc2SMark Adams xb = t; 19659f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1966b19a5dc2SMark Adams } else xb = b; 196717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 196817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1969b19a5dc2SMark Adams sum = xb[i]; 1970b19a5dc2SMark Adams if (xb == b) { 1971b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1972416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1973ed480e8bSBarry Smith idx = a->j + a->i[i]; 1974ed480e8bSBarry Smith v = a->a + a->i[i]; 1975e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1976ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1977b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1978b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1979b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1980b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1981b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1982b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 198317ab2063SBarry Smith } 1984b19a5dc2SMark Adams } 1985b19a5dc2SMark Adams if (xb == b) { 19869f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1987b19a5dc2SMark Adams } else { 1988b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1989b19a5dc2SMark Adams } 199017ab2063SBarry Smith } 199117ab2063SBarry Smith } 19921ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 19933649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1994365a8a9eSBarry Smith PetscFunctionReturn(0); 199517ab2063SBarry Smith } 199617ab2063SBarry Smith 19972af78befSBarry Smith 1998dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 199917ab2063SBarry Smith { 2000416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20014e220ebcSLois Curfman McInnes 20023a40ed3dSBarry Smith PetscFunctionBegin; 20034e220ebcSLois Curfman McInnes info->block_size = 1.0; 20043966268fSBarry Smith info->nz_allocated = a->maxnz; 20053966268fSBarry Smith info->nz_used = a->nz; 20063966268fSBarry Smith info->nz_unneeded = (a->maxnz - a->nz); 20073966268fSBarry Smith info->assemblies = A->num_ass; 20083966268fSBarry Smith info->mallocs = A->info.mallocs; 20097adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2010d5f3da31SBarry Smith if (A->factortype) { 20114e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 20124e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 20134e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 20144e220ebcSLois Curfman McInnes } else { 20154e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 20164e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 20174e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 20184e220ebcSLois Curfman McInnes } 20193a40ed3dSBarry Smith PetscFunctionReturn(0); 202017ab2063SBarry Smith } 202117ab2063SBarry Smith 20222b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 202317ab2063SBarry Smith { 2024416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2025c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 20266849ba73SBarry Smith PetscErrorCode ierr; 202797b48c8fSBarry Smith const PetscScalar *xx; 202897b48c8fSBarry Smith PetscScalar *bb; 2029c7da8527SEric Chamberland PetscInt d = 0; 203017ab2063SBarry Smith 20313a40ed3dSBarry Smith PetscFunctionBegin; 203297b48c8fSBarry Smith if (x && b) { 203397b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 203497b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 203597b48c8fSBarry Smith for (i=0; i<N; i++) { 203697b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2037447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 203897b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 203997b48c8fSBarry Smith } 204097b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 204197b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 204297b48c8fSBarry Smith } 204397b48c8fSBarry Smith 2044a9817697SBarry Smith if (a->keepnonzeropattern) { 2045f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2046e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2047580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2048f1e2ffcdSBarry Smith } 2049f4df32b1SMatthew Knepley if (diag != 0.0) { 2050c7da8527SEric Chamberland for (i=0; i<N; i++) { 2051c7da8527SEric Chamberland d = rows[i]; 2052447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2053c7da8527SEric Chamberland if (a->diag[d] >= a->i[d+1]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in the zeroed row %D",d); 2054c7da8527SEric Chamberland } 2055f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2056447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2057f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 2058f1e2ffcdSBarry Smith } 2059f1e2ffcdSBarry Smith } 2060f1e2ffcdSBarry Smith } else { 2061f4df32b1SMatthew Knepley if (diag != 0.0) { 206217ab2063SBarry Smith for (i=0; i<N; i++) { 2063e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 20647ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2065447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2066447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2067447d62f5SStefano Zampini } else { 2068416022c9SBarry Smith a->ilen[rows[i]] = 1; 2069f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 2070bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2071447d62f5SStefano Zampini } 2072447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2073f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 207417ab2063SBarry Smith } 207517ab2063SBarry Smith } 20763a40ed3dSBarry Smith } else { 207717ab2063SBarry Smith for (i=0; i<N; i++) { 2078e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2079416022c9SBarry Smith a->ilen[rows[i]] = 0; 208017ab2063SBarry Smith } 208117ab2063SBarry Smith } 2082e56f5c9eSBarry Smith A->nonzerostate++; 2083f1e2ffcdSBarry Smith } 2084e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2085c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2086e2cf4d64SStefano Zampini #endif 20874099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20883a40ed3dSBarry Smith PetscFunctionReturn(0); 208917ab2063SBarry Smith } 209017ab2063SBarry Smith 20916e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 20926e169961SBarry Smith { 20936e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20946e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 20956e169961SBarry Smith PetscErrorCode ierr; 20962b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 20976e169961SBarry Smith const PetscScalar *xx; 20986e169961SBarry Smith PetscScalar *bb; 20996e169961SBarry Smith 21006e169961SBarry Smith PetscFunctionBegin; 21016e169961SBarry Smith if (x && b) { 21026e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 21036e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 21042b40b63fSBarry Smith vecs = PETSC_TRUE; 21056e169961SBarry Smith } 21061795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 21076e169961SBarry Smith for (i=0; i<N; i++) { 21086e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2109580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 21102205254eSKarl Rupp 21116e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 21126e169961SBarry Smith } 21136e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 21146e169961SBarry Smith if (!zeroed[i]) { 21156e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 21164cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 21172b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 21186e169961SBarry Smith a->a[j] = 0.0; 21196e169961SBarry Smith } 21206e169961SBarry Smith } 21214cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 21226e169961SBarry Smith } 21236e169961SBarry Smith if (x && b) { 21246e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 21256e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 21266e169961SBarry Smith } 21276e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 21286e169961SBarry Smith if (diag != 0.0) { 21296e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 21301d5a398dSstefano_zampini if (missing) { 21311d5a398dSstefano_zampini for (i=0; i<N; i++) { 21324cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 21334cf107fdSStefano Zampini if (a->nonew && rows[i] >= d) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D (%D)",d,rows[i]); 21341d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 21351d5a398dSstefano_zampini } 21361d5a398dSstefano_zampini } else { 21376e169961SBarry Smith for (i=0; i<N; i++) { 21386e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 21396e169961SBarry Smith } 21406e169961SBarry Smith } 21411d5a398dSstefano_zampini } 2142e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2143c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2144e2cf4d64SStefano Zampini #endif 21454099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21466e169961SBarry Smith PetscFunctionReturn(0); 21476e169961SBarry Smith } 21486e169961SBarry Smith 2149a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 215017ab2063SBarry Smith { 2151416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 215297f1f81fSBarry Smith PetscInt *itmp; 215317ab2063SBarry Smith 21543a40ed3dSBarry Smith PetscFunctionBegin; 2155e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 215617ab2063SBarry Smith 2157416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 2158bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 215917ab2063SBarry Smith if (idx) { 2160bfeeae90SHong Zhang itmp = a->j + a->i[row]; 216126fbe8dcSKarl Rupp if (*nz) *idx = itmp; 216217ab2063SBarry Smith else *idx = 0; 216317ab2063SBarry Smith } 21643a40ed3dSBarry Smith PetscFunctionReturn(0); 216517ab2063SBarry Smith } 216617ab2063SBarry Smith 2167bfeeae90SHong Zhang /* remove this function? */ 2168a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 216917ab2063SBarry Smith { 21703a40ed3dSBarry Smith PetscFunctionBegin; 21713a40ed3dSBarry Smith PetscFunctionReturn(0); 217217ab2063SBarry Smith } 217317ab2063SBarry Smith 2174dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 217517ab2063SBarry Smith { 2176416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 217754f21887SBarry Smith MatScalar *v = a->a; 217836db0b34SBarry Smith PetscReal sum = 0.0; 21796849ba73SBarry Smith PetscErrorCode ierr; 218097f1f81fSBarry Smith PetscInt i,j; 218117ab2063SBarry Smith 21823a40ed3dSBarry Smith PetscFunctionBegin; 218317ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2184570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2185570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 2186570b7f6dSBarry Smith *nrm = BLASnrm2_(&nz,v,&one); 2187570b7f6dSBarry Smith #else 2188416022c9SBarry Smith for (i=0; i<a->nz; i++) { 218936db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 219017ab2063SBarry Smith } 21918f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2192570b7f6dSBarry Smith #endif 219351f70360SJed Brown ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 21943a40ed3dSBarry Smith } else if (type == NORM_1) { 219536db0b34SBarry Smith PetscReal *tmp; 219697f1f81fSBarry Smith PetscInt *jj = a->j; 21971795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2198064f8208SBarry Smith *nrm = 0.0; 2199416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2200bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 220117ab2063SBarry Smith } 2202d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2203064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 220417ab2063SBarry Smith } 2205606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 220651f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 22073a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2208064f8208SBarry Smith *nrm = 0.0; 2209d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 2210bfeeae90SHong Zhang v = a->a + a->i[j]; 221117ab2063SBarry Smith sum = 0.0; 2212416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 2213cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 221417ab2063SBarry Smith } 2215064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 221617ab2063SBarry Smith } 221751f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2218f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 22193a40ed3dSBarry Smith PetscFunctionReturn(0); 222017ab2063SBarry Smith } 222117ab2063SBarry Smith 22224e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 22234e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 22244e938277SHong Zhang { 22254e938277SHong Zhang PetscErrorCode ierr; 22264e938277SHong Zhang PetscInt i,j,anzj; 22274e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 22284e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 22294e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 22304e938277SHong Zhang 22314e938277SHong Zhang PetscFunctionBegin; 22324e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2233854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2234785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2235785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 22364e938277SHong Zhang 22374e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 22384e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 223926fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 22404e938277SHong Zhang /* Form ati for csr format of A^T. */ 224126fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 22424e938277SHong Zhang 22434e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2244580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 22454e938277SHong Zhang 22464e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 22474e938277SHong Zhang for (i=0;i<am;i++) { 22484e938277SHong Zhang anzj = ai[i+1] - ai[i]; 22494e938277SHong Zhang for (j=0;j<anzj;j++) { 22504e938277SHong Zhang atj[atfill[*aj]] = i; 22514e938277SHong Zhang atfill[*aj++] += 1; 22524e938277SHong Zhang } 22534e938277SHong Zhang } 22544e938277SHong Zhang 22554e938277SHong Zhang /* Clean up temporary space and complete requests. */ 22564e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2257ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 225833d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2259b5bb3eecSMark Adams ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2260a2f3521dSMark F. Adams 22614e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 22624e938277SHong Zhang b->free_a = PETSC_FALSE; 22634e938277SHong Zhang b->free_ij = PETSC_TRUE; 22644e938277SHong Zhang b->nonew = 0; 22654e938277SHong Zhang PetscFunctionReturn(0); 22664e938277SHong Zhang } 22674e938277SHong Zhang 22687087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2269cd0d46ebSvictorle { 22703d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 227154f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 227254f21887SBarry Smith MatScalar *va,*vb; 22736849ba73SBarry Smith PetscErrorCode ierr; 227497f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2275cd0d46ebSvictorle 2276cd0d46ebSvictorle PetscFunctionBegin; 2277cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2278cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 22795485867bSBarry Smith if (ma!=nb || na!=mb) { 22805485867bSBarry Smith *f = PETSC_FALSE; 22815485867bSBarry Smith PetscFunctionReturn(0); 22825485867bSBarry Smith } 2283cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2284cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2285cd0d46ebSvictorle va = aij->a; vb = bij->a; 2286785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2287785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2288cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2289cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2290cd0d46ebSvictorle 2291cd0d46ebSvictorle *f = PETSC_TRUE; 2292cd0d46ebSvictorle for (i=0; i<ma; i++) { 2293cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 229497f1f81fSBarry Smith PetscInt idc,idr; 22955485867bSBarry Smith PetscScalar vc,vr; 2296cd0d46ebSvictorle /* column/row index/value */ 22975485867bSBarry Smith idc = adx[aptr[i]]; 22985485867bSBarry Smith idr = bdx[bptr[idc]]; 22995485867bSBarry Smith vc = va[aptr[i]]; 23005485867bSBarry Smith vr = vb[bptr[idc]]; 23015485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 23025485867bSBarry Smith *f = PETSC_FALSE; 23035485867bSBarry Smith goto done; 2304cd0d46ebSvictorle } else { 23055485867bSBarry Smith aptr[i]++; 23065485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2307cd0d46ebSvictorle } 2308cd0d46ebSvictorle } 2309cd0d46ebSvictorle } 2310cd0d46ebSvictorle done: 2311cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 23123aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2313cd0d46ebSvictorle PetscFunctionReturn(0); 2314cd0d46ebSvictorle } 2315cd0d46ebSvictorle 23167087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 23171cbb95d3SBarry Smith { 23183d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 231954f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 232054f21887SBarry Smith MatScalar *va,*vb; 23211cbb95d3SBarry Smith PetscErrorCode ierr; 23221cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 23231cbb95d3SBarry Smith 23241cbb95d3SBarry Smith PetscFunctionBegin; 23251cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 23261cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 23271cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 23281cbb95d3SBarry Smith *f = PETSC_FALSE; 23291cbb95d3SBarry Smith PetscFunctionReturn(0); 23301cbb95d3SBarry Smith } 23311cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 23321cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 23331cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2334785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2335785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 23361cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 23371cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 23381cbb95d3SBarry Smith 23391cbb95d3SBarry Smith *f = PETSC_TRUE; 23401cbb95d3SBarry Smith for (i=0; i<ma; i++) { 23411cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 23421cbb95d3SBarry Smith PetscInt idc,idr; 23431cbb95d3SBarry Smith PetscScalar vc,vr; 23441cbb95d3SBarry Smith /* column/row index/value */ 23451cbb95d3SBarry Smith idc = adx[aptr[i]]; 23461cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 23471cbb95d3SBarry Smith vc = va[aptr[i]]; 23481cbb95d3SBarry Smith vr = vb[bptr[idc]]; 23491cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 23501cbb95d3SBarry Smith *f = PETSC_FALSE; 23511cbb95d3SBarry Smith goto done; 23521cbb95d3SBarry Smith } else { 23531cbb95d3SBarry Smith aptr[i]++; 23541cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 23551cbb95d3SBarry Smith } 23561cbb95d3SBarry Smith } 23571cbb95d3SBarry Smith } 23581cbb95d3SBarry Smith done: 23591cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 23601cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 23611cbb95d3SBarry Smith PetscFunctionReturn(0); 23621cbb95d3SBarry Smith } 23631cbb95d3SBarry Smith 2364ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 23659e29f15eSvictorle { 2366dfbe8321SBarry Smith PetscErrorCode ierr; 23676e111a19SKarl Rupp 23689e29f15eSvictorle PetscFunctionBegin; 23695485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 23709e29f15eSvictorle PetscFunctionReturn(0); 23719e29f15eSvictorle } 23729e29f15eSvictorle 2373ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 23741cbb95d3SBarry Smith { 23751cbb95d3SBarry Smith PetscErrorCode ierr; 23766e111a19SKarl Rupp 23771cbb95d3SBarry Smith PetscFunctionBegin; 23781cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 23791cbb95d3SBarry Smith PetscFunctionReturn(0); 23801cbb95d3SBarry Smith } 23811cbb95d3SBarry Smith 2382dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 238317ab2063SBarry Smith { 2384416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2385fff8e43fSBarry Smith const PetscScalar *l,*r; 2386fff8e43fSBarry Smith PetscScalar x; 238754f21887SBarry Smith MatScalar *v; 2388dfbe8321SBarry Smith PetscErrorCode ierr; 2389fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2390fff8e43fSBarry Smith const PetscInt *jj; 239117ab2063SBarry Smith 23923a40ed3dSBarry Smith PetscFunctionBegin; 239317ab2063SBarry Smith if (ll) { 23943ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 23953ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2396e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2397e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2398fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 2399416022c9SBarry Smith v = a->a; 240017ab2063SBarry Smith for (i=0; i<m; i++) { 240117ab2063SBarry Smith x = l[i]; 2402416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 24032205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 240417ab2063SBarry Smith } 2405fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2406efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 240717ab2063SBarry Smith } 240817ab2063SBarry Smith if (rr) { 2409e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2410e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2411fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 2412416022c9SBarry Smith v = a->a; jj = a->j; 24132205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 2414fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2415efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 241617ab2063SBarry Smith } 2417acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 2418e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2419c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2420e2cf4d64SStefano Zampini #endif 24213a40ed3dSBarry Smith PetscFunctionReturn(0); 242217ab2063SBarry Smith } 242317ab2063SBarry Smith 24247dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 242517ab2063SBarry Smith { 2426db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 24276849ba73SBarry Smith PetscErrorCode ierr; 2428d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 242997f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 24305d0c19d7SBarry Smith const PetscInt *irow,*icol; 24315d0c19d7SBarry Smith PetscInt nrows,ncols; 243297f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 243354f21887SBarry Smith MatScalar *a_new,*mat_a; 2434416022c9SBarry Smith Mat C; 2435cdc6f3adSToby Isaac PetscBool stride; 243617ab2063SBarry Smith 24373a40ed3dSBarry Smith PetscFunctionBegin; 243899141d43SSatish Balay 243917ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2440b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2441b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 244217ab2063SBarry Smith 2443251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2444ff718158SBarry Smith if (stride) { 2445ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2446ff718158SBarry Smith } else { 2447ff718158SBarry Smith first = 0; 2448ff718158SBarry Smith step = 0; 2449ff718158SBarry Smith } 2450fee21e36SBarry Smith if (stride && step == 1) { 245102834360SBarry Smith /* special case of contiguous rows */ 2452dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 245302834360SBarry Smith /* loop over new rows determining lens and starting points */ 245402834360SBarry Smith for (i=0; i<nrows; i++) { 2455bfeeae90SHong Zhang kstart = ai[irow[i]]; 2456a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2457a91a9bebSLisandro Dalcin starts[i] = kstart; 245802834360SBarry Smith for (k=kstart; k<kend; k++) { 2459bfeeae90SHong Zhang if (aj[k] >= first) { 246002834360SBarry Smith starts[i] = k; 246102834360SBarry Smith break; 246202834360SBarry Smith } 246302834360SBarry Smith } 2464a2744918SBarry Smith sum = 0; 246502834360SBarry Smith while (k < kend) { 2466bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2467a2744918SBarry Smith sum++; 246802834360SBarry Smith } 2469a2744918SBarry Smith lens[i] = sum; 247002834360SBarry Smith } 247102834360SBarry Smith /* create submatrix */ 2472cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 247397f1f81fSBarry Smith PetscInt n_cols,n_rows; 247408480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2475e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2476d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 247708480c60SBarry Smith C = *B; 24783a40ed3dSBarry Smith } else { 24793bef6203SJed Brown PetscInt rbs,cbs; 2480ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2481f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 24823bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 24833bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 24843bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 24857adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2486ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 248708480c60SBarry Smith } 2488db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2489db02288aSLois Curfman McInnes 249002834360SBarry Smith /* loop over rows inserting into submatrix */ 2491db02288aSLois Curfman McInnes a_new = c->a; 2492db02288aSLois Curfman McInnes j_new = c->j; 2493db02288aSLois Curfman McInnes i_new = c->i; 2494bfeeae90SHong Zhang 249502834360SBarry Smith for (i=0; i<nrows; i++) { 2496a2744918SBarry Smith ii = starts[i]; 2497a2744918SBarry Smith lensi = lens[i]; 2498a2744918SBarry Smith for (k=0; k<lensi; k++) { 2499a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 250002834360SBarry Smith } 2501580bdb30SBarry Smith ierr = PetscArraycpy(a_new,a->a + starts[i],lensi);CHKERRQ(ierr); 2502a2744918SBarry Smith a_new += lensi; 2503a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2504a2744918SBarry Smith c->ilen[i] = lensi; 250502834360SBarry Smith } 25060e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 25073a40ed3dSBarry Smith } else { 250802834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 25091795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2510854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 25114dcab191SBarry Smith for (i=0; i<ncols; i++) { 25124dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 25134dcab191SBarry Smith if (icol[i] >= oldcols) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%D] %D <= A->cmap->n %D",i,icol[i],oldcols); 25144dcab191SBarry Smith #endif 25154dcab191SBarry Smith smap[icol[i]] = i+1; 25164dcab191SBarry Smith } 25174dcab191SBarry Smith 251802834360SBarry Smith /* determine lens of each row */ 251902834360SBarry Smith for (i=0; i<nrows; i++) { 2520bfeeae90SHong Zhang kstart = ai[irow[i]]; 252102834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 252202834360SBarry Smith lens[i] = 0; 252302834360SBarry Smith for (k=kstart; k<kend; k++) { 2524bfeeae90SHong Zhang if (smap[aj[k]]) { 252502834360SBarry Smith lens[i]++; 252602834360SBarry Smith } 252702834360SBarry Smith } 252802834360SBarry Smith } 252917ab2063SBarry Smith /* Create and fill new matrix */ 2530a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2531ace3abfcSBarry Smith PetscBool equal; 25320f5bd95cSBarry Smith 253399141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2534e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2535580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2536f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2537580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 253808480c60SBarry Smith C = *B; 25393a40ed3dSBarry Smith } else { 25403bef6203SJed Brown PetscInt rbs,cbs; 2541ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2542f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 25433bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 25443bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 25453bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 25467adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2547ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 254808480c60SBarry Smith } 254999141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 255017ab2063SBarry Smith for (i=0; i<nrows; i++) { 255199141d43SSatish Balay row = irow[i]; 2552bfeeae90SHong Zhang kstart = ai[row]; 255399141d43SSatish Balay kend = kstart + a->ilen[row]; 2554bfeeae90SHong Zhang mat_i = c->i[i]; 255599141d43SSatish Balay mat_j = c->j + mat_i; 255699141d43SSatish Balay mat_a = c->a + mat_i; 255799141d43SSatish Balay mat_ilen = c->ilen + i; 255817ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2559bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2560ed480e8bSBarry Smith *mat_j++ = tcol - 1; 256199141d43SSatish Balay *mat_a++ = a->a[k]; 256299141d43SSatish Balay (*mat_ilen)++; 256399141d43SSatish Balay 256417ab2063SBarry Smith } 256517ab2063SBarry Smith } 256617ab2063SBarry Smith } 256702834360SBarry Smith /* Free work space */ 256802834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2569606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2570606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2571cdc6f3adSToby Isaac /* sort */ 2572cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2573cdc6f3adSToby Isaac PetscInt ilen; 2574cdc6f3adSToby Isaac 2575cdc6f3adSToby Isaac mat_i = c->i[i]; 2576cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2577cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2578cdc6f3adSToby Isaac ilen = c->ilen[i]; 2579390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2580cdc6f3adSToby Isaac } 258102834360SBarry Smith } 2582305c6ccfSStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2583b470e4b4SRichard Tran Mills ierr = MatBindToCPU(C,A->boundtocpu);CHKERRQ(ierr); 2584305c6ccfSStefano Zampini #endif 25856d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 25866d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 258717ab2063SBarry Smith 258817ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2589416022c9SBarry Smith *B = C; 25903a40ed3dSBarry Smith PetscFunctionReturn(0); 259117ab2063SBarry Smith } 259217ab2063SBarry Smith 2593fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 259482d44351SHong Zhang { 259582d44351SHong Zhang PetscErrorCode ierr; 259682d44351SHong Zhang Mat B; 259782d44351SHong Zhang 259882d44351SHong Zhang PetscFunctionBegin; 2599c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 260082d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 260182d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 260233d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 260382d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 260482d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 260582d44351SHong Zhang *subMat = B; 2606c2d650bdSHong Zhang } else { 2607c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2608c2d650bdSHong Zhang } 260982d44351SHong Zhang PetscFunctionReturn(0); 261082d44351SHong Zhang } 261182d44351SHong Zhang 26129a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2613a871dcd8SBarry Smith { 261463b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2615dfbe8321SBarry Smith PetscErrorCode ierr; 261663b91edcSBarry Smith Mat outA; 2617ace3abfcSBarry Smith PetscBool row_identity,col_identity; 261863b91edcSBarry Smith 26193a40ed3dSBarry Smith PetscFunctionBegin; 2620e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 26211df811f5SHong Zhang 2622b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2623b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2624a871dcd8SBarry Smith 262563b91edcSBarry Smith outA = inA; 2626d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2627f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2628f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 26292205254eSKarl Rupp 2630c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 26316bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 26322205254eSKarl Rupp 2633c3122656SLisandro Dalcin a->row = row; 26342205254eSKarl Rupp 2635c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 26366bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 26372205254eSKarl Rupp 2638c3122656SLisandro Dalcin a->col = col; 263963b91edcSBarry Smith 264036db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 26416bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 26424c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 26433bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2644f0ec6fceSSatish Balay 264594a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2646854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 26473bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 264894a9d846SBarry Smith } 264963b91edcSBarry Smith 2650f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2651137fb511SHong Zhang if (row_identity && col_identity) { 2652ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2653137fb511SHong Zhang } else { 2654719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2655137fb511SHong Zhang } 26563a40ed3dSBarry Smith PetscFunctionReturn(0); 2657a871dcd8SBarry Smith } 2658a871dcd8SBarry Smith 2659f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2660f0b747eeSBarry Smith { 2661f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2662f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2663efee365bSSatish Balay PetscErrorCode ierr; 2664c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 26653a40ed3dSBarry Smith 26663a40ed3dSBarry Smith PetscFunctionBegin; 2667c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 26688b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2669efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2670acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 2671e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2672c70f7ee4SJunchao Zhang if (inA->offloadmask != PETSC_OFFLOAD_UNALLOCATED) inA->offloadmask = PETSC_OFFLOAD_CPU; 2673e2cf4d64SStefano Zampini #endif 26743a40ed3dSBarry Smith PetscFunctionReturn(0); 2675f0b747eeSBarry Smith } 2676f0b747eeSBarry Smith 2677f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 267816b64355SHong Zhang { 267916b64355SHong Zhang PetscErrorCode ierr; 268016b64355SHong Zhang PetscInt i; 268116b64355SHong Zhang 268216b64355SHong Zhang PetscFunctionBegin; 268316b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 268416b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 268516b64355SHong Zhang 268616b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 268716b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 268816b64355SHong Zhang } 268916b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 269016b64355SHong Zhang 269116b64355SHong Zhang if (submatj->rbuf1) { 269216b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 269316b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 269416b64355SHong Zhang } 269516b64355SHong Zhang 269616b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 269716b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 269816b64355SHong Zhang } 269916b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 270016b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 270116b64355SHong Zhang } 270216b64355SHong Zhang 270316b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 270416b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 270516b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 270616b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 270716b64355SHong Zhang #else 270816b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 270916b64355SHong Zhang #endif 271016b64355SHong Zhang 271116b64355SHong Zhang if (!submatj->allcolumns) { 271216b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 271316b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 271416b64355SHong Zhang #else 271516b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 271616b64355SHong Zhang #endif 271716b64355SHong Zhang } 271816b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 271916b64355SHong Zhang 272016b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 272116b64355SHong Zhang PetscFunctionReturn(0); 272216b64355SHong Zhang } 272316b64355SHong Zhang 27240fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 272516b64355SHong Zhang { 272616b64355SHong Zhang PetscErrorCode ierr; 272716b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 27285c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 272916b64355SHong Zhang 273016b64355SHong Zhang PetscFunctionBegin; 273134136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2732f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 273316b64355SHong Zhang PetscFunctionReturn(0); 273416b64355SHong Zhang } 273516b64355SHong Zhang 27362d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 27372d033e1fSHong Zhang { 27382d033e1fSHong Zhang PetscErrorCode ierr; 27392d033e1fSHong Zhang PetscInt i; 27400fb991dcSHong Zhang Mat C; 27410fb991dcSHong Zhang Mat_SeqAIJ *c; 27420fb991dcSHong Zhang Mat_SubSppt *submatj; 27432d033e1fSHong Zhang 27442d033e1fSHong Zhang PetscFunctionBegin; 27452d033e1fSHong Zhang for (i=0; i<n; i++) { 27460fb991dcSHong Zhang C = (*mat)[i]; 27470fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 27480fb991dcSHong Zhang submatj = c->submatis1; 27492d033e1fSHong Zhang if (submatj) { 2750682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 275134136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2752f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 275334136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 27542d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 27552d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 27562d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2757682e4c99SStefano Zampini } 27582d033e1fSHong Zhang } else { 27592d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 27602d033e1fSHong Zhang } 27612d033e1fSHong Zhang } 276286e85357SHong Zhang 276363a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 276463a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 276563a75b2aSHong Zhang 27662d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 27672d033e1fSHong Zhang PetscFunctionReturn(0); 27682d033e1fSHong Zhang } 27692d033e1fSHong Zhang 27707dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2771cddf8d76SBarry Smith { 2772dfbe8321SBarry Smith PetscErrorCode ierr; 277397f1f81fSBarry Smith PetscInt i; 2774cddf8d76SBarry Smith 27753a40ed3dSBarry Smith PetscFunctionBegin; 2776cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2777df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2778cddf8d76SBarry Smith } 2779cddf8d76SBarry Smith 2780cddf8d76SBarry Smith for (i=0; i<n; i++) { 27817dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2782cddf8d76SBarry Smith } 27833a40ed3dSBarry Smith PetscFunctionReturn(0); 2784cddf8d76SBarry Smith } 2785cddf8d76SBarry Smith 278697f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 27874dcbc457SBarry Smith { 2788e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 27896849ba73SBarry Smith PetscErrorCode ierr; 27905d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 27915d0c19d7SBarry Smith const PetscInt *idx; 279297f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2793f1af5d2fSBarry Smith PetscBT table; 2794bbd702dbSSatish Balay 27953a40ed3dSBarry Smith PetscFunctionBegin; 2796d0f46423SBarry Smith m = A->rmap->n; 2797e4d965acSSatish Balay ai = a->i; 2798bfeeae90SHong Zhang aj = a->j; 27998a047759SSatish Balay 2800e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 280106763907SSatish Balay 2802854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 280353b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 280406763907SSatish Balay 2805e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2806b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2807e4d965acSSatish Balay isz = 0; 28086831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2809e4d965acSSatish Balay 2810e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 28114dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2812b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2813e4d965acSSatish Balay 2814dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2815e4d965acSSatish Balay for (j=0; j<n; ++j) { 28162205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 28174dcbc457SBarry Smith } 281806763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 28196bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2820e4d965acSSatish Balay 282104a348a9SBarry Smith k = 0; 282204a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 282304a348a9SBarry Smith n = isz; 282406763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2825e4d965acSSatish Balay row = nidx[k]; 2826e4d965acSSatish Balay start = ai[row]; 2827e4d965acSSatish Balay end = ai[row+1]; 282804a348a9SBarry Smith for (l = start; l<end; l++) { 2829efb16452SHong Zhang val = aj[l]; 28302205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2831e4d965acSSatish Balay } 2832e4d965acSSatish Balay } 2833e4d965acSSatish Balay } 283470b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2835e4d965acSSatish Balay } 283694bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2837606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 28383a40ed3dSBarry Smith PetscFunctionReturn(0); 28394dcbc457SBarry Smith } 284017ab2063SBarry Smith 28410513a670SBarry Smith /* -------------------------------------------------------------- */ 2842dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 28430513a670SBarry Smith { 28440513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 28456849ba73SBarry Smith PetscErrorCode ierr; 28463b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 28475d0c19d7SBarry Smith const PetscInt *row,*col; 28485d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 284956cd22aeSBarry Smith IS icolp,irowp; 28500298fd71SBarry Smith PetscInt *cwork = NULL; 28510298fd71SBarry Smith PetscScalar *vwork = NULL; 28520513a670SBarry Smith 28533a40ed3dSBarry Smith PetscFunctionBegin; 28544c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 285556cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 28564c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 285756cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 28580513a670SBarry Smith 28590513a670SBarry Smith /* determine lengths of permuted rows */ 2860854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 28612205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2862ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2863f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 286433d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 28657adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2866ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2867606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 28680513a670SBarry Smith 2869785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 28700513a670SBarry Smith for (i=0; i<m; i++) { 287132ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 28722205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2873cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 287432ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 28750513a670SBarry Smith } 2876606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 28772205254eSKarl Rupp 28783c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 28792205254eSKarl Rupp 28809fe5e383SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2881b470e4b4SRichard Tran Mills ierr = MatBindToCPU(*B,A->boundtocpu);CHKERRQ(ierr); 28829fe5e383SStefano Zampini #endif 28830513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28840513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 288556cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 288656cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 28876bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 28886bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 28896768869dSprj- if (rowp == colp) { 28906768869dSprj- if (A->symmetric) { 28916768869dSprj- ierr = MatSetOption(*B,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 28926768869dSprj- } 28936768869dSprj- if (A->hermitian) { 28946768869dSprj- ierr = MatSetOption(*B,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 28956768869dSprj- } 28966768869dSprj- } 28973a40ed3dSBarry Smith PetscFunctionReturn(0); 28980513a670SBarry Smith } 28990513a670SBarry Smith 2900dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2901cb5b572fSBarry Smith { 2902dfbe8321SBarry Smith PetscErrorCode ierr; 2903cb5b572fSBarry Smith 2904cb5b572fSBarry Smith PetscFunctionBegin; 290533f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 290633f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2907be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2908be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2909be6bf707SBarry Smith 29104d805d7cSStefano Zampini if (a->i[A->rmap->n] != b->i[B->rmap->n]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different %D != %D",a->i[A->rmap->n],b->i[B->rmap->n]); 2911580bdb30SBarry Smith ierr = PetscArraycpy(b->a,a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 2912cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 2913cb5b572fSBarry Smith } else { 2914cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2915cb5b572fSBarry Smith } 2916cb5b572fSBarry Smith PetscFunctionReturn(0); 2917cb5b572fSBarry Smith } 2918cb5b572fSBarry Smith 29194994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2920273d9f13SBarry Smith { 2921dfbe8321SBarry Smith PetscErrorCode ierr; 2922273d9f13SBarry Smith 2923273d9f13SBarry Smith PetscFunctionBegin; 2924ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2925273d9f13SBarry Smith PetscFunctionReturn(0); 2926273d9f13SBarry Smith } 2927273d9f13SBarry Smith 2928f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 29296c0721eeSBarry Smith { 29306c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29316e111a19SKarl Rupp 29326c0721eeSBarry Smith PetscFunctionBegin; 29336c0721eeSBarry Smith *array = a->a; 29346c0721eeSBarry Smith PetscFunctionReturn(0); 29356c0721eeSBarry Smith } 29366c0721eeSBarry Smith 2937f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 29386c0721eeSBarry Smith { 29396c0721eeSBarry Smith PetscFunctionBegin; 2940f38c1e66SStefano Zampini *array = NULL; 29416c0721eeSBarry Smith PetscFunctionReturn(0); 29426c0721eeSBarry Smith } 2943273d9f13SBarry Smith 29448229c054SShri Abhyankar /* 29458229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 29468229c054SShri Abhyankar have different nonzero structure. 29478229c054SShri Abhyankar */ 2948b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 2949ec7775f6SShri Abhyankar { 2950b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 2951ec7775f6SShri Abhyankar 2952ec7775f6SShri Abhyankar PetscFunctionBegin; 2953ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2954ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 2955b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 2956b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 2957b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 29588af7cee1SJed Brown nnz[i] = 0; 29598af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 2960b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 2961b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 29628af7cee1SJed Brown nnz[i]++; 29638af7cee1SJed Brown } 29648af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2965ec7775f6SShri Abhyankar } 2966ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2967ec7775f6SShri Abhyankar } 2968ec7775f6SShri Abhyankar 2969b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2970b264fe52SHong Zhang { 2971b264fe52SHong Zhang PetscInt m = Y->rmap->N; 2972b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2973b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2974b264fe52SHong Zhang PetscErrorCode ierr; 2975b264fe52SHong Zhang 2976b264fe52SHong Zhang PetscFunctionBegin; 2977b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 2978b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 2979b264fe52SHong Zhang PetscFunctionReturn(0); 2980b264fe52SHong Zhang } 2981b264fe52SHong Zhang 2982f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2983ac90fabeSBarry Smith { 2984dfbe8321SBarry Smith PetscErrorCode ierr; 2985ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2986c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2987ac90fabeSBarry Smith 2988ac90fabeSBarry Smith PetscFunctionBegin; 2989c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2990ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2991f4df32b1SMatthew Knepley PetscScalar alpha = a; 29928b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2993acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2994a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 2995e2cf4d64SStefano Zampini /* the MatAXPY_Basic* subroutines calls MatAssembly, so the matrix on the GPU 2996e2cf4d64SStefano Zampini will be updated */ 2997e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2998c70f7ee4SJunchao Zhang if (Y->offloadmask != PETSC_OFFLOAD_UNALLOCATED) { 2999c70f7ee4SJunchao Zhang Y->offloadmask = PETSC_OFFLOAD_CPU; 3000e2cf4d64SStefano Zampini } 3001e2cf4d64SStefano Zampini #endif 3002ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 3003ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 3004ac90fabeSBarry Smith } else { 30058229c054SShri Abhyankar Mat B; 30068229c054SShri Abhyankar PetscInt *nnz; 3007785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 3008ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 3009bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 30104aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 301133d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr); 3012176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 30138229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 3014ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 3015ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 301628be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 30178229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 3018ac90fabeSBarry Smith } 3019ac90fabeSBarry Smith PetscFunctionReturn(0); 3020ac90fabeSBarry Smith } 3021ac90fabeSBarry Smith 30227087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3023354c94deSBarry Smith { 3024354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3025354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3026354c94deSBarry Smith PetscInt i,nz; 3027354c94deSBarry Smith PetscScalar *a; 3028354c94deSBarry Smith 3029354c94deSBarry Smith PetscFunctionBegin; 3030354c94deSBarry Smith nz = aij->nz; 3031354c94deSBarry Smith a = aij->a; 30322205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 3033e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 3034c70f7ee4SJunchao Zhang if (mat->offloadmask != PETSC_OFFLOAD_UNALLOCATED) mat->offloadmask = PETSC_OFFLOAD_CPU; 3035e2cf4d64SStefano Zampini #endif 3036354c94deSBarry Smith #else 3037354c94deSBarry Smith PetscFunctionBegin; 3038354c94deSBarry Smith #endif 3039354c94deSBarry Smith PetscFunctionReturn(0); 3040354c94deSBarry Smith } 3041354c94deSBarry Smith 3042985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3043e34fafa9SBarry Smith { 3044e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3045e34fafa9SBarry Smith PetscErrorCode ierr; 3046d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3047e34fafa9SBarry Smith PetscReal atmp; 3048985db425SBarry Smith PetscScalar *x; 3049e34fafa9SBarry Smith MatScalar *aa; 3050e34fafa9SBarry Smith 3051e34fafa9SBarry Smith PetscFunctionBegin; 3052e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3053e34fafa9SBarry Smith aa = a->a; 3054e34fafa9SBarry Smith ai = a->i; 3055e34fafa9SBarry Smith aj = a->j; 3056e34fafa9SBarry Smith 3057985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3058e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3059e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3060e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3061e34fafa9SBarry Smith for (i=0; i<m; i++) { 3062e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 30639189402eSHong Zhang x[i] = 0.0; 3064e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3065985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3066985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3067985db425SBarry Smith aa++; aj++; 3068985db425SBarry Smith } 3069985db425SBarry Smith } 3070985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3071985db425SBarry Smith PetscFunctionReturn(0); 3072985db425SBarry Smith } 3073985db425SBarry Smith 3074985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3075985db425SBarry Smith { 3076985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3077985db425SBarry Smith PetscErrorCode ierr; 3078d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3079985db425SBarry Smith PetscScalar *x; 3080985db425SBarry Smith MatScalar *aa; 3081985db425SBarry Smith 3082985db425SBarry Smith PetscFunctionBegin; 3083e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3084985db425SBarry Smith aa = a->a; 3085985db425SBarry Smith ai = a->i; 3086985db425SBarry Smith aj = a->j; 3087985db425SBarry Smith 3088985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3089985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3090985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3091e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3092985db425SBarry Smith for (i=0; i<m; i++) { 3093985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3094d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3095985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3096985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3097985db425SBarry Smith x[i] = 0.0; 3098985db425SBarry Smith if (idx) { 3099985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3100985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 3101985db425SBarry Smith if (aj[j] > j) { 3102985db425SBarry Smith idx[i] = j; 3103985db425SBarry Smith break; 3104985db425SBarry Smith } 3105985db425SBarry Smith } 3106985db425SBarry Smith } 3107985db425SBarry Smith } 3108985db425SBarry Smith for (j=0; j<ncols; j++) { 3109985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3110985db425SBarry Smith aa++; aj++; 3111985db425SBarry Smith } 3112985db425SBarry Smith } 3113985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3114985db425SBarry Smith PetscFunctionReturn(0); 3115985db425SBarry Smith } 3116985db425SBarry Smith 3117c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3118c87e5d42SMatthew Knepley { 3119c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3120c87e5d42SMatthew Knepley PetscErrorCode ierr; 3121c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3122c87e5d42SMatthew Knepley PetscReal atmp; 3123c87e5d42SMatthew Knepley PetscScalar *x; 3124c87e5d42SMatthew Knepley MatScalar *aa; 3125c87e5d42SMatthew Knepley 3126c87e5d42SMatthew Knepley PetscFunctionBegin; 3127e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3128c87e5d42SMatthew Knepley aa = a->a; 3129c87e5d42SMatthew Knepley ai = a->i; 3130c87e5d42SMatthew Knepley aj = a->j; 3131c87e5d42SMatthew Knepley 3132c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3133c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3134c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 313560e0710aSBarry Smith if (n != A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %D vs. %D rows", A->rmap->n, n); 3136c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3137c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3138289a08f5SMatthew Knepley if (ncols) { 3139289a08f5SMatthew Knepley /* Get first nonzero */ 3140289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 3141289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 31422205254eSKarl Rupp if (atmp > 1.0e-12) { 31432205254eSKarl Rupp x[i] = atmp; 31442205254eSKarl Rupp if (idx) idx[i] = aj[j]; 31452205254eSKarl Rupp break; 31462205254eSKarl Rupp } 3147289a08f5SMatthew Knepley } 314812431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 3149289a08f5SMatthew Knepley } else { 3150289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 3151289a08f5SMatthew Knepley } 3152c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 3153c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 3154289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3155c87e5d42SMatthew Knepley aa++; aj++; 3156c87e5d42SMatthew Knepley } 3157c87e5d42SMatthew Knepley } 3158c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3159c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3160c87e5d42SMatthew Knepley } 3161c87e5d42SMatthew Knepley 3162985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3163985db425SBarry Smith { 3164985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3165985db425SBarry Smith PetscErrorCode ierr; 3166d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3167d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3168985db425SBarry Smith PetscScalar *x; 3169d9ca1df4SBarry Smith const MatScalar *aa; 3170985db425SBarry Smith 3171985db425SBarry Smith PetscFunctionBegin; 3172e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3173985db425SBarry Smith aa = a->a; 3174985db425SBarry Smith ai = a->i; 3175985db425SBarry Smith aj = a->j; 3176985db425SBarry Smith 3177985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3178985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3179985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3180e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3181985db425SBarry Smith for (i=0; i<m; i++) { 3182985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3183d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3184985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3185985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3186985db425SBarry Smith x[i] = 0.0; 3187985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3188985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3189985db425SBarry Smith for (j=0; j<ncols; j++) { 3190985db425SBarry Smith if (aj[j] > j) { 3191985db425SBarry Smith idx[i] = j; 3192985db425SBarry Smith break; 3193985db425SBarry Smith } 3194985db425SBarry Smith } 3195985db425SBarry Smith } 3196985db425SBarry Smith } 3197985db425SBarry Smith for (j=0; j<ncols; j++) { 3198985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3199985db425SBarry Smith aa++; aj++; 3200e34fafa9SBarry Smith } 3201e34fafa9SBarry Smith } 3202e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3203e34fafa9SBarry Smith PetscFunctionReturn(0); 3204e34fafa9SBarry Smith } 3205bbead8a2SBarry Smith 3206713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3207bbead8a2SBarry Smith { 3208bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3209bbead8a2SBarry Smith PetscErrorCode ierr; 321033d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3211bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 32120da83c2eSBarry Smith const PetscReal shift = 0.0; 32131a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3214bbead8a2SBarry Smith 3215bbead8a2SBarry Smith PetscFunctionBegin; 3216a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 32174a0d0026SBarry Smith if (a->ibdiagvalid) { 32184a0d0026SBarry Smith if (values) *values = a->ibdiag; 32194a0d0026SBarry Smith PetscFunctionReturn(0); 32204a0d0026SBarry Smith } 3221bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3222bbead8a2SBarry Smith if (!a->ibdiag) { 3223785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 32243bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3225bbead8a2SBarry Smith } 3226bbead8a2SBarry Smith diag = a->ibdiag; 3227bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3228bbead8a2SBarry Smith /* factor and invert each block */ 3229bbead8a2SBarry Smith switch (bs) { 3230bbead8a2SBarry Smith case 1: 3231bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3232bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3233ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3234ec1892c8SHong Zhang if (allowzeropivot) { 32357b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 32367b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 32377b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 32387b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 32397b6c816cSBarry Smith } else SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Zero pivot, row %D pivot %g tolerance %g",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON); 3240ec1892c8SHong Zhang } 3241bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3242bbead8a2SBarry Smith } 3243bbead8a2SBarry Smith break; 3244bbead8a2SBarry Smith case 2: 3245bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3246bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3247bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3248a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32497b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 325096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3251bbead8a2SBarry Smith diag += 4; 3252bbead8a2SBarry Smith } 3253bbead8a2SBarry Smith break; 3254bbead8a2SBarry Smith case 3: 3255bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3256bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3257bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3258a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32597b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 326096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3261bbead8a2SBarry Smith diag += 9; 3262bbead8a2SBarry Smith } 3263bbead8a2SBarry Smith break; 3264bbead8a2SBarry Smith case 4: 3265bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3266bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3267bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3268a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32697b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 327096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3271bbead8a2SBarry Smith diag += 16; 3272bbead8a2SBarry Smith } 3273bbead8a2SBarry Smith break; 3274bbead8a2SBarry Smith case 5: 3275bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3276bbead8a2SBarry Smith ij[0] = 5*i; ij[1] = 5*i + 1; ij[2] = 5*i + 2; ij[3] = 5*i + 3; ij[4] = 5*i + 4; 3277bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3278a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32797b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 328096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3281bbead8a2SBarry Smith diag += 25; 3282bbead8a2SBarry Smith } 3283bbead8a2SBarry Smith break; 3284bbead8a2SBarry Smith case 6: 3285bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3286bbead8a2SBarry Smith ij[0] = 6*i; ij[1] = 6*i + 1; ij[2] = 6*i + 2; ij[3] = 6*i + 3; ij[4] = 6*i + 4; ij[5] = 6*i + 5; 3287bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3288a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32897b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 329096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3291bbead8a2SBarry Smith diag += 36; 3292bbead8a2SBarry Smith } 3293bbead8a2SBarry Smith break; 3294bbead8a2SBarry Smith case 7: 3295bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3296bbead8a2SBarry Smith ij[0] = 7*i; ij[1] = 7*i + 1; ij[2] = 7*i + 2; ij[3] = 7*i + 3; ij[4] = 7*i + 4; ij[5] = 7*i + 5; ij[5] = 7*i + 6; 3297bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3298a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32997b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 330096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3301bbead8a2SBarry Smith diag += 49; 3302bbead8a2SBarry Smith } 3303bbead8a2SBarry Smith break; 3304bbead8a2SBarry Smith default: 3305dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3306bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3307bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3308bbead8a2SBarry Smith IJ[j] = bs*i + j; 3309bbead8a2SBarry Smith } 3310bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 33115f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 33127b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 331396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3314bbead8a2SBarry Smith diag += bs2; 3315bbead8a2SBarry Smith } 3316bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3317bbead8a2SBarry Smith } 3318bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3319bbead8a2SBarry Smith PetscFunctionReturn(0); 3320bbead8a2SBarry Smith } 3321bbead8a2SBarry Smith 332273a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 332373a71a0fSBarry Smith { 332473a71a0fSBarry Smith PetscErrorCode ierr; 332573a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 332673a71a0fSBarry Smith PetscScalar a; 332773a71a0fSBarry Smith PetscInt m,n,i,j,col; 332873a71a0fSBarry Smith 332973a71a0fSBarry Smith PetscFunctionBegin; 333073a71a0fSBarry Smith if (!x->assembled) { 333173a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 333273a71a0fSBarry Smith for (i=0; i<m; i++) { 333373a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 333473a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 333573a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 333673a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 333773a71a0fSBarry Smith } 333873a71a0fSBarry Smith } 3339e2ce353bSJunchao Zhang } else { 3340e2ce353bSJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aij->a+i);CHKERRQ(ierr);} 3341e2ce353bSJunchao Zhang } 334273a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 334373a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 334473a71a0fSBarry Smith PetscFunctionReturn(0); 334573a71a0fSBarry Smith } 334673a71a0fSBarry Smith 3347679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3348679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3349679944adSJunchao Zhang { 3350679944adSJunchao Zhang PetscErrorCode ierr; 3351679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3352679944adSJunchao Zhang PetscScalar a; 3353679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3354679944adSJunchao Zhang 3355679944adSJunchao Zhang PetscFunctionBegin; 3356679944adSJunchao Zhang nskip = high - low; 3357679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3358679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3359679944adSJunchao Zhang for (i=0; i<m; i++) { 3360679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3361679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3362679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3363679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3364679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3365679944adSJunchao Zhang } 3366e2ce353bSJunchao Zhang } 3367679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3368679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3369679944adSJunchao Zhang PetscFunctionReturn(0); 3370679944adSJunchao Zhang } 3371679944adSJunchao Zhang 3372679944adSJunchao Zhang 3373682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 33740a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3375cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3376cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3377cb5b572fSBarry Smith MatMult_SeqAIJ, 337897304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 33797c922b88SBarry Smith MatMultTranspose_SeqAIJ, 33807c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3381db4efbfdSBarry Smith 0, 3382db4efbfdSBarry Smith 0, 3383db4efbfdSBarry Smith 0, 3384db4efbfdSBarry Smith /* 10*/ 0, 3385cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3386cb5b572fSBarry Smith 0, 338741f059aeSBarry Smith MatSOR_SeqAIJ, 338891e9d3e2SHong Zhang MatTranspose_SeqAIJ, 338997304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3390cb5b572fSBarry Smith MatEqual_SeqAIJ, 3391cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3392cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3393cb5b572fSBarry Smith MatNorm_SeqAIJ, 339497304618SKris Buschelman /* 20*/ 0, 3395cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3396cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3397cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3398d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3399db4efbfdSBarry Smith 0, 3400db4efbfdSBarry Smith 0, 3401db4efbfdSBarry Smith 0, 3402db4efbfdSBarry Smith 0, 34034994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3404db4efbfdSBarry Smith 0, 3405db4efbfdSBarry Smith 0, 34068c778c55SBarry Smith 0, 34078c778c55SBarry Smith 0, 3408d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3409cb5b572fSBarry Smith 0, 3410cb5b572fSBarry Smith 0, 3411cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3412cb5b572fSBarry Smith 0, 3413d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 34147dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3415cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3416cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3417cb5b572fSBarry Smith MatCopy_SeqAIJ, 3418d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3419cb5b572fSBarry Smith MatScale_SeqAIJ, 34207d68702bSBarry Smith MatShift_SeqAIJ, 342179299369SBarry Smith MatDiagonalSet_SeqAIJ, 34226e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 342373a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 34243b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 34253b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 34263b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3427a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 342893dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3429b9617806SBarry Smith 0, 34300513a670SBarry Smith 0, 3431cda55fadSBarry Smith MatPermute_SeqAIJ, 3432cda55fadSBarry Smith 0, 3433d519adbfSMatthew Knepley /* 59*/ 0, 3434b9b97703SBarry Smith MatDestroy_SeqAIJ, 3435b9b97703SBarry Smith MatView_SeqAIJ, 3436357abbc8SBarry Smith 0, 3437*4222ddf1SHong Zhang 0, 3438*4222ddf1SHong Zhang /* 64*/ 0, 3439321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3440ee4f033dSBarry Smith 0, 3441ee4f033dSBarry Smith 0, 3442ee4f033dSBarry Smith 0, 3443d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3444c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3445ee4f033dSBarry Smith 0, 3446dcf5cc72SBarry Smith 0, 34472c93a97aSBarry Smith 0, 34482c93a97aSBarry Smith /* 74*/ 0, 34493acb8795SBarry Smith MatFDColoringApply_AIJ, 345097304618SKris Buschelman 0, 345197304618SKris Buschelman 0, 345297304618SKris Buschelman 0, 34536ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 345497304618SKris Buschelman 0, 345597304618SKris Buschelman 0, 345697304618SKris Buschelman 0, 3457bc011b1eSHong Zhang MatLoad_SeqAIJ, 3458d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 34591cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 34606284ec50SHong Zhang 0, 34616284ec50SHong Zhang 0, 3462bc011b1eSHong Zhang 0, 3463*4222ddf1SHong Zhang /* 89*/ 0, 3464*4222ddf1SHong Zhang 0, 346526be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3466*4222ddf1SHong Zhang 0, 3467*4222ddf1SHong Zhang 0, 34688fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 3469*4222ddf1SHong Zhang 0, 3470*4222ddf1SHong Zhang 0, 34716fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 34722121bac1SHong Zhang 0, 3473*4222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqAIJ, 3474609c6c4dSKris Buschelman 0, 3475609c6c4dSKris Buschelman 0, 347687d4246cSBarry Smith MatConjugate_SeqAIJ, 347787d4246cSBarry Smith 0, 3478d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 347999cafbc1SBarry Smith MatRealPart_SeqAIJ, 3480f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3481f5edf698SHong Zhang 0, 34822bebee5dSHong Zhang 0, 3483cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3484985db425SBarry Smith 0, 34852af78befSBarry Smith MatGetRowMin_SeqAIJ, 34862af78befSBarry Smith 0, 3487599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3488d519adbfSMatthew Knepley /*114*/ 0, 3489599ef60dSHong Zhang 0, 34903c2a7987SHong Zhang 0, 3491fe97e370SBarry Smith 0, 3492fbdbba38SShri Abhyankar 0, 3493fbdbba38SShri Abhyankar /*119*/ 0, 3494fbdbba38SShri Abhyankar 0, 3495fbdbba38SShri Abhyankar 0, 349682d44351SHong Zhang 0, 3497b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 34980716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3499bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 350037868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 35010da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 350237868618SMatthew G Knepley 0, 35035df89d91SHong Zhang /*129*/ 0, 3504*4222ddf1SHong Zhang 0, 3505*4222ddf1SHong Zhang 0, 350675648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3507b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3508b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 35092b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 3510*4222ddf1SHong Zhang 0, 3511*4222ddf1SHong Zhang 0, 35123964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 35133964eb88SJed Brown /*139*/0, 3514f9426fe0SMark Adams 0, 35151919a2e2SJed Brown 0, 35163a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 35179c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 3518*4222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 3519*4222ddf1SHong Zhang /*145*/MatDestroySubMatrices_SeqAIJ, 3520*4222ddf1SHong Zhang 0, 3521*4222ddf1SHong Zhang 0 35229e29f15eSvictorle }; 352317ab2063SBarry Smith 35247087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3525bef8e0ddSBarry Smith { 3526bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 352797f1f81fSBarry Smith PetscInt i,nz,n; 3528bef8e0ddSBarry Smith 3529bef8e0ddSBarry Smith PetscFunctionBegin; 3530bef8e0ddSBarry Smith nz = aij->maxnz; 3531d0f46423SBarry Smith n = mat->rmap->n; 3532bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3533bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3534bef8e0ddSBarry Smith } 3535bef8e0ddSBarry Smith aij->nz = nz; 3536bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3537bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3538bef8e0ddSBarry Smith } 3539bef8e0ddSBarry Smith PetscFunctionReturn(0); 3540bef8e0ddSBarry Smith } 3541bef8e0ddSBarry Smith 3542a3bb6f32SFande Kong /* 3543e8b528d9SFande Kong * When a sparse matrix has many zero columns, we should compact them out to save the space 3544a3bb6f32SFande Kong * This happens in MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3545a3bb6f32SFande Kong * */ 3546a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3547a3bb6f32SFande Kong { 3548a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3549a3bb6f32SFande Kong PetscTable gid1_lid1; 3550a3bb6f32SFande Kong PetscTablePosition tpos; 3551a3bb6f32SFande Kong PetscInt gid,lid,i,j,ncols,ec; 3552a3bb6f32SFande Kong PetscInt *garray; 3553a3bb6f32SFande Kong PetscErrorCode ierr; 3554a3bb6f32SFande Kong 3555a3bb6f32SFande Kong PetscFunctionBegin; 3556a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3557a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3558a3bb6f32SFande Kong /* use a table */ 3559a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3560a3bb6f32SFande Kong ec = 0; 3561a3bb6f32SFande Kong for (i=0; i<mat->rmap->n; i++) { 3562a3bb6f32SFande Kong ncols = aij->i[i+1] - aij->i[i]; 3563a3bb6f32SFande Kong for (j=0; j<ncols; j++) { 3564a3bb6f32SFande Kong PetscInt data,gid1 = aij->j[aij->i[i] + j] + 1; 3565a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3566a3bb6f32SFande Kong if (!data) { 3567a3bb6f32SFande Kong /* one based table */ 3568a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3569a3bb6f32SFande Kong } 3570a3bb6f32SFande Kong } 3571a3bb6f32SFande Kong } 3572a3bb6f32SFande Kong /* form array of columns we need */ 3573a3bb6f32SFande Kong ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); 3574a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3575a3bb6f32SFande Kong while (tpos) { 3576a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3577a3bb6f32SFande Kong gid--; 3578a3bb6f32SFande Kong lid--; 3579a3bb6f32SFande Kong garray[lid] = gid; 3580a3bb6f32SFande Kong } 3581a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3582a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3583a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3584a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3585a3bb6f32SFande Kong } 3586a3bb6f32SFande Kong /* compact out the extra columns in B */ 3587a3bb6f32SFande Kong for (i=0; i<mat->rmap->n; i++) { 3588a3bb6f32SFande Kong ncols = aij->i[i+1] - aij->i[i]; 3589a3bb6f32SFande Kong for (j=0; j<ncols; j++) { 3590a3bb6f32SFande Kong PetscInt gid1 = aij->j[aij->i[i] + j] + 1; 3591a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3592a3bb6f32SFande Kong lid--; 3593a3bb6f32SFande Kong aij->j[aij->i[i] + j] = lid; 3594a3bb6f32SFande Kong } 3595a3bb6f32SFande Kong } 3596ca5434daSLawrence Mitchell ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 3597ca5434daSLawrence Mitchell ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr); 3598a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 3599a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3600a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3601a3bb6f32SFande Kong PetscFunctionReturn(0); 3602a3bb6f32SFande Kong } 3603a3bb6f32SFande Kong 3604bef8e0ddSBarry Smith /*@ 3605bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3606bef8e0ddSBarry Smith in the matrix. 3607bef8e0ddSBarry Smith 3608bef8e0ddSBarry Smith Input Parameters: 3609bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3610bef8e0ddSBarry Smith - indices - the column indices 3611bef8e0ddSBarry Smith 361215091d37SBarry Smith Level: advanced 361315091d37SBarry Smith 3614bef8e0ddSBarry Smith Notes: 3615bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3616bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3617bef8e0ddSBarry Smith of the MatSetValues() operation. 3618bef8e0ddSBarry Smith 3619bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3620d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3621bef8e0ddSBarry Smith 3622bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3623bef8e0ddSBarry Smith 3624b9617806SBarry Smith The indices should start with zero, not one. 3625b9617806SBarry Smith 3626bef8e0ddSBarry Smith @*/ 36277087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3628bef8e0ddSBarry Smith { 36294ac538c5SBarry Smith PetscErrorCode ierr; 3630bef8e0ddSBarry Smith 3631bef8e0ddSBarry Smith PetscFunctionBegin; 36320700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 36334482741eSBarry Smith PetscValidPointer(indices,2); 36344ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3635bef8e0ddSBarry Smith PetscFunctionReturn(0); 3636bef8e0ddSBarry Smith } 3637bef8e0ddSBarry Smith 3638be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3639be6bf707SBarry Smith 36407087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3641be6bf707SBarry Smith { 3642be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 36436849ba73SBarry Smith PetscErrorCode ierr; 3644d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3645be6bf707SBarry Smith 3646be6bf707SBarry Smith PetscFunctionBegin; 3647169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3648be6bf707SBarry Smith 3649be6bf707SBarry Smith /* allocate space for values if not already there */ 3650be6bf707SBarry Smith if (!aij->saved_values) { 3651854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 36523bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3653be6bf707SBarry Smith } 3654be6bf707SBarry Smith 3655be6bf707SBarry Smith /* copy values over */ 3656580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3657be6bf707SBarry Smith PetscFunctionReturn(0); 3658be6bf707SBarry Smith } 3659be6bf707SBarry Smith 3660be6bf707SBarry Smith /*@ 3661be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3662be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3663be6bf707SBarry Smith nonlinear portion. 3664be6bf707SBarry Smith 3665be6bf707SBarry Smith Collect on Mat 3666be6bf707SBarry Smith 3667be6bf707SBarry Smith Input Parameters: 36680e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3669be6bf707SBarry Smith 367015091d37SBarry Smith Level: advanced 367115091d37SBarry Smith 3672be6bf707SBarry Smith Common Usage, with SNESSolve(): 3673be6bf707SBarry Smith $ Create Jacobian matrix 3674be6bf707SBarry Smith $ Set linear terms into matrix 3675be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3676be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3677be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3678512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3679be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3680be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3681be6bf707SBarry Smith $ In your Jacobian routine 3682be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3683be6bf707SBarry Smith $ Set nonlinear terms in matrix 3684be6bf707SBarry Smith 3685be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3686be6bf707SBarry Smith $ // build linear portion of Jacobian 3687512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3688be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3689be6bf707SBarry Smith $ loop over nonlinear iterations 3690be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3691be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3692be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3693be6bf707SBarry Smith $ Solve linear system with Jacobian 3694be6bf707SBarry Smith $ endloop 3695be6bf707SBarry Smith 3696be6bf707SBarry Smith Notes: 3697be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3698512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3699be6bf707SBarry Smith calling this routine. 3700be6bf707SBarry Smith 37010c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 37020c468ba9SBarry Smith and does not allocated additional space. 37030c468ba9SBarry Smith 3704be6bf707SBarry Smith .seealso: MatRetrieveValues() 3705be6bf707SBarry Smith 3706be6bf707SBarry Smith @*/ 37077087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3708be6bf707SBarry Smith { 37094ac538c5SBarry Smith PetscErrorCode ierr; 3710be6bf707SBarry Smith 3711be6bf707SBarry Smith PetscFunctionBegin; 37120700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3713e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3714e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 37154ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3716be6bf707SBarry Smith PetscFunctionReturn(0); 3717be6bf707SBarry Smith } 3718be6bf707SBarry Smith 37197087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3720be6bf707SBarry Smith { 3721be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 37226849ba73SBarry Smith PetscErrorCode ierr; 3723d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3724be6bf707SBarry Smith 3725be6bf707SBarry Smith PetscFunctionBegin; 3726169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3727f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3728be6bf707SBarry Smith /* copy values over */ 3729580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3730be6bf707SBarry Smith PetscFunctionReturn(0); 3731be6bf707SBarry Smith } 3732be6bf707SBarry Smith 3733be6bf707SBarry Smith /*@ 3734be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3735be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3736be6bf707SBarry Smith nonlinear portion. 3737be6bf707SBarry Smith 3738be6bf707SBarry Smith Collect on Mat 3739be6bf707SBarry Smith 3740be6bf707SBarry Smith Input Parameters: 3741386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3742be6bf707SBarry Smith 374315091d37SBarry Smith Level: advanced 374415091d37SBarry Smith 3745be6bf707SBarry Smith .seealso: MatStoreValues() 3746be6bf707SBarry Smith 3747be6bf707SBarry Smith @*/ 37487087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3749be6bf707SBarry Smith { 37504ac538c5SBarry Smith PetscErrorCode ierr; 3751be6bf707SBarry Smith 3752be6bf707SBarry Smith PetscFunctionBegin; 37530700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3754e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3755e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 37564ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3757be6bf707SBarry Smith PetscFunctionReturn(0); 3758be6bf707SBarry Smith } 3759be6bf707SBarry Smith 3760f83d6046SBarry Smith 3761be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 376217ab2063SBarry Smith /*@C 3763682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 37640d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 37656e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 376651c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 37672bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 376817ab2063SBarry Smith 3769d083f849SBarry Smith Collective 3770db81eaa0SLois Curfman McInnes 377117ab2063SBarry Smith Input Parameters: 3772db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 377317ab2063SBarry Smith . m - number of rows 377417ab2063SBarry Smith . n - number of columns 377517ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 377651c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 37770298fd71SBarry Smith (possibly different for each row) or NULL 377817ab2063SBarry Smith 377917ab2063SBarry Smith Output Parameter: 3780416022c9SBarry Smith . A - the matrix 378117ab2063SBarry Smith 3782175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3783f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3784175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3785175b88e8SBarry Smith 3786b259b22eSLois Curfman McInnes Notes: 378749a6f317SBarry Smith If nnz is given then nz is ignored 378849a6f317SBarry Smith 378917ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 379017ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 37910002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 379244cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 379317ab2063SBarry Smith 379417ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 37950298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 37963d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 37976da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 379817ab2063SBarry Smith 3799682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 38004fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3801682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 38026c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 38036c7ebb05SLois Curfman McInnes 38046c7ebb05SLois Curfman McInnes Options Database Keys: 3805698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 38069db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 380717ab2063SBarry Smith 3808027ccd11SLois Curfman McInnes Level: intermediate 3809027ccd11SLois Curfman McInnes 381069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 381136db0b34SBarry Smith 381217ab2063SBarry Smith @*/ 38137087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 381417ab2063SBarry Smith { 3815dfbe8321SBarry Smith PetscErrorCode ierr; 38166945ee14SBarry Smith 38173a40ed3dSBarry Smith PetscFunctionBegin; 3818f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3819117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3820c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3821d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3822273d9f13SBarry Smith PetscFunctionReturn(0); 3823273d9f13SBarry Smith } 3824273d9f13SBarry Smith 3825273d9f13SBarry Smith /*@C 3826273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3827273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3828273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3829273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3830273d9f13SBarry Smith 3831d083f849SBarry Smith Collective 3832273d9f13SBarry Smith 3833273d9f13SBarry Smith Input Parameters: 38341c4f3114SJed Brown + B - The matrix 3835273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3836273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 38370298fd71SBarry Smith (possibly different for each row) or NULL 3838273d9f13SBarry Smith 3839273d9f13SBarry Smith Notes: 384049a6f317SBarry Smith If nnz is given then nz is ignored 384149a6f317SBarry Smith 3842273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3843273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3844273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3845273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3846273d9f13SBarry Smith 3847273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 38480298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3849273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3850273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3851273d9f13SBarry Smith 3852aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3853aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3854aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3855aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3856aa95bbe8SBarry Smith 3857a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3858a96a251dSBarry Smith entries or columns indices 3859a96a251dSBarry Smith 3860273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3861273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3862273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3863273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3864273d9f13SBarry Smith 3865273d9f13SBarry Smith Options Database Keys: 3866698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 386747b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3868273d9f13SBarry Smith 3869273d9f13SBarry Smith Level: intermediate 3870273d9f13SBarry Smith 387169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3872273d9f13SBarry Smith 3873273d9f13SBarry Smith @*/ 38747087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3875273d9f13SBarry Smith { 38764ac538c5SBarry Smith PetscErrorCode ierr; 3877a23d5eceSKris Buschelman 3878a23d5eceSKris Buschelman PetscFunctionBegin; 38796ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 38806ba663aaSJed Brown PetscValidType(B,1); 38814ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3882a23d5eceSKris Buschelman PetscFunctionReturn(0); 3883a23d5eceSKris Buschelman } 3884a23d5eceSKris Buschelman 38857087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3886a23d5eceSKris Buschelman { 3887273d9f13SBarry Smith Mat_SeqAIJ *b; 38882576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 38896849ba73SBarry Smith PetscErrorCode ierr; 389097f1f81fSBarry Smith PetscInt i; 3891273d9f13SBarry Smith 3892273d9f13SBarry Smith PetscFunctionBegin; 38932576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3894a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3895c461c341SBarry Smith skipallocation = PETSC_TRUE; 3896c461c341SBarry Smith nz = 0; 3897c461c341SBarry Smith } 389826283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 389926283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3900899cda47SBarry Smith 3901435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 390260e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 3903071fcb05SBarry Smith #if defined(PETSC_USE_DEBUG) 3904b73539f3SBarry Smith if (nnz) { 3905d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 390660e0710aSBarry 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]); 390760e0710aSBarry Smith if (nnz[i] > B->cmap->n) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %D value %d rowlength %D",i,nnz[i],B->cmap->n); 3908b73539f3SBarry Smith } 3909b73539f3SBarry Smith } 3910071fcb05SBarry Smith #endif 3911b73539f3SBarry Smith 3912273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 39132205254eSKarl Rupp 3914273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3915273d9f13SBarry Smith 3916ab93d7beSBarry Smith if (!skipallocation) { 39172ee49352SLisandro Dalcin if (!b->imax) { 3918071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 3919071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 3920071fcb05SBarry Smith } 3921071fcb05SBarry Smith if (!b->ilen) { 3922071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 3923071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 3924071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 3925071fcb05SBarry Smith } else { 3926071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 39272ee49352SLisandro Dalcin } 3928846b4da1SFande Kong if (!b->ipre) { 3929846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 3930846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 3931846b4da1SFande Kong } 3932273d9f13SBarry Smith if (!nnz) { 3933435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3934c62bd62aSJed Brown else if (nz < 0) nz = 1; 39355d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 3936d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3937d0f46423SBarry Smith nz = nz*B->rmap->n; 3938273d9f13SBarry Smith } else { 3939c73702f5SBarry Smith PetscInt64 nz64 = 0; 3940c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 3941c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 3942273d9f13SBarry Smith } 3943ab93d7beSBarry Smith 3944273d9f13SBarry Smith /* allocate the matrix space */ 394553dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 39462ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3947396832f4SHong Zhang if (B->structure_only) { 39485848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 39495848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 3950396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 3951396832f4SHong Zhang } else { 3952dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 39533bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3954396832f4SHong Zhang } 3955bfeeae90SHong Zhang b->i[0] = 0; 3956d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 39575da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 39585da197adSKris Buschelman } 3959396832f4SHong Zhang if (B->structure_only) { 3960396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 3961396832f4SHong Zhang b->free_a = PETSC_FALSE; 3962396832f4SHong Zhang } else { 3963273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3964e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3965396832f4SHong Zhang } 3966e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3967c461c341SBarry Smith } else { 3968e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3969e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3970c461c341SBarry Smith } 3971273d9f13SBarry Smith 3972846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 3973846b4da1SFande Kong /* reserve user-requested sparsity */ 3974580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 3975846b4da1SFande Kong } 3976846b4da1SFande Kong 3977846b4da1SFande Kong 3978273d9f13SBarry Smith b->nz = 0; 3979273d9f13SBarry Smith b->maxnz = nz; 3980273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 39812205254eSKarl Rupp if (realalloc) { 39822205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 39832205254eSKarl Rupp } 3984cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 3985cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 3986273d9f13SBarry Smith PetscFunctionReturn(0); 3987273d9f13SBarry Smith } 3988273d9f13SBarry Smith 3989846b4da1SFande Kong 3990846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 3991846b4da1SFande Kong { 3992846b4da1SFande Kong Mat_SeqAIJ *a; 3993a5bbaf83SFande Kong PetscInt i; 3994846b4da1SFande Kong PetscErrorCode ierr; 3995846b4da1SFande Kong 3996846b4da1SFande Kong PetscFunctionBegin; 3997846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 399814d0e64fSAlex Lindsay 399914d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 400014d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 400114d0e64fSAlex Lindsay 4002846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 40032c814fdeSFande Kong /* if no saved info, we error out */ 4004fb4dc15dSAlex Lindsay if (!a->ipre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 40052c814fdeSFande Kong 4006fb4dc15dSAlex Lindsay if (!a->i || !a->j || !a->a || !a->imax || !a->ilen) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Memory info is incomplete, and can not reset preallocation \n"); 40072c814fdeSFande Kong 4008580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 4009580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 4010846b4da1SFande Kong a->i[0] = 0; 4011846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 4012846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 4013846b4da1SFande Kong } 4014846b4da1SFande Kong A->preallocated = PETSC_TRUE; 4015846b4da1SFande Kong a->nz = 0; 4016846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 4017846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 4018846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 4019846b4da1SFande Kong A->assembled = PETSC_FALSE; 4020846b4da1SFande Kong PetscFunctionReturn(0); 4021846b4da1SFande Kong } 4022846b4da1SFande Kong 402358d36128SBarry Smith /*@ 4024a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 4025a1661176SMatthew Knepley 4026a1661176SMatthew Knepley Input Parameters: 4027a1661176SMatthew Knepley + B - the matrix 4028a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4029a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4030a1661176SMatthew Knepley - v - optional values in the matrix 4031a1661176SMatthew Knepley 4032a1661176SMatthew Knepley Level: developer 4033a1661176SMatthew Knepley 403458d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 403558d36128SBarry Smith 4036c1c1d628SHong Zhang .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ 4037a1661176SMatthew Knepley @*/ 4038a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4039a1661176SMatthew Knepley { 4040a1661176SMatthew Knepley PetscErrorCode ierr; 4041a1661176SMatthew Knepley 4042a1661176SMatthew Knepley PetscFunctionBegin; 40430700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 40446ba663aaSJed Brown PetscValidType(B,1); 40454ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 4046a1661176SMatthew Knepley PetscFunctionReturn(0); 4047a1661176SMatthew Knepley } 4048a1661176SMatthew Knepley 40497087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4050a1661176SMatthew Knepley { 4051a1661176SMatthew Knepley PetscInt i; 4052a1661176SMatthew Knepley PetscInt m,n; 4053a1661176SMatthew Knepley PetscInt nz; 4054a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 4055a1661176SMatthew Knepley PetscErrorCode ierr; 4056a1661176SMatthew Knepley 4057a1661176SMatthew Knepley PetscFunctionBegin; 405865e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4059779a8d59SSatish Balay 4060779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4061779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4062779a8d59SSatish Balay 4063779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4064854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 4065a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4066b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 4067a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 406865e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4069a1661176SMatthew Knepley nnz[i] = nz; 4070a1661176SMatthew Knepley } 4071a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4072a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4073a1661176SMatthew Knepley 4074a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4075071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 4076a1661176SMatthew Knepley } 4077a1661176SMatthew Knepley 4078a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4079a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4080a1661176SMatthew Knepley 40817827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4082a1661176SMatthew Knepley PetscFunctionReturn(0); 4083a1661176SMatthew Knepley } 4084a1661176SMatthew Knepley 4085c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4086af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4087170fe5c8SBarry Smith 4088170fe5c8SBarry Smith /* 4089170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4090170fe5c8SBarry Smith 4091170fe5c8SBarry Smith n p p 4092170fe5c8SBarry Smith ( ) ( ) ( ) 4093170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 4094170fe5c8SBarry Smith ( ) ( ) ( ) 4095170fe5c8SBarry Smith 4096170fe5c8SBarry Smith */ 4097170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4098170fe5c8SBarry Smith { 4099170fe5c8SBarry Smith PetscErrorCode ierr; 4100170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4101170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4102170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 41031de00fd4SBarry Smith PetscInt i,n,m,q,p; 4104170fe5c8SBarry Smith const PetscInt *ii,*idx; 4105170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4106170fe5c8SBarry Smith PetscScalar *c,*c_q; 4107170fe5c8SBarry Smith 4108170fe5c8SBarry Smith PetscFunctionBegin; 4109d0f46423SBarry Smith m = A->rmap->n; 4110d0f46423SBarry Smith n = A->cmap->n; 4111d0f46423SBarry Smith p = B->cmap->n; 4112170fe5c8SBarry Smith a = sub_a->v; 4113170fe5c8SBarry Smith b = sub_b->a; 4114170fe5c8SBarry Smith c = sub_c->v; 4115580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 4116170fe5c8SBarry Smith 4117170fe5c8SBarry Smith ii = sub_b->i; 4118170fe5c8SBarry Smith idx = sub_b->j; 4119170fe5c8SBarry Smith for (i=0; i<n; i++) { 4120170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4121170fe5c8SBarry Smith while (q-->0) { 4122170fe5c8SBarry Smith c_q = c + m*(*idx); 4123170fe5c8SBarry Smith a_q = a + m*i; 4124854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4125170fe5c8SBarry Smith idx++; 4126170fe5c8SBarry Smith b++; 4127170fe5c8SBarry Smith } 4128170fe5c8SBarry Smith } 4129170fe5c8SBarry Smith PetscFunctionReturn(0); 4130170fe5c8SBarry Smith } 4131170fe5c8SBarry Smith 4132*4222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C) 4133170fe5c8SBarry Smith { 4134170fe5c8SBarry Smith PetscErrorCode ierr; 4135d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 4136170fe5c8SBarry Smith 4137170fe5c8SBarry Smith PetscFunctionBegin; 413860e0710aSBarry Smith if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %D != B->rmap->n %D\n",A->cmap->n,B->rmap->n); 4139*4222ddf1SHong Zhang ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr); 4140*4222ddf1SHong Zhang ierr = MatSetBlockSizesFromMats(C,A,B);CHKERRQ(ierr); 4141*4222ddf1SHong Zhang ierr = MatSetType(C,MATSEQDENSE);CHKERRQ(ierr); 4142*4222ddf1SHong Zhang ierr = MatSeqDenseSetPreallocation(C,NULL);CHKERRQ(ierr); 4143d73949e8SHong Zhang 4144*4222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 4145170fe5c8SBarry Smith PetscFunctionReturn(0); 4146170fe5c8SBarry Smith } 4147170fe5c8SBarry Smith 4148170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 41490bad9183SKris Buschelman /*MC 4150fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 41510bad9183SKris Buschelman based on compressed sparse row format. 41520bad9183SKris Buschelman 41530bad9183SKris Buschelman Options Database Keys: 41540bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 41550bad9183SKris Buschelman 41560bad9183SKris Buschelman Level: beginner 41570bad9183SKris Buschelman 41580cd7f59aSBarry Smith Notes: 41590cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 41600cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 41610cd7f59aSBarry Smith in the matrix 41620cd7f59aSBarry Smith 41630cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 41640cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 41650cd7f59aSBarry Smith 41660cd7f59aSBarry Smith Developer Notes: 41670cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 41680cd7f59aSBarry Smith 4169f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 41700bad9183SKris Buschelman M*/ 41710bad9183SKris Buschelman 4172ccd284c7SBarry Smith /*MC 4173ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4174ccd284c7SBarry Smith 4175ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4176ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 41770cd7f59aSBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation() is supported 4178ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4179ccd284c7SBarry Smith the above preallocation routines for simplicity. 4180ccd284c7SBarry Smith 4181ccd284c7SBarry Smith Options Database Keys: 4182ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4183ccd284c7SBarry Smith 418495452b02SPatrick Sanan Developer Notes: 4185ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4186ccd284c7SBarry Smith enough exist. 4187ccd284c7SBarry Smith 4188ccd284c7SBarry Smith Level: beginner 4189ccd284c7SBarry Smith 4190ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4191ccd284c7SBarry Smith M*/ 4192ccd284c7SBarry Smith 4193ccd284c7SBarry Smith /*MC 4194ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4195ccd284c7SBarry Smith 4196ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4197ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4198ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4199ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4200ccd284c7SBarry Smith the above preallocation routines for simplicity. 4201ccd284c7SBarry Smith 4202ccd284c7SBarry Smith Options Database Keys: 4203ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4204ccd284c7SBarry Smith 4205ccd284c7SBarry Smith Level: beginner 4206ccd284c7SBarry Smith 4207ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4208ccd284c7SBarry Smith M*/ 4209ccd284c7SBarry Smith 42107906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 42117906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 42127906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 42137906f579SHong Zhang #endif 42147906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 42157906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 42167906f579SHong Zhang #endif 42177906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 42187906f579SHong Zhang 4219d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4220c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 4221*4222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat); 42227906f579SHong Zhang 42238c778c55SBarry Smith /*@C 42248f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 42258c778c55SBarry Smith 42268c778c55SBarry Smith Not Collective 42278c778c55SBarry Smith 42288c778c55SBarry Smith Input Parameter: 4229579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 42308c778c55SBarry Smith 42318c778c55SBarry Smith Output Parameter: 42328c778c55SBarry Smith . array - pointer to the data 42338c778c55SBarry Smith 42348c778c55SBarry Smith Level: intermediate 42358c778c55SBarry Smith 4236774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 42378c778c55SBarry Smith @*/ 42388c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 42398c778c55SBarry Smith { 42408c778c55SBarry Smith PetscErrorCode ierr; 42418c778c55SBarry Smith 42428c778c55SBarry Smith PetscFunctionBegin; 42438c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 42448c778c55SBarry Smith PetscFunctionReturn(0); 42458c778c55SBarry Smith } 42468c778c55SBarry Smith 424721e72a00SBarry Smith /*@C 42488f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 42498f1ea47aSStefano Zampini 42508f1ea47aSStefano Zampini Not Collective 42518f1ea47aSStefano Zampini 42528f1ea47aSStefano Zampini Input Parameter: 42538f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 42548f1ea47aSStefano Zampini 42558f1ea47aSStefano Zampini Output Parameter: 42568f1ea47aSStefano Zampini . array - pointer to the data 42578f1ea47aSStefano Zampini 42588f1ea47aSStefano Zampini Level: intermediate 42598f1ea47aSStefano Zampini 42608f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 42618f1ea47aSStefano Zampini @*/ 42628f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 42638f1ea47aSStefano Zampini { 42648f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4265c70f7ee4SJunchao Zhang PetscOffloadMask oval; 42668f1ea47aSStefano Zampini #endif 42678f1ea47aSStefano Zampini PetscErrorCode ierr; 42688f1ea47aSStefano Zampini 42698f1ea47aSStefano Zampini PetscFunctionBegin; 42708f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4271c70f7ee4SJunchao Zhang oval = A->offloadmask; 42728f1ea47aSStefano Zampini #endif 42738f1ea47aSStefano Zampini ierr = MatSeqAIJGetArray(A,(PetscScalar**)array);CHKERRQ(ierr); 42748f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4275c70f7ee4SJunchao Zhang if (oval == PETSC_OFFLOAD_GPU || oval == PETSC_OFFLOAD_BOTH) A->offloadmask = PETSC_OFFLOAD_BOTH; 42768f1ea47aSStefano Zampini #endif 42778f1ea47aSStefano Zampini PetscFunctionReturn(0); 42788f1ea47aSStefano Zampini } 42798f1ea47aSStefano Zampini 42808f1ea47aSStefano Zampini /*@C 42818f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 42828f1ea47aSStefano Zampini 42838f1ea47aSStefano Zampini Not Collective 42848f1ea47aSStefano Zampini 42858f1ea47aSStefano Zampini Input Parameter: 42868f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 42878f1ea47aSStefano Zampini 42888f1ea47aSStefano Zampini Output Parameter: 42898f1ea47aSStefano Zampini . array - pointer to the data 42908f1ea47aSStefano Zampini 42918f1ea47aSStefano Zampini Level: intermediate 42928f1ea47aSStefano Zampini 42938f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 42948f1ea47aSStefano Zampini @*/ 42958f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 42968f1ea47aSStefano Zampini { 42978f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4298c70f7ee4SJunchao Zhang PetscOffloadMask oval; 42998f1ea47aSStefano Zampini #endif 43008f1ea47aSStefano Zampini PetscErrorCode ierr; 43018f1ea47aSStefano Zampini 43028f1ea47aSStefano Zampini PetscFunctionBegin; 43038f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4304c70f7ee4SJunchao Zhang oval = A->offloadmask; 43058f1ea47aSStefano Zampini #endif 43068f1ea47aSStefano Zampini ierr = MatSeqAIJRestoreArray(A,(PetscScalar**)array);CHKERRQ(ierr); 43078f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4308c70f7ee4SJunchao Zhang A->offloadmask = oval; 43098f1ea47aSStefano Zampini #endif 43108f1ea47aSStefano Zampini PetscFunctionReturn(0); 43118f1ea47aSStefano Zampini } 43128f1ea47aSStefano Zampini 43138f1ea47aSStefano Zampini /*@C 431421e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 431521e72a00SBarry Smith 431621e72a00SBarry Smith Not Collective 431721e72a00SBarry Smith 431821e72a00SBarry Smith Input Parameter: 4319579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 432021e72a00SBarry Smith 432121e72a00SBarry Smith Output Parameter: 432221e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 432321e72a00SBarry Smith 432421e72a00SBarry Smith Level: intermediate 432521e72a00SBarry Smith 432621e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 432721e72a00SBarry Smith @*/ 432821e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 432921e72a00SBarry Smith { 433021e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 433121e72a00SBarry Smith 433221e72a00SBarry Smith PetscFunctionBegin; 433321e72a00SBarry Smith *nz = aij->rmax; 433421e72a00SBarry Smith PetscFunctionReturn(0); 433521e72a00SBarry Smith } 433621e72a00SBarry Smith 43378c778c55SBarry Smith /*@C 4338579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 43398c778c55SBarry Smith 43408c778c55SBarry Smith Not Collective 43418c778c55SBarry Smith 43428c778c55SBarry Smith Input Parameters: 4343a2b725a8SWilliam Gropp + mat - a MATSEQAIJ matrix 4344a2b725a8SWilliam Gropp - array - pointer to the data 43458c778c55SBarry Smith 43468c778c55SBarry Smith Level: intermediate 43478c778c55SBarry Smith 4348774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 43498c778c55SBarry Smith @*/ 43508c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 43518c778c55SBarry Smith { 43528c778c55SBarry Smith PetscErrorCode ierr; 43538c778c55SBarry Smith 43548c778c55SBarry Smith PetscFunctionBegin; 43558c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 43568c778c55SBarry Smith PetscFunctionReturn(0); 43578c778c55SBarry Smith } 43588c778c55SBarry Smith 435934b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 436002fe1965SBarry Smith PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat); 436102fe1965SBarry Smith #endif 436202fe1965SBarry Smith 43638cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4364273d9f13SBarry Smith { 4365273d9f13SBarry Smith Mat_SeqAIJ *b; 4366dfbe8321SBarry Smith PetscErrorCode ierr; 436738baddfdSBarry Smith PetscMPIInt size; 4368273d9f13SBarry Smith 4369273d9f13SBarry Smith PetscFunctionBegin; 4370ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 4371e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4372273d9f13SBarry Smith 4373b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 43742205254eSKarl Rupp 4375b0a32e0cSBarry Smith B->data = (void*)b; 43762205254eSKarl Rupp 4377549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4378071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 43792205254eSKarl Rupp 4380416022c9SBarry Smith b->row = 0; 4381416022c9SBarry Smith b->col = 0; 438282bf6240SBarry Smith b->icol = 0; 4383b810aeb4SBarry Smith b->reallocs = 0; 438436db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4385f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4386416022c9SBarry Smith b->nonew = 0; 4387416022c9SBarry Smith b->diag = 0; 4388416022c9SBarry Smith b->solve_work = 0; 43892a1b7f2aSHong Zhang B->spptr = 0; 4390be6bf707SBarry Smith b->saved_values = 0; 4391d7f994e1SBarry Smith b->idiag = 0; 439271f1c65dSBarry Smith b->mdiag = 0; 439371f1c65dSBarry Smith b->ssor_work = 0; 439471f1c65dSBarry Smith b->omega = 1.0; 439571f1c65dSBarry Smith b->fshift = 0.0; 439671f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4397bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4398a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 439917ab2063SBarry Smith 440035d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4401bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4402bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 44038c778c55SBarry Smith 4404b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4405bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4406bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4407b3866ffcSBarry Smith #endif 440817f1a0eaSHong Zhang 4409bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4410bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4411bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4412bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4413bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4414bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 44154dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 44169779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 44174a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4418191b95cbSRichard Tran Mills #endif 441934b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 442002fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 4421*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 442202fe1965SBarry Smith #endif 4423bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4424af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4425af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4426af8000cdSHong Zhang #endif 442763c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 442863c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 4429*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ);CHKERRQ(ierr); 443063c07aadSStefano Zampini #endif 4431b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4432d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4433c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4434bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4435bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4436bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4437846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4438bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4439bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 4440bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 4441bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 4442*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ);CHKERRQ(ierr); 4443*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ);CHKERRQ(ierr); 4444*4222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 44454108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 444617667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 44474099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 44483a40ed3dSBarry Smith PetscFunctionReturn(0); 444917ab2063SBarry Smith } 445017ab2063SBarry Smith 4451b24902e0SBarry Smith /* 4452b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4453b24902e0SBarry Smith */ 4454ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 445517ab2063SBarry Smith { 4456416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 44576849ba73SBarry Smith PetscErrorCode ierr; 4458071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 445917ab2063SBarry Smith 44603a40ed3dSBarry Smith PetscFunctionBegin; 4461273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 4462273d9f13SBarry Smith 4463d5f3da31SBarry Smith C->factortype = A->factortype; 4464416022c9SBarry Smith c->row = 0; 4465416022c9SBarry Smith c->col = 0; 446682bf6240SBarry Smith c->icol = 0; 44676ad4291fSHong Zhang c->reallocs = 0; 446817ab2063SBarry Smith 44696ad4291fSHong Zhang C->assembled = PETSC_TRUE; 447017ab2063SBarry Smith 4471aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4472aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4473eec197d1SBarry Smith 4474071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4475071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4476071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4477071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 44783bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 447917ab2063SBarry Smith 448017ab2063SBarry Smith /* allocate the matrix space */ 4481f77e22a1SHong Zhang if (mallocmatspace) { 4482dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 44833bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 44842205254eSKarl Rupp 4485f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 44862205254eSKarl Rupp 4487580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 448817ab2063SBarry Smith if (m > 0) { 4489580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4490be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 4491580bdb30SBarry Smith ierr = PetscArraycpy(c->a,a->a,a->i[m]);CHKERRQ(ierr); 4492be6bf707SBarry Smith } else { 4493580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 449417ab2063SBarry Smith } 449508480c60SBarry Smith } 4496f77e22a1SHong Zhang } 449717ab2063SBarry Smith 44986ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4499416022c9SBarry Smith c->roworiented = a->roworiented; 4500416022c9SBarry Smith c->nonew = a->nonew; 4501416022c9SBarry Smith if (a->diag) { 4502854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4503071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 45043bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4505071fcb05SBarry Smith } else c->diag = NULL; 45062205254eSKarl Rupp 45076ad4291fSHong Zhang c->solve_work = 0; 45086ad4291fSHong Zhang c->saved_values = 0; 45096ad4291fSHong Zhang c->idiag = 0; 451071f1c65dSBarry Smith c->ssor_work = 0; 4511a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4512e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4513e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 45146ad4291fSHong Zhang 4515893ad86cSHong Zhang c->rmax = a->rmax; 4516416022c9SBarry Smith c->nz = a->nz; 45178ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4518273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4519754ec7b1SSatish Balay 45206ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 45216ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4522cd6b891eSBarry Smith if (a->compressedrow.use) { 45236ad4291fSHong Zhang i = a->compressedrow.nrows; 4524dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4525580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4526580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 452727ea64f8SHong Zhang } else { 452827ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 45290298fd71SBarry Smith c->compressedrow.i = NULL; 45300298fd71SBarry Smith c->compressedrow.rindex = NULL; 45316ad4291fSHong Zhang } 4532ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4533e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 45344846f1f5SKris Buschelman 45352205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4536140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 45373a40ed3dSBarry Smith PetscFunctionReturn(0); 453817ab2063SBarry Smith } 453917ab2063SBarry Smith 4540b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4541b24902e0SBarry Smith { 4542b24902e0SBarry Smith PetscErrorCode ierr; 4543b24902e0SBarry Smith 4544b24902e0SBarry Smith PetscFunctionBegin; 4545ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 45464b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4547cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 454833d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4549cfd3f464SBarry Smith } 4550a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4551f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4552b24902e0SBarry Smith PetscFunctionReturn(0); 4553b24902e0SBarry Smith } 4554b24902e0SBarry Smith 4555112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4556fbdbba38SShri Abhyankar { 455752f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 455852f91c60SVaclav Hapla PetscErrorCode ierr; 455952f91c60SVaclav Hapla 456052f91c60SVaclav Hapla PetscFunctionBegin; 456152f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 456252f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4563c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4564c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 456552f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 456652f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 456752f91c60SVaclav Hapla if (isbinary) { 456852f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 456952f91c60SVaclav Hapla } else if (ishdf5) { 457052f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 457152f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 457252f91c60SVaclav Hapla #else 457352f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 457452f91c60SVaclav Hapla #endif 457552f91c60SVaclav Hapla } else { 457652f91c60SVaclav Hapla 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); 457752f91c60SVaclav Hapla } 457852f91c60SVaclav Hapla PetscFunctionReturn(0); 457952f91c60SVaclav Hapla } 458052f91c60SVaclav Hapla 45813ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer) 458252f91c60SVaclav Hapla { 45833ea6fe3dSLisandro Dalcin Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 4584fbdbba38SShri Abhyankar PetscErrorCode ierr; 45853ea6fe3dSLisandro Dalcin PetscInt header[4],*rowlens,M,N,nz,sum,rows,cols,i; 4586fbdbba38SShri Abhyankar 4587fbdbba38SShri Abhyankar PetscFunctionBegin; 45883ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4589bbead8a2SBarry Smith 45903ea6fe3dSLisandro Dalcin /* read in matrix header */ 45913ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 45923ea6fe3dSLisandro Dalcin if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 4593fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 45943ea6fe3dSLisandro Dalcin if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M); 45953ea6fe3dSLisandro Dalcin if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N); 4596bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 4597fbdbba38SShri Abhyankar 45983ea6fe3dSLisandro Dalcin /* set block sizes from the viewer's .info file */ 45993ea6fe3dSLisandro Dalcin ierr = MatLoad_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 46003ea6fe3dSLisandro Dalcin /* set local and global sizes if not set already */ 46013ea6fe3dSLisandro Dalcin if (mat->rmap->n < 0) mat->rmap->n = M; 46023ea6fe3dSLisandro Dalcin if (mat->cmap->n < 0) mat->cmap->n = N; 46033ea6fe3dSLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 46043ea6fe3dSLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 46053ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 46063ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 46073ea6fe3dSLisandro Dalcin 46083ea6fe3dSLisandro Dalcin /* check if the matrix sizes are correct */ 46093ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 46103ea6fe3dSLisandro Dalcin if (M != rows || N != cols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%D, %D) than the input matrix (%D, %D)",M,N,rows,cols); 46113ea6fe3dSLisandro Dalcin 4612fbdbba38SShri Abhyankar /* read in row lengths */ 46133ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(M,&rowlens);CHKERRQ(ierr); 46143ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT);CHKERRQ(ierr); 46153ea6fe3dSLisandro Dalcin /* check if sum(rowlens) is same as nz */ 46163ea6fe3dSLisandro Dalcin sum = 0; for (i=0; i<M; i++) sum += rowlens[i]; 46173ea6fe3dSLisandro Dalcin if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Inconsistent matrix data in file: nonzeros = %D, sum-row-lengths = %D\n",nz,sum); 46183ea6fe3dSLisandro Dalcin /* preallocate and check sizes */ 46193ea6fe3dSLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens);CHKERRQ(ierr); 46203ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 462160e0710aSBarry Smith 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); 46223ea6fe3dSLisandro Dalcin /* store row lengths */ 46233ea6fe3dSLisandro Dalcin ierr = PetscArraycpy(a->ilen,rowlens,M);CHKERRQ(ierr); 46243ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 4625fbdbba38SShri Abhyankar 46263ea6fe3dSLisandro Dalcin /* fill in "i" row pointers */ 46273ea6fe3dSLisandro Dalcin a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i]; 46283ea6fe3dSLisandro Dalcin /* read in "j" column indices */ 46293ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 46303ea6fe3dSLisandro Dalcin /* read in "a" nonzero values */ 46313ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4632fbdbba38SShri Abhyankar 46333ea6fe3dSLisandro Dalcin ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46343ea6fe3dSLisandro Dalcin ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4635fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4636fbdbba38SShri Abhyankar } 4637fbdbba38SShri Abhyankar 4638ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 46397264ac53SSatish Balay { 46407264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4641dfbe8321SBarry Smith PetscErrorCode ierr; 4642eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4643eeffb40dSHong Zhang PetscInt k; 4644eeffb40dSHong Zhang #endif 46457264ac53SSatish Balay 46463a40ed3dSBarry Smith PetscFunctionBegin; 4647bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4648d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4649ca44d042SBarry Smith *flg = PETSC_FALSE; 4650ca44d042SBarry Smith PetscFunctionReturn(0); 4651bcd2baecSBarry Smith } 46527264ac53SSatish Balay 46537264ac53SSatish Balay /* if the a->i are the same */ 4654580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4655abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 46567264ac53SSatish Balay 46577264ac53SSatish Balay /* if a->j are the same */ 4658580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 4659abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4660bcd2baecSBarry Smith 4661bcd2baecSBarry Smith /* if a->a are the same */ 4662eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4663eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4664eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4665eeffb40dSHong Zhang *flg = PETSC_FALSE; 46663a40ed3dSBarry Smith PetscFunctionReturn(0); 4667eeffb40dSHong Zhang } 4668eeffb40dSHong Zhang } 4669eeffb40dSHong Zhang #else 4670580bdb30SBarry Smith ierr = PetscArraycmp(a->a,b->a,a->nz,flg);CHKERRQ(ierr); 4671eeffb40dSHong Zhang #endif 4672eeffb40dSHong Zhang PetscFunctionReturn(0); 46737264ac53SSatish Balay } 467436db0b34SBarry Smith 467505869f15SSatish Balay /*@ 467636db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 467736db0b34SBarry Smith provided by the user. 467836db0b34SBarry Smith 4679d083f849SBarry Smith Collective 468036db0b34SBarry Smith 468136db0b34SBarry Smith Input Parameters: 468236db0b34SBarry Smith + comm - must be an MPI communicator of size 1 468336db0b34SBarry Smith . m - number of rows 468436db0b34SBarry Smith . n - number of columns 4685483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 468636db0b34SBarry Smith . j - column indices 468736db0b34SBarry Smith - a - matrix values 468836db0b34SBarry Smith 468936db0b34SBarry Smith Output Parameter: 469036db0b34SBarry Smith . mat - the matrix 469136db0b34SBarry Smith 469236db0b34SBarry Smith Level: intermediate 469336db0b34SBarry Smith 469436db0b34SBarry Smith Notes: 46950551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4696292fb18eSBarry Smith once the matrix is destroyed and not before 469736db0b34SBarry Smith 469836db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 469936db0b34SBarry Smith 4700bfeeae90SHong Zhang The i and j indices are 0 based 470136db0b34SBarry Smith 4702a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4703a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 47048eef79e4SBarry Smith as shown 4705a4552177SSatish Balay 47068eef79e4SBarry Smith $ 1 0 0 47078eef79e4SBarry Smith $ 2 0 3 47088eef79e4SBarry Smith $ 4 5 6 47098eef79e4SBarry Smith $ 47108eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 47118eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 47128eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4713a4552177SSatish Balay 47149985e31cSBarry Smith 471569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 471636db0b34SBarry Smith 471736db0b34SBarry Smith @*/ 4718c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 471936db0b34SBarry Smith { 4720dfbe8321SBarry Smith PetscErrorCode ierr; 4721cbcfb4deSHong Zhang PetscInt ii; 472236db0b34SBarry Smith Mat_SeqAIJ *aij; 4723cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4724cbcfb4deSHong Zhang PetscInt jj; 4725cbcfb4deSHong Zhang #endif 472636db0b34SBarry Smith 472736db0b34SBarry Smith PetscFunctionBegin; 472841096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4729f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4730f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4731a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4732ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4733ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4734ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4735071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 4736071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 4737ab93d7beSBarry Smith 473836db0b34SBarry Smith aij->i = i; 473936db0b34SBarry Smith aij->j = j; 474036db0b34SBarry Smith aij->a = a; 474136db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 474236db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4743e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4744e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 474536db0b34SBarry Smith 474636db0b34SBarry Smith for (ii=0; ii<m; ii++) { 474736db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 47482515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 474960e0710aSBarry 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]); 47509985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4751a061629eSStefano Zampini if (j[jj] < j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual column %D) in row %D is not sorted",jj-i[ii],j[jj],ii); 4752a061629eSStefano Zampini if (j[jj] == j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual column %D) in row %D is identical to previous entry",jj-i[ii],j[jj],ii); 47539985e31cSBarry Smith } 475436db0b34SBarry Smith #endif 475536db0b34SBarry Smith } 47562515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 475736db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 475860e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 475960e0710aSBarry 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]); 476036db0b34SBarry Smith } 476136db0b34SBarry Smith #endif 476236db0b34SBarry Smith 4763b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4764b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 476536db0b34SBarry Smith PetscFunctionReturn(0); 476636db0b34SBarry Smith } 476780ef6e79SMatthew G Knepley /*@C 4768d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 47698a0b0e6bSVictor Minden provided by the user. 47708a0b0e6bSVictor Minden 4771d083f849SBarry Smith Collective 47728a0b0e6bSVictor Minden 47738a0b0e6bSVictor Minden Input Parameters: 47748a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 47758a0b0e6bSVictor Minden . m - number of rows 47768a0b0e6bSVictor Minden . n - number of columns 47778a0b0e6bSVictor Minden . i - row indices 47788a0b0e6bSVictor Minden . j - column indices 47791230e6d1SVictor Minden . a - matrix values 47801230e6d1SVictor Minden . nz - number of nonzeros 47811230e6d1SVictor Minden - idx - 0 or 1 based 47828a0b0e6bSVictor Minden 47838a0b0e6bSVictor Minden Output Parameter: 47848a0b0e6bSVictor Minden . mat - the matrix 47858a0b0e6bSVictor Minden 47868a0b0e6bSVictor Minden Level: intermediate 47878a0b0e6bSVictor Minden 47888a0b0e6bSVictor Minden Notes: 47898a0b0e6bSVictor Minden The i and j indices are 0 based 47908a0b0e6bSVictor Minden 47918a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 47928a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 47938a0b0e6bSVictor Minden as shown: 47948a0b0e6bSVictor Minden 47958a0b0e6bSVictor Minden 1 0 0 47968a0b0e6bSVictor Minden 2 0 3 47978a0b0e6bSVictor Minden 4 5 6 47988a0b0e6bSVictor Minden 47998a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 48008a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 48018a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 48028a0b0e6bSVictor Minden 48038a0b0e6bSVictor Minden 480469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 48058a0b0e6bSVictor Minden 48068a0b0e6bSVictor Minden @*/ 4807c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 48088a0b0e6bSVictor Minden { 48098a0b0e6bSVictor Minden PetscErrorCode ierr; 4810d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 48118a0b0e6bSVictor Minden 48128a0b0e6bSVictor Minden 48138a0b0e6bSVictor Minden PetscFunctionBegin; 48141795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 48151230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4816c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 48171230e6d1SVictor Minden } 48188a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 48198a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 48208a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 48211230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 48221230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 48231230e6d1SVictor Minden if (idx) { 48241230e6d1SVictor Minden row = i[ii] - 1; 48251230e6d1SVictor Minden col = j[ii] - 1; 48261230e6d1SVictor Minden } else { 48271230e6d1SVictor Minden row = i[ii]; 48281230e6d1SVictor Minden col = j[ii]; 48298a0b0e6bSVictor Minden } 48301230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 48318a0b0e6bSVictor Minden } 48328a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 48338a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4834d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 48358a0b0e6bSVictor Minden PetscFunctionReturn(0); 48368a0b0e6bSVictor Minden } 483736db0b34SBarry Smith 4838acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4839acf2f550SJed Brown { 4840acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4841acf2f550SJed Brown PetscErrorCode ierr; 4842acf2f550SJed Brown 4843acf2f550SJed Brown PetscFunctionBegin; 4844acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4845acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 48462205254eSKarl Rupp 4847acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4848acf2f550SJed Brown PetscFunctionReturn(0); 4849acf2f550SJed Brown } 4850acf2f550SJed Brown 48519c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 48529c8f2541SHong Zhang { 48539c8f2541SHong Zhang PetscErrorCode ierr; 48548761c3d6SHong Zhang PetscMPIInt size; 48559c8f2541SHong Zhang 48569c8f2541SHong Zhang PetscFunctionBegin; 48578761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 48587bbdc51dSHong Zhang if (size == 1) { 48597bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 48607bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 48617bbdc51dSHong Zhang } else { 48628761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 48637bbdc51dSHong Zhang } 48648761c3d6SHong Zhang } else { 48659c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 48668761c3d6SHong Zhang } 48679c8f2541SHong Zhang PetscFunctionReturn(0); 48689c8f2541SHong Zhang } 48699c8f2541SHong Zhang 487081824310SBarry Smith /* 487153dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 487253dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 487353dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 487453dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 487553dd7562SDmitry Karpeev */ 487653dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 487753dd7562SDmitry Karpeev { 487853dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 487953dd7562SDmitry Karpeev PetscErrorCode ierr; 488053dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 488153dd7562SDmitry Karpeev PetscBool seqaij; 488253dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 488353dd7562SDmitry Karpeev PetscScalar v; 488453dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 488553dd7562SDmitry Karpeev 488653dd7562SDmitry Karpeev PetscFunctionBegin; 488753dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 488853dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 48894099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 489053dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 489153dd7562SDmitry Karpeev if (rowemb) { 489253dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 489353dd7562SDmitry Karpeev if (m != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Row IS of size %D is incompatible with matrix row size %D",m,B->rmap->n); 489453dd7562SDmitry Karpeev } else { 48956c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 489653dd7562SDmitry Karpeev } 489753dd7562SDmitry Karpeev if (colemb) { 489853dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 489953dd7562SDmitry Karpeev if (n != B->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Diag col IS of size %D is incompatible with input matrix col size %D",n,B->cmap->n); 490053dd7562SDmitry Karpeev } else { 490153dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 490253dd7562SDmitry Karpeev } 490353dd7562SDmitry Karpeev 490453dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 490553dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 490653dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 490753dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 490853dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 490953dd7562SDmitry Karpeev } 491053dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 491153dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 491253dd7562SDmitry Karpeev } 491353dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 491453dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 491553dd7562SDmitry Karpeev } 491653dd7562SDmitry Karpeev count = 0; 491753dd7562SDmitry Karpeev rowindices = NULL; 491853dd7562SDmitry Karpeev colindices = NULL; 491953dd7562SDmitry Karpeev if (rowemb) { 492053dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 492153dd7562SDmitry Karpeev } 492253dd7562SDmitry Karpeev if (colemb) { 492353dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 492453dd7562SDmitry Karpeev } 492553dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 492653dd7562SDmitry Karpeev PetscInt row; 492753dd7562SDmitry Karpeev row = i; 492853dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 492953dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 493053dd7562SDmitry Karpeev PetscInt col; 493153dd7562SDmitry Karpeev col = Baij->j[count]; 493253dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 493353dd7562SDmitry Karpeev v = Baij->a[count]; 493453dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 493553dd7562SDmitry Karpeev ++count; 493653dd7562SDmitry Karpeev } 493753dd7562SDmitry Karpeev } 493853dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 493953dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 494053dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 494153dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 494253dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 494353dd7562SDmitry Karpeev PetscFunctionReturn(0); 494453dd7562SDmitry Karpeev } 494553dd7562SDmitry Karpeev 49464099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 49474099cc6bSBarry Smith 49484099cc6bSBarry Smith /*@C 49494099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 49504099cc6bSBarry Smith 49514099cc6bSBarry Smith Collective on Mat 49524099cc6bSBarry Smith 49534099cc6bSBarry Smith Input Parameters: 49544099cc6bSBarry Smith + mat - the matrix object 49554099cc6bSBarry Smith - matype - matrix type 49564099cc6bSBarry Smith 49574099cc6bSBarry Smith Options Database Key: 49584099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 49594099cc6bSBarry Smith 49604099cc6bSBarry Smith 49614099cc6bSBarry Smith Level: intermediate 49624099cc6bSBarry Smith 49634099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 49644099cc6bSBarry Smith @*/ 49654099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 49664099cc6bSBarry Smith { 4967fd9d3c67SJed Brown PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*); 49684099cc6bSBarry Smith PetscBool sametype; 49694099cc6bSBarry Smith 49704099cc6bSBarry Smith PetscFunctionBegin; 49714099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 49724099cc6bSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 49734099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 49744099cc6bSBarry Smith 49754099cc6bSBarry Smith ierr = PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr); 49764099cc6bSBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 49774099cc6bSBarry Smith ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 49784099cc6bSBarry Smith PetscFunctionReturn(0); 49794099cc6bSBarry Smith } 49804099cc6bSBarry Smith 49814099cc6bSBarry Smith 49824099cc6bSBarry Smith /*@C 49834099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 49844099cc6bSBarry Smith 49854099cc6bSBarry Smith Not Collective 49864099cc6bSBarry Smith 49874099cc6bSBarry Smith Input Parameters: 49884099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 49894099cc6bSBarry Smith - function - routine to convert to subtype 49904099cc6bSBarry Smith 49914099cc6bSBarry Smith Notes: 49924099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 49934099cc6bSBarry Smith 49944099cc6bSBarry Smith 49954099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 49964099cc6bSBarry Smith $ -mat_seqaij_type my_mat 49974099cc6bSBarry Smith 49984099cc6bSBarry Smith Level: advanced 49994099cc6bSBarry Smith 50004099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 50014099cc6bSBarry Smith 50024099cc6bSBarry Smith 50034099cc6bSBarry Smith Level: advanced 50044099cc6bSBarry Smith @*/ 5005388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 50064099cc6bSBarry Smith { 50074099cc6bSBarry Smith PetscErrorCode ierr; 50084099cc6bSBarry Smith 50094099cc6bSBarry Smith PetscFunctionBegin; 50109cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 50114099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 50124099cc6bSBarry Smith PetscFunctionReturn(0); 50134099cc6bSBarry Smith } 50144099cc6bSBarry Smith 50154099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 50164099cc6bSBarry Smith 50174099cc6bSBarry Smith /*@C 50184099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 50194099cc6bSBarry Smith 50204099cc6bSBarry Smith Not Collective 50214099cc6bSBarry Smith 50224099cc6bSBarry Smith Level: advanced 50234099cc6bSBarry Smith 50244099cc6bSBarry Smith Developers Note: CUSP and CUSPARSE do not yet support the MatConvert_SeqAIJ..() paradigm and thus cannot be registered here 50254099cc6bSBarry Smith 50264099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 50274099cc6bSBarry Smith @*/ 50284099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 50294099cc6bSBarry Smith { 50304099cc6bSBarry Smith PetscErrorCode ierr; 50314099cc6bSBarry Smith 50324099cc6bSBarry Smith PetscFunctionBegin; 50334099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 50344099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 50354099cc6bSBarry Smith 50364099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 50374099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 50384dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 50399779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 50406b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 5041485f9817SRichard Tran Mills #endif 50424099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 50434099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 50444099cc6bSBarry Smith #endif 50454099cc6bSBarry Smith PetscFunctionReturn(0); 50464099cc6bSBarry Smith } 504753dd7562SDmitry Karpeev 504853dd7562SDmitry Karpeev /* 504981824310SBarry Smith Special version for direct calls from Fortran 505081824310SBarry Smith */ 5051af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 505281824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 505381824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 505481824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 505581824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 505681824310SBarry Smith #endif 505781824310SBarry Smith 505881824310SBarry Smith /* Change these macros so can be used in void function */ 505981824310SBarry Smith #undef CHKERRQ 5060ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 506181824310SBarry Smith #undef SETERRQ2 5062e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 50634994cf47SJed Brown #undef SETERRQ3 50644994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 506581824310SBarry Smith 506619caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 506781824310SBarry Smith { 506881824310SBarry Smith Mat A = *AA; 506981824310SBarry Smith PetscInt m = *mm, n = *nn; 507081824310SBarry Smith InsertMode is = *isis; 507181824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 507281824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 507381824310SBarry Smith PetscInt *imax,*ai,*ailen; 507481824310SBarry Smith PetscErrorCode ierr; 507581824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 507654f21887SBarry Smith MatScalar *ap,value,*aa; 5077ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5078ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 507981824310SBarry Smith 508081824310SBarry Smith PetscFunctionBegin; 50814994cf47SJed Brown MatCheckPreallocated(A,1); 508281824310SBarry Smith imax = a->imax; 508381824310SBarry Smith ai = a->i; 508481824310SBarry Smith ailen = a->ilen; 508581824310SBarry Smith aj = a->j; 508681824310SBarry Smith aa = a->a; 508781824310SBarry Smith 508881824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 508981824310SBarry Smith row = im[k]; 509081824310SBarry Smith if (row < 0) continue; 509181824310SBarry Smith #if defined(PETSC_USE_DEBUG) 5092ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 509381824310SBarry Smith #endif 509481824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 509581824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 509681824310SBarry Smith low = 0; 509781824310SBarry Smith high = nrow; 509881824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 509981824310SBarry Smith if (in[l] < 0) continue; 510081824310SBarry Smith #if defined(PETSC_USE_DEBUG) 5101ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 510281824310SBarry Smith #endif 510381824310SBarry Smith col = in[l]; 51042205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 51052205254eSKarl Rupp else value = v[k + l*m]; 51062205254eSKarl Rupp 510781824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 510881824310SBarry Smith 51092205254eSKarl Rupp if (col <= lastcol) low = 0; 51102205254eSKarl Rupp else high = nrow; 511181824310SBarry Smith lastcol = col; 511281824310SBarry Smith while (high-low > 5) { 511381824310SBarry Smith t = (low+high)/2; 511481824310SBarry Smith if (rp[t] > col) high = t; 511581824310SBarry Smith else low = t; 511681824310SBarry Smith } 511781824310SBarry Smith for (i=low; i<high; i++) { 511881824310SBarry Smith if (rp[i] > col) break; 511981824310SBarry Smith if (rp[i] == col) { 512081824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 512181824310SBarry Smith else ap[i] = value; 512281824310SBarry Smith goto noinsert; 512381824310SBarry Smith } 512481824310SBarry Smith } 512581824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 512681824310SBarry Smith if (nonew == 1) goto noinsert; 5127ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5128fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 512981824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 513081824310SBarry Smith /* shift up all the later entries in this row */ 513181824310SBarry Smith for (ii=N; ii>=i; ii--) { 513281824310SBarry Smith rp[ii+1] = rp[ii]; 513381824310SBarry Smith ap[ii+1] = ap[ii]; 513481824310SBarry Smith } 513581824310SBarry Smith rp[i] = col; 513681824310SBarry Smith ap[i] = value; 5137e56f5c9eSBarry Smith A->nonzerostate++; 513881824310SBarry Smith noinsert:; 513981824310SBarry Smith low = i + 1; 514081824310SBarry Smith } 514181824310SBarry Smith ailen[row] = nrow; 514281824310SBarry Smith } 514381824310SBarry Smith PetscFunctionReturnVoid(); 514481824310SBarry Smith } 5145