1d5d45c9bSBarry Smith /* 23369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 3d5d45c9bSBarry Smith matrix storage format. 4d5d45c9bSBarry Smith */ 53369ce9aSBarry Smith 67c4f633dSBarry Smith 7c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 8c6db04a5SJed Brown #include <petscblaslapack.h> 9c6db04a5SJed Brown #include <petscbt.h> 10af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h> 110716a85fSBarry Smith 124099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetTypeFromOptions(Mat A) 134099cc6bSBarry Smith { 144099cc6bSBarry Smith PetscErrorCode ierr; 154099cc6bSBarry Smith PetscBool flg; 164099cc6bSBarry Smith char type[256]; 174099cc6bSBarry Smith 184099cc6bSBarry Smith PetscFunctionBegin; 194099cc6bSBarry Smith ierr = PetscObjectOptionsBegin((PetscObject)A); 204099cc6bSBarry Smith ierr = PetscOptionsFList("-mat_seqaij_type","Matrix SeqAIJ type","MatSeqAIJSetType",MatSeqAIJList,"seqaij",type,256,&flg);CHKERRQ(ierr); 214099cc6bSBarry Smith if (flg) { 224099cc6bSBarry Smith ierr = MatSeqAIJSetType(A,type);CHKERRQ(ierr); 234099cc6bSBarry Smith } 244099cc6bSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 254099cc6bSBarry Smith PetscFunctionReturn(0); 264099cc6bSBarry Smith } 274099cc6bSBarry Smith 280716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms) 290716a85fSBarry Smith { 300716a85fSBarry Smith PetscErrorCode ierr; 310716a85fSBarry Smith PetscInt i,m,n; 320716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 330716a85fSBarry Smith 340716a85fSBarry Smith PetscFunctionBegin; 350716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 36580bdb30SBarry Smith ierr = PetscArrayzero(norms,n);CHKERRQ(ierr); 370716a85fSBarry Smith if (type == NORM_2) { 380716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 390716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 400716a85fSBarry Smith } 410716a85fSBarry Smith } else if (type == NORM_1) { 420716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 430716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]); 440716a85fSBarry Smith } 450716a85fSBarry Smith } else if (type == NORM_INFINITY) { 460716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 470716a85fSBarry Smith norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]); 480716a85fSBarry Smith } 490716a85fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType"); 500716a85fSBarry Smith 510716a85fSBarry Smith if (type == NORM_2) { 528f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 530716a85fSBarry Smith } 540716a85fSBarry Smith PetscFunctionReturn(0); 550716a85fSBarry Smith } 560716a85fSBarry Smith 573a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 583a062f41SBarry Smith { 593a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 603a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 613a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 623a062f41SBarry Smith PetscInt *rows; 633a062f41SBarry Smith PetscErrorCode ierr; 643a062f41SBarry Smith 653a062f41SBarry Smith PetscFunctionBegin; 663a062f41SBarry Smith for (i=0; i<m; i++) { 673a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 683a062f41SBarry Smith cnt++; 693a062f41SBarry Smith } 703a062f41SBarry Smith } 713a062f41SBarry Smith ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 723a062f41SBarry Smith cnt = 0; 733a062f41SBarry Smith for (i=0; i<m; i++) { 743a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 753a062f41SBarry Smith rows[cnt] = i; 763a062f41SBarry Smith cnt++; 773a062f41SBarry Smith } 783a062f41SBarry Smith } 793a062f41SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr); 803a062f41SBarry Smith PetscFunctionReturn(0); 813a062f41SBarry Smith } 823a062f41SBarry Smith 83f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 846ce1633cSBarry Smith { 856ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 866ce1633cSBarry Smith const MatScalar *aa = a->a; 876ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 88b2db7409Sstefano_zampini const PetscInt *ii = a->i,*jj = a->j,*diag; 896ce1633cSBarry Smith PetscInt *rows; 906ce1633cSBarry Smith PetscErrorCode ierr; 916ce1633cSBarry Smith 926ce1633cSBarry Smith PetscFunctionBegin; 936ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 946ce1633cSBarry Smith diag = a->diag; 956ce1633cSBarry Smith for (i=0; i<m; i++) { 96b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 976ce1633cSBarry Smith cnt++; 986ce1633cSBarry Smith } 996ce1633cSBarry Smith } 100785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 1016ce1633cSBarry Smith cnt = 0; 1026ce1633cSBarry Smith for (i=0; i<m; i++) { 103b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1046ce1633cSBarry Smith rows[cnt++] = i; 1056ce1633cSBarry Smith } 1066ce1633cSBarry Smith } 107f1f41ecbSJed Brown *nrows = cnt; 108f1f41ecbSJed Brown *zrows = rows; 109f1f41ecbSJed Brown PetscFunctionReturn(0); 110f1f41ecbSJed Brown } 111f1f41ecbSJed Brown 112f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 113f1f41ecbSJed Brown { 114f1f41ecbSJed Brown PetscInt nrows,*rows; 115f1f41ecbSJed Brown PetscErrorCode ierr; 116f1f41ecbSJed Brown 117f1f41ecbSJed Brown PetscFunctionBegin; 1180298fd71SBarry Smith *zrows = NULL; 119f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 120ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1216ce1633cSBarry Smith PetscFunctionReturn(0); 1226ce1633cSBarry Smith } 1236ce1633cSBarry Smith 124b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 125b3a44c85SBarry Smith { 126b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 127b3a44c85SBarry Smith const MatScalar *aa; 128b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 129b3a44c85SBarry Smith const PetscInt *ii; 130b3a44c85SBarry Smith PetscInt n,i,j,*rows; 131b3a44c85SBarry Smith PetscErrorCode ierr; 132b3a44c85SBarry Smith 133b3a44c85SBarry Smith PetscFunctionBegin; 1342e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 135f4259b30SLisandro Dalcin *keptrows = NULL; 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 } 1432e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 144b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 145b3a44c85SBarry Smith } 146b3a44c85SBarry Smith cnt++; 147b3a44c85SBarry Smith ok1:; 148b3a44c85SBarry Smith } 1492e5835c6SStefano Zampini if (!cnt) { 1502e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 1512e5835c6SStefano Zampini PetscFunctionReturn(0); 1522e5835c6SStefano Zampini } 153854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr); 154b3a44c85SBarry Smith cnt = 0; 155b3a44c85SBarry Smith for (i=0; i<m; i++) { 156b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 157b3a44c85SBarry Smith if (!n) continue; 1582e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 159b3a44c85SBarry Smith if (aa[j] != 0.0) { 160b3a44c85SBarry Smith rows[cnt++] = i; 161b3a44c85SBarry Smith break; 162b3a44c85SBarry Smith } 163b3a44c85SBarry Smith } 164b3a44c85SBarry Smith } 1652e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 166b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 167b3a44c85SBarry Smith PetscFunctionReturn(0); 168b3a44c85SBarry Smith } 169b3a44c85SBarry Smith 1707087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 17179299369SBarry Smith { 17279299369SBarry Smith PetscErrorCode ierr; 17379299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 17499e65526SBarry Smith PetscInt i,m = Y->rmap->n; 17599e65526SBarry Smith const PetscInt *diag; 1762e5835c6SStefano Zampini MatScalar *aa; 17799e65526SBarry Smith const PetscScalar *v; 178ace3abfcSBarry Smith PetscBool missing; 1798c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 180837a59e1SRichard Tran Mills PetscBool inserted = PETSC_FALSE; 181837a59e1SRichard Tran Mills #endif 18279299369SBarry Smith 18379299369SBarry Smith PetscFunctionBegin; 18409f38230SBarry Smith if (Y->assembled) { 1850298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 18609f38230SBarry Smith if (!missing) { 18779299369SBarry Smith diag = aij->diag; 18899e65526SBarry Smith ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr); 1892e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(Y,&aa);CHKERRQ(ierr); 19079299369SBarry Smith if (is == INSERT_VALUES) { 1918c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 192837a59e1SRichard Tran Mills inserted = PETSC_TRUE; 193837a59e1SRichard Tran Mills #endif 19479299369SBarry Smith for (i=0; i<m; i++) { 19579299369SBarry Smith aa[diag[i]] = v[i]; 19679299369SBarry Smith } 19779299369SBarry Smith } else { 19879299369SBarry Smith for (i=0; i<m; i++) { 1998c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 200837a59e1SRichard Tran Mills if (v[i] != 0.0) inserted = PETSC_TRUE; 201837a59e1SRichard Tran Mills #endif 20279299369SBarry Smith aa[diag[i]] += v[i]; 20379299369SBarry Smith } 20479299369SBarry Smith } 2052e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(Y,&aa);CHKERRQ(ierr); 2068c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 207837a59e1SRichard Tran Mills if (inserted) Y->offloadmask = PETSC_OFFLOAD_CPU; 208837a59e1SRichard Tran Mills #endif 20999e65526SBarry Smith ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr); 21079299369SBarry Smith PetscFunctionReturn(0); 21179299369SBarry Smith } 212acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 21309f38230SBarry Smith } 21409f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 21509f38230SBarry Smith PetscFunctionReturn(0); 21609f38230SBarry Smith } 21779299369SBarry Smith 2181a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 21917ab2063SBarry Smith { 220416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 221dfbe8321SBarry Smith PetscErrorCode ierr; 22297f1f81fSBarry Smith PetscInt i,ishift; 22317ab2063SBarry Smith 2243a40ed3dSBarry Smith PetscFunctionBegin; 225d0f46423SBarry Smith *m = A->rmap->n; 2263a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 227bfeeae90SHong Zhang ishift = 0; 22853e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 2292462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 230bfeeae90SHong Zhang } else if (oshift == 1) { 2311a83f524SJed Brown PetscInt *tia; 232d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2333b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 234854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr); 2351a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2361a83f524SJed Brown *ia = tia; 237ecc77c7aSBarry Smith if (ja) { 2381a83f524SJed Brown PetscInt *tja; 239854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr); 2401a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2411a83f524SJed Brown *ja = tja; 242ecc77c7aSBarry Smith } 2436945ee14SBarry Smith } else { 244ecc77c7aSBarry Smith *ia = a->i; 245ecc77c7aSBarry Smith if (ja) *ja = a->j; 246a2ce50c7SBarry Smith } 2473a40ed3dSBarry Smith PetscFunctionReturn(0); 248a2744918SBarry Smith } 249a2744918SBarry Smith 2501a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2516945ee14SBarry Smith { 252dfbe8321SBarry Smith PetscErrorCode ierr; 2536945ee14SBarry Smith 2543a40ed3dSBarry Smith PetscFunctionBegin; 2553a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 256bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 257606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 258ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 259bcd2baecSBarry Smith } 2603a40ed3dSBarry Smith PetscFunctionReturn(0); 26117ab2063SBarry Smith } 26217ab2063SBarry Smith 2631a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2643b2fbd54SBarry Smith { 2653b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 266dfbe8321SBarry Smith PetscErrorCode ierr; 267d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 26897f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2693b2fbd54SBarry Smith 2703a40ed3dSBarry Smith PetscFunctionBegin; 271899cda47SBarry Smith *nn = n; 2723a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2733b2fbd54SBarry Smith if (symmetric) { 2742462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2753b2fbd54SBarry Smith } else { 276b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 277854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 278b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 2793b2fbd54SBarry Smith jj = a->j; 2803b2fbd54SBarry Smith for (i=0; i<nz; i++) { 281bfeeae90SHong Zhang collengths[jj[i]]++; 2823b2fbd54SBarry Smith } 2833b2fbd54SBarry Smith cia[0] = oshift; 2843b2fbd54SBarry Smith for (i=0; i<n; i++) { 2853b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2863b2fbd54SBarry Smith } 287580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 2883b2fbd54SBarry Smith jj = a->j; 289a93ec695SBarry Smith for (row=0; row<m; row++) { 290a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 291a93ec695SBarry Smith for (i=0; i<mr; i++) { 292bfeeae90SHong Zhang col = *jj++; 2932205254eSKarl Rupp 2943b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2953b2fbd54SBarry Smith } 2963b2fbd54SBarry Smith } 297606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2983b2fbd54SBarry Smith *ia = cia; *ja = cja; 2993b2fbd54SBarry Smith } 3003a40ed3dSBarry Smith PetscFunctionReturn(0); 3013b2fbd54SBarry Smith } 3023b2fbd54SBarry Smith 3031a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 3043b2fbd54SBarry Smith { 305dfbe8321SBarry Smith PetscErrorCode ierr; 306606d414cSSatish Balay 3073a40ed3dSBarry Smith PetscFunctionBegin; 3083a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 3093b2fbd54SBarry Smith 310606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 311606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 3123a40ed3dSBarry Smith PetscFunctionReturn(0); 3133b2fbd54SBarry Smith } 3143b2fbd54SBarry Smith 3157cee066cSHong Zhang /* 3167cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 3177cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 318040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 3197cee066cSHong Zhang */ 3207cee066cSHong 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) 3217cee066cSHong Zhang { 3227cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3237cee066cSHong Zhang PetscErrorCode ierr; 3247cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 325071fcb05SBarry Smith PetscInt nz = a->i[m],row,mr,col,tmp; 3267cee066cSHong Zhang PetscInt *cspidx; 327071fcb05SBarry Smith const PetscInt *jj; 3287cee066cSHong Zhang 3297cee066cSHong Zhang PetscFunctionBegin; 3307cee066cSHong Zhang *nn = n; 3317cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 332625f6d37SHong Zhang 333b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 334854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 335b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 336b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cspidx);CHKERRQ(ierr); 3377cee066cSHong Zhang jj = a->j; 3387cee066cSHong Zhang for (i=0; i<nz; i++) { 3397cee066cSHong Zhang collengths[jj[i]]++; 3407cee066cSHong Zhang } 3417cee066cSHong Zhang cia[0] = oshift; 3427cee066cSHong Zhang for (i=0; i<n; i++) { 3437cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3447cee066cSHong Zhang } 345580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 3467cee066cSHong Zhang jj = a->j; 3477cee066cSHong Zhang for (row=0; row<m; row++) { 3487cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3497cee066cSHong Zhang for (i=0; i<mr; i++) { 3507cee066cSHong Zhang col = *jj++; 351071fcb05SBarry Smith tmp = cia[col] + collengths[col]++ - oshift; 352071fcb05SBarry Smith cspidx[tmp] = a->i[row] + i; /* index of a->j */ 353071fcb05SBarry Smith cja[tmp] = row + oshift; 3547cee066cSHong Zhang } 3557cee066cSHong Zhang } 3567cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 357071fcb05SBarry Smith *ia = cia; 358071fcb05SBarry Smith *ja = cja; 3597cee066cSHong Zhang *spidx = cspidx; 3607cee066cSHong Zhang PetscFunctionReturn(0); 3617cee066cSHong Zhang } 3627cee066cSHong Zhang 3637cee066cSHong 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) 3647cee066cSHong Zhang { 3657cee066cSHong Zhang PetscErrorCode ierr; 3667cee066cSHong Zhang 3677cee066cSHong Zhang PetscFunctionBegin; 3685243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3697cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3707cee066cSHong Zhang PetscFunctionReturn(0); 3717cee066cSHong Zhang } 3727cee066cSHong Zhang 37387d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 37487d4246cSBarry Smith { 37587d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 37687d4246cSBarry Smith PetscInt *ai = a->i; 37787d4246cSBarry Smith PetscErrorCode ierr; 37887d4246cSBarry Smith 37987d4246cSBarry Smith PetscFunctionBegin; 380580bdb30SBarry Smith ierr = PetscArraycpy(a->a+ai[row],v,ai[row+1]-ai[row]);CHKERRQ(ierr); 3818c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 382c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && ai[row+1]-ai[row]) A->offloadmask = PETSC_OFFLOAD_CPU; 383e2cf4d64SStefano Zampini #endif 38487d4246cSBarry Smith PetscFunctionReturn(0); 38587d4246cSBarry Smith } 38687d4246cSBarry Smith 387bd04181cSBarry Smith /* 388bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 389bd04181cSBarry Smith 390bd04181cSBarry Smith - a single row of values is set with each call 391bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 392bd04181cSBarry Smith - the values are always added to the matrix, not set 393bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 394bd04181cSBarry Smith 3951f763a69SBarry Smith This does NOT assume the global column indices are sorted 396bd04181cSBarry Smith 3971f763a69SBarry Smith */ 398bd04181cSBarry Smith 399af0996ceSBarry Smith #include <petsc/private/isimpl.h> 400189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 401189e4007SBarry Smith { 402189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4031f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 4041f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 4051f763a69SBarry Smith PetscInt lastcol = -1; 406189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 407189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 408189e4007SBarry Smith 409f38dd0b8SBarry Smith row = ridx[im[0]]; 4101f763a69SBarry Smith rp = aj + ai[row]; 4111f763a69SBarry Smith ap = aa + ai[row]; 4121f763a69SBarry Smith nrow = ailen[row]; 413189e4007SBarry Smith low = 0; 414189e4007SBarry Smith high = nrow; 415189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 416189e4007SBarry Smith col = cidx[in[l]]; 417f38dd0b8SBarry Smith value = v[l]; 418189e4007SBarry Smith 419189e4007SBarry Smith if (col <= lastcol) low = 0; 420189e4007SBarry Smith else high = nrow; 421189e4007SBarry Smith lastcol = col; 422189e4007SBarry Smith while (high-low > 5) { 423189e4007SBarry Smith t = (low+high)/2; 424189e4007SBarry Smith if (rp[t] > col) high = t; 425189e4007SBarry Smith else low = t; 426189e4007SBarry Smith } 427189e4007SBarry Smith for (i=low; i<high; i++) { 428189e4007SBarry Smith if (rp[i] == col) { 4291f763a69SBarry Smith ap[i] += value; 430189e4007SBarry Smith low = i + 1; 4311f763a69SBarry Smith break; 432189e4007SBarry Smith } 433189e4007SBarry Smith } 434189e4007SBarry Smith } 4358c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 436c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 437e2cf4d64SStefano Zampini #endif 438f38dd0b8SBarry Smith return 0; 439189e4007SBarry Smith } 440189e4007SBarry Smith 44197f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 44217ab2063SBarry Smith { 443416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 444e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 44597f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 4466849ba73SBarry Smith PetscErrorCode ierr; 447e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 448ce496241SStefano Zampini MatScalar *ap=NULL,value=0.0,*aa; 449ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 450ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 4518c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 452e2cf4d64SStefano Zampini PetscBool inserted = PETSC_FALSE; 453e2cf4d64SStefano Zampini #endif 45417ab2063SBarry Smith 4553a40ed3dSBarry Smith PetscFunctionBegin; 456ce496241SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 457ce496241SStefano Zampini if (A->offloadmask == PETSC_OFFLOAD_GPU) { 458ce496241SStefano Zampini const PetscScalar *dummy; 459ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&dummy);CHKERRQ(ierr); 460ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&dummy);CHKERRQ(ierr); 461ce496241SStefano Zampini } 462ce496241SStefano Zampini #endif 463ce496241SStefano Zampini aa = a->a; 46417ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 465416022c9SBarry Smith row = im[k]; 4665ef9f2a5SBarry Smith if (row < 0) continue; 467cf9c20a2SJed Brown if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1); 468720833daSHong Zhang rp = aj + ai[row]; 469876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 47017ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 471416022c9SBarry Smith low = 0; 472c71e6ed7SBarry Smith high = nrow; 47317ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4745ef9f2a5SBarry Smith if (in[l] < 0) continue; 475cf9c20a2SJed Brown if (PetscUnlikelyDebug(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); 476bfeeae90SHong Zhang col = in[l]; 477071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 478071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 47936db0b34SBarry Smith 4802205254eSKarl Rupp if (col <= lastcol) low = 0; 4812205254eSKarl Rupp else high = nrow; 482e2ee6c50SBarry Smith lastcol = col; 483416022c9SBarry Smith while (high-low > 5) { 484416022c9SBarry Smith t = (low+high)/2; 485416022c9SBarry Smith if (rp[t] > col) high = t; 486416022c9SBarry Smith else low = t; 48717ab2063SBarry Smith } 488416022c9SBarry Smith for (i=low; i<high; i++) { 48917ab2063SBarry Smith if (rp[i] > col) break; 49017ab2063SBarry Smith if (rp[i] == col) { 491876c6284SHong Zhang if (!A->structure_only) { 4920c0d7e18SFande Kong if (is == ADD_VALUES) { 4930c0d7e18SFande Kong ap[i] += value; 4940c0d7e18SFande Kong (void)PetscLogFlops(1.0); 4950c0d7e18SFande Kong } 49617ab2063SBarry Smith else ap[i] = value; 4978c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 498e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 499e2cf4d64SStefano Zampini #endif 500720833daSHong Zhang } 501e44c0bd4SBarry Smith low = i + 1; 50217ab2063SBarry Smith goto noinsert; 50317ab2063SBarry Smith } 50417ab2063SBarry Smith } 505dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 506c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 507e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 508720833daSHong Zhang if (A->structure_only) { 509876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 510720833daSHong Zhang } else { 511fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 512720833daSHong Zhang } 513c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 514416022c9SBarry Smith /* shift up all the later entries in this row */ 515580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 51617ab2063SBarry Smith rp[i] = col; 517580bdb30SBarry Smith if (!A->structure_only){ 518580bdb30SBarry Smith ierr = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr); 519580bdb30SBarry Smith ap[i] = value; 520580bdb30SBarry Smith } 521416022c9SBarry Smith low = i + 1; 522e56f5c9eSBarry Smith A->nonzerostate++; 5238c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 524e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 525e2cf4d64SStefano Zampini #endif 526e44c0bd4SBarry Smith noinsert:; 52717ab2063SBarry Smith } 52817ab2063SBarry Smith ailen[row] = nrow; 52917ab2063SBarry Smith } 5308c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 531c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && inserted) A->offloadmask = PETSC_OFFLOAD_CPU; 532e2cf4d64SStefano Zampini #endif 5333a40ed3dSBarry Smith PetscFunctionReturn(0); 53417ab2063SBarry Smith } 53517ab2063SBarry Smith 53619b08ed1SBarry Smith 53719b08ed1SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFullNoPreallocation(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 53819b08ed1SBarry Smith { 53919b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 54019b08ed1SBarry Smith PetscInt *rp,k,row; 54119b08ed1SBarry Smith PetscInt *ai = a->i; 54219b08ed1SBarry Smith PetscErrorCode ierr; 54319b08ed1SBarry Smith PetscInt *aj = a->j; 54419b08ed1SBarry Smith MatScalar *aa = a->a,*ap; 54519b08ed1SBarry Smith 54619b08ed1SBarry Smith PetscFunctionBegin; 54719b08ed1SBarry Smith if (A->was_assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call on assembled matrix."); 54819b08ed1SBarry Smith if (m*n+a->nz > a->maxnz) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of entries in matrix will be larger than maximum nonzeros allocated for %D in MatSeqAIJSetTotalPreallocation()",a->maxnz); 54919b08ed1SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 55019b08ed1SBarry Smith row = im[k]; 55119b08ed1SBarry Smith rp = aj + ai[row]; 55219b08ed1SBarry Smith ap = aa + ai[row]; 55319b08ed1SBarry Smith 55419b08ed1SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 55519b08ed1SBarry Smith if (!A->structure_only) { 55619b08ed1SBarry Smith if (v) { 55719b08ed1SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 55819b08ed1SBarry Smith v += n; 55919b08ed1SBarry Smith } else { 56019b08ed1SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 56119b08ed1SBarry Smith } 56219b08ed1SBarry Smith } 56319b08ed1SBarry Smith a->ilen[row] = n; 56419b08ed1SBarry Smith a->imax[row] = n; 56519b08ed1SBarry Smith a->i[row+1] = a->i[row]+n; 56619b08ed1SBarry Smith a->nz += n; 56719b08ed1SBarry Smith } 5688c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 56919b08ed1SBarry Smith if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 57019b08ed1SBarry Smith #endif 57119b08ed1SBarry Smith PetscFunctionReturn(0); 57219b08ed1SBarry Smith } 57319b08ed1SBarry Smith 57419b08ed1SBarry Smith /*@ 57519b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation - Sets an upper bound on the total number of expected nonzeros in the matrix. 57619b08ed1SBarry Smith 57719b08ed1SBarry Smith Input Parameters: 57819b08ed1SBarry Smith + A - the SeqAIJ matrix 57919b08ed1SBarry Smith - nztotal - bound on the number of nonzeros 58019b08ed1SBarry Smith 58119b08ed1SBarry Smith Level: advanced 58219b08ed1SBarry Smith 58319b08ed1SBarry Smith Notes: 58419b08ed1SBarry Smith This can be called if you will be provided the matrix row by row (from row zero) with sorted column indices for each row. 58519b08ed1SBarry Smith Simply call MatSetValues() after this call to provide the matrix entries in the usual manner. This matrix may be used 58619b08ed1SBarry Smith as always with multiple matrix assemblies. 58719b08ed1SBarry Smith 58819b08ed1SBarry Smith .seealso: MatSetOption(), MAT_SORTED_FULL, MatSetValues(), MatSeqAIJSetPreallocation() 58919b08ed1SBarry Smith @*/ 59019b08ed1SBarry Smith 59119b08ed1SBarry Smith PetscErrorCode MatSeqAIJSetTotalPreallocation(Mat A,PetscInt nztotal) 59219b08ed1SBarry Smith { 59319b08ed1SBarry Smith PetscErrorCode ierr; 59419b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 59519b08ed1SBarry Smith 59619b08ed1SBarry Smith PetscFunctionBegin; 59719b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 59819b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 59919b08ed1SBarry Smith a->maxnz = nztotal; 60019b08ed1SBarry Smith if (!a->imax) { 60119b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->imax);CHKERRQ(ierr); 60219b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 60319b08ed1SBarry Smith } 60419b08ed1SBarry Smith if (!a->ilen) { 60519b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->ilen);CHKERRQ(ierr); 60619b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 60719b08ed1SBarry Smith } else { 60819b08ed1SBarry Smith ierr = PetscMemzero(a->ilen,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 60919b08ed1SBarry Smith } 61019b08ed1SBarry Smith 61119b08ed1SBarry Smith /* allocate the matrix space */ 61219b08ed1SBarry Smith if (A->structure_only) { 61319b08ed1SBarry Smith ierr = PetscMalloc1(nztotal,&a->j);CHKERRQ(ierr); 61419b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&a->i);CHKERRQ(ierr); 61519b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*sizeof(PetscInt));CHKERRQ(ierr); 61619b08ed1SBarry Smith } else { 61719b08ed1SBarry Smith ierr = PetscMalloc3(nztotal,&a->a,nztotal,&a->j,A->rmap->n+1,&a->i);CHKERRQ(ierr); 61819b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 61919b08ed1SBarry Smith } 62019b08ed1SBarry Smith a->i[0] = 0; 62119b08ed1SBarry Smith if (A->structure_only) { 62219b08ed1SBarry Smith a->singlemalloc = PETSC_FALSE; 62319b08ed1SBarry Smith a->free_a = PETSC_FALSE; 62419b08ed1SBarry Smith } else { 62519b08ed1SBarry Smith a->singlemalloc = PETSC_TRUE; 62619b08ed1SBarry Smith a->free_a = PETSC_TRUE; 62719b08ed1SBarry Smith } 62819b08ed1SBarry Smith a->free_ij = PETSC_TRUE; 62919b08ed1SBarry Smith A->ops->setvalues = MatSetValues_SeqAIJ_SortedFullNoPreallocation; 63019b08ed1SBarry Smith A->preallocated = PETSC_TRUE; 63119b08ed1SBarry Smith PetscFunctionReturn(0); 63219b08ed1SBarry Smith } 63319b08ed1SBarry Smith 634071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 635071fcb05SBarry Smith { 636071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 637071fcb05SBarry Smith PetscInt *rp,k,row; 638071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 639071fcb05SBarry Smith PetscErrorCode ierr; 640071fcb05SBarry Smith PetscInt *aj = a->j; 641071fcb05SBarry Smith MatScalar *aa = a->a,*ap; 642071fcb05SBarry Smith 643071fcb05SBarry Smith PetscFunctionBegin; 644071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 645071fcb05SBarry Smith row = im[k]; 64619b08ed1SBarry Smith if (PetscUnlikelyDebug(n > a->imax[row])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Preallocation for row %D does not match number of columns provided",n); 647071fcb05SBarry Smith rp = aj + ai[row]; 648071fcb05SBarry Smith ap = aa + ai[row]; 649071fcb05SBarry Smith if (!A->was_assembled) { 650071fcb05SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 651071fcb05SBarry Smith } 652071fcb05SBarry Smith if (!A->structure_only) { 653071fcb05SBarry Smith if (v) { 654071fcb05SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 655071fcb05SBarry Smith v += n; 656071fcb05SBarry Smith } else { 657071fcb05SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 658071fcb05SBarry Smith } 659071fcb05SBarry Smith } 660071fcb05SBarry Smith ailen[row] = n; 661071fcb05SBarry Smith a->nz += n; 662071fcb05SBarry Smith } 6638c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 664c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 665e2cf4d64SStefano Zampini #endif 666071fcb05SBarry Smith PetscFunctionReturn(0); 667071fcb05SBarry Smith } 668071fcb05SBarry Smith 66981824310SBarry Smith 670a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 6717eb43aa7SLois Curfman McInnes { 6727eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 67397f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 67497f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 67554f21887SBarry Smith MatScalar *ap,*aa = a->a; 6767eb43aa7SLois Curfman McInnes 6773a40ed3dSBarry Smith PetscFunctionBegin; 6787eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 6797eb43aa7SLois Curfman McInnes row = im[k]; 680e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 681e32f2f54SBarry 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); 682bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 6837eb43aa7SLois Curfman McInnes nrow = ailen[row]; 6847eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 685e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 686e32f2f54SBarry 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); 687bfeeae90SHong Zhang col = in[l]; 6887eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 6897eb43aa7SLois Curfman McInnes while (high-low > 5) { 6907eb43aa7SLois Curfman McInnes t = (low+high)/2; 6917eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 6927eb43aa7SLois Curfman McInnes else low = t; 6937eb43aa7SLois Curfman McInnes } 6947eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 6957eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 6967eb43aa7SLois Curfman McInnes if (rp[i] == col) { 697b49de8d1SLois Curfman McInnes *v++ = ap[i]; 6987eb43aa7SLois Curfman McInnes goto finished; 6997eb43aa7SLois Curfman McInnes } 7007eb43aa7SLois Curfman McInnes } 70197e567efSBarry Smith *v++ = 0.0; 7027eb43aa7SLois Curfman McInnes finished:; 7037eb43aa7SLois Curfman McInnes } 7047eb43aa7SLois Curfman McInnes } 7053a40ed3dSBarry Smith PetscFunctionReturn(0); 7067eb43aa7SLois Curfman McInnes } 7077eb43aa7SLois Curfman McInnes 7083ea6fe3dSLisandro Dalcin PetscErrorCode MatView_SeqAIJ_Binary(Mat mat,PetscViewer viewer) 70917ab2063SBarry Smith { 7103ea6fe3dSLisandro Dalcin Mat_SeqAIJ *A = (Mat_SeqAIJ*)mat->data; 711c898d852SStefano Zampini const PetscScalar *av; 7123ea6fe3dSLisandro Dalcin PetscInt header[4],M,N,m,nz,i; 7133ea6fe3dSLisandro Dalcin PetscInt *rowlens; 7146849ba73SBarry Smith PetscErrorCode ierr; 71517ab2063SBarry Smith 7163a40ed3dSBarry Smith PetscFunctionBegin; 7173ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 7182205254eSKarl Rupp 7193ea6fe3dSLisandro Dalcin M = mat->rmap->N; 7203ea6fe3dSLisandro Dalcin N = mat->cmap->N; 7213ea6fe3dSLisandro Dalcin m = mat->rmap->n; 7223ea6fe3dSLisandro Dalcin nz = A->nz; 723416022c9SBarry Smith 7243ea6fe3dSLisandro Dalcin /* write matrix header */ 7253ea6fe3dSLisandro Dalcin header[0] = MAT_FILE_CLASSID; 7263ea6fe3dSLisandro Dalcin header[1] = M; header[2] = N; header[3] = nz; 7273ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr); 728416022c9SBarry Smith 7293ea6fe3dSLisandro Dalcin /* fill in and store row lengths */ 7303ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(m,&rowlens);CHKERRQ(ierr); 7313ea6fe3dSLisandro Dalcin for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i]; 7323ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT);CHKERRQ(ierr); 7333ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 7343ea6fe3dSLisandro Dalcin /* store column indices */ 7353ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT);CHKERRQ(ierr); 736416022c9SBarry Smith /* store nonzero values */ 737c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(mat,&av);CHKERRQ(ierr); 738c898d852SStefano Zampini ierr = PetscViewerBinaryWrite(viewer,av,nz,PETSC_SCALAR);CHKERRQ(ierr); 739c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(mat,&av);CHKERRQ(ierr); 740b37d52dbSMark F. Adams 7413ea6fe3dSLisandro Dalcin /* write block size option to the viewer's .info file */ 7423ea6fe3dSLisandro Dalcin ierr = MatView_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 7433a40ed3dSBarry Smith PetscFunctionReturn(0); 74417ab2063SBarry Smith } 745416022c9SBarry Smith 7467dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 7477dc0baabSHong Zhang { 7487dc0baabSHong Zhang PetscErrorCode ierr; 7497dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7507dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 7517dc0baabSHong Zhang 7527dc0baabSHong Zhang PetscFunctionBegin; 7537dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7547dc0baabSHong Zhang for (i=0; i<m; i++) { 7557dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 7567dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 7577dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 7587dc0baabSHong Zhang } 7597dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 7607dc0baabSHong Zhang } 7617dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7627dc0baabSHong Zhang PetscFunctionReturn(0); 7637dc0baabSHong Zhang } 7647dc0baabSHong Zhang 76509573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 766cd155464SBarry Smith 767dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 768416022c9SBarry Smith { 769416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 770c898d852SStefano Zampini const PetscScalar *av; 771dfbe8321SBarry Smith PetscErrorCode ierr; 77260e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 773e060cb09SBarry Smith const char *name; 774f3ef73ceSBarry Smith PetscViewerFormat format; 77517ab2063SBarry Smith 7763a40ed3dSBarry Smith PetscFunctionBegin; 7777dc0baabSHong Zhang if (A->structure_only) { 7787dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 7797dc0baabSHong Zhang PetscFunctionReturn(0); 7807dc0baabSHong Zhang } 78143e49210SHong Zhang 782b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 7832e5835c6SStefano Zampini if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 7842e5835c6SStefano Zampini 785c898d852SStefano Zampini /* trigger copy to CPU if needed */ 786c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 787c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 78871c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 78997f1f81fSBarry Smith PetscInt nofinalvalue = 0; 79060e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 791c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 792d00d2cf4SBarry Smith nofinalvalue = 1; 793d00d2cf4SBarry Smith } 794d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 795d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 79677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 797fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 798fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 799fbfe6fa7SJed Brown #else 80077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 801fbfe6fa7SJed Brown #endif 802b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 80317ab2063SBarry Smith 80417ab2063SBarry Smith for (i=0; i<m; i++) { 80560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 806aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 807a9bf72d8SJed 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); 80817ab2063SBarry Smith #else 80960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 81017ab2063SBarry Smith #endif 81117ab2063SBarry Smith } 81217ab2063SBarry Smith } 813d00d2cf4SBarry Smith if (nofinalvalue) { 814c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 815c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 816c337ccceSJed Brown #else 817d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 818c337ccceSJed Brown #endif 819d00d2cf4SBarry Smith } 820317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 821fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 822d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 823fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 824d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 82544cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 82677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 82760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 828aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 82936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 83060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 83136db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 83260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 83336db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 83460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 8356831982aSBarry Smith } 83644cd7ae7SLois Curfman McInnes #else 83760e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 83844cd7ae7SLois Curfman McInnes #endif 83944cd7ae7SLois Curfman McInnes } 840b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 84144cd7ae7SLois Curfman McInnes } 842d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 843fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 84497f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 845d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 846854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 847496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 848496be53dSLois Curfman McInnes sptr[i] = nzd+1; 84960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 850496be53dSLois Curfman McInnes if (a->j[j] >= i) { 851aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 85236db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 853496be53dSLois Curfman McInnes #else 854496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 855496be53dSLois Curfman McInnes #endif 856496be53dSLois Curfman McInnes } 857496be53dSLois Curfman McInnes } 858496be53dSLois Curfman McInnes } 8592e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 86077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 8612e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 8622205254eSKarl Rupp if (i+4<m) { 8632205254eSKarl 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); 8642205254eSKarl Rupp } else if (i+3<m) { 8652205254eSKarl 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); 8662205254eSKarl Rupp } else if (i+2<m) { 8672205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 8682205254eSKarl Rupp } else if (i+1<m) { 8692205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 8702205254eSKarl Rupp } else if (i<m) { 8712205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 8722205254eSKarl Rupp } else { 8732205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 8742205254eSKarl Rupp } 875496be53dSLois Curfman McInnes } 876b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 877606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 878496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 87960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 88077431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 881496be53dSLois Curfman McInnes } 882b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 883496be53dSLois Curfman McInnes } 884b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 885496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 88660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 887496be53dSLois Curfman McInnes if (a->j[j] >= i) { 888aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 88936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 89060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8916831982aSBarry Smith } 892496be53dSLois Curfman McInnes #else 89360e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 894496be53dSLois Curfman McInnes #endif 895496be53dSLois Curfman McInnes } 896496be53dSLois Curfman McInnes } 897b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 898496be53dSLois Curfman McInnes } 899d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 900fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 90197f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 90287828ca2SBarry Smith PetscScalar value; 90368f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 90468f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 90568f1ed48SBarry Smith 90668f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 90768f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 90868f1ed48SBarry Smith realonly = PETSC_FALSE; 90968f1ed48SBarry Smith break; 91068f1ed48SBarry Smith } 91168f1ed48SBarry Smith } 91268f1ed48SBarry Smith #endif 91302594712SBarry Smith 914d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 91502594712SBarry Smith for (i=0; i<m; i++) { 91602594712SBarry Smith jcnt = 0; 917d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 918e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 91902594712SBarry Smith value = a->a[cnt++]; 920e24b481bSBarry Smith jcnt++; 92102594712SBarry Smith } else { 92202594712SBarry Smith value = 0.0; 92302594712SBarry Smith } 924aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 92568f1ed48SBarry Smith if (realonly) { 92660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 92768f1ed48SBarry Smith } else { 92860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 92968f1ed48SBarry Smith } 93002594712SBarry Smith #else 93160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 93202594712SBarry Smith #endif 93302594712SBarry Smith } 934b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 93502594712SBarry Smith } 936d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9373c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 938150b93efSMatthew G. Knepley PetscInt fshift=1; 939d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 9403c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 94119303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 9423c215bfdSMatthew Knepley #else 94319303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 9443c215bfdSMatthew Knepley #endif 945d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 9463c215bfdSMatthew Knepley for (i=0; i<m; i++) { 94760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 9483c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 949a9a0e077SKarl 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); 9503c215bfdSMatthew Knepley #else 951150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 9523c215bfdSMatthew Knepley #endif 9533c215bfdSMatthew Knepley } 9543c215bfdSMatthew Knepley } 955d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9563a40ed3dSBarry Smith } else { 957d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 958d5f3da31SBarry Smith if (A->factortype) { 95916cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 96016cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 96116cd7e1dSShri Abhyankar /* L part */ 96260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 96316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 96416cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 96560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 96616cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9676712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 96816cd7e1dSShri Abhyankar } else { 96960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 97016cd7e1dSShri Abhyankar } 97116cd7e1dSShri Abhyankar #else 97260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 97316cd7e1dSShri Abhyankar #endif 97416cd7e1dSShri Abhyankar } 97516cd7e1dSShri Abhyankar /* diagonal */ 97616cd7e1dSShri Abhyankar j = a->diag[i]; 97716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 97816cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 97960e0710aSBarry 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); 98016cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9816712e2f1SBarry 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); 98216cd7e1dSShri Abhyankar } else { 98360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 98416cd7e1dSShri Abhyankar } 98516cd7e1dSShri Abhyankar #else 98660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 98716cd7e1dSShri Abhyankar #endif 98816cd7e1dSShri Abhyankar 98916cd7e1dSShri Abhyankar /* U part */ 99060e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 99116cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 99216cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 99360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 99416cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 99522ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 99616cd7e1dSShri Abhyankar } else { 99760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 99816cd7e1dSShri Abhyankar } 99916cd7e1dSShri Abhyankar #else 100060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 100116cd7e1dSShri Abhyankar #endif 100216cd7e1dSShri Abhyankar } 100316cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 100416cd7e1dSShri Abhyankar } 100516cd7e1dSShri Abhyankar } else { 100617ab2063SBarry Smith for (i=0; i<m; i++) { 100777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 100860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 1009aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 101036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 101160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 101236db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 101360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 10143a40ed3dSBarry Smith } else { 101560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 101617ab2063SBarry Smith } 101717ab2063SBarry Smith #else 101860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 101917ab2063SBarry Smith #endif 102017ab2063SBarry Smith } 1021b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 102217ab2063SBarry Smith } 102316cd7e1dSShri Abhyankar } 1024d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 102517ab2063SBarry Smith } 1026b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 10273a40ed3dSBarry Smith PetscFunctionReturn(0); 1028416022c9SBarry Smith } 1029416022c9SBarry Smith 10309804daf3SBarry Smith #include <petscdraw.h> 1031dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 1032416022c9SBarry Smith { 1033480ef9eaSBarry Smith Mat A = (Mat) Aa; 1034416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1035dfbe8321SBarry Smith PetscErrorCode ierr; 1036383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 1037383922c3SLisandro Dalcin int color; 1038b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1039b0a32e0cSBarry Smith PetscViewer viewer; 1040f3ef73ceSBarry Smith PetscViewerFormat format; 1041cddf8d76SBarry Smith 10423a40ed3dSBarry Smith PetscFunctionBegin; 1043480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 1044b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1045b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1046383922c3SLisandro Dalcin 1047416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 10480513a670SBarry Smith 1049fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1050383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10510513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 1052b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1053416022c9SBarry Smith for (i=0; i<m; i++) { 1054cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1055bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1056bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 105736db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 1058b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1059cddf8d76SBarry Smith } 1060cddf8d76SBarry Smith } 1061b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 1062cddf8d76SBarry Smith for (i=0; i<m; i++) { 1063cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1064bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1065bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1066cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 1067b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1068cddf8d76SBarry Smith } 1069cddf8d76SBarry Smith } 1070b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1071cddf8d76SBarry Smith for (i=0; i<m; i++) { 1072cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1073bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1074bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 107536db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 1076b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1077416022c9SBarry Smith } 1078416022c9SBarry Smith } 1079383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10800513a670SBarry Smith } else { 10810513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 10820513a670SBarry Smith /* first determine max of all nonzero values */ 1083b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1084383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 1085b0a32e0cSBarry Smith PetscDraw popup; 10860513a670SBarry Smith 10870513a670SBarry Smith for (i=0; i<nz; i++) { 10880513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 10890513a670SBarry Smith } 1090383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 1091b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 109245f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 1093383922c3SLisandro Dalcin 1094383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10950513a670SBarry Smith for (i=0; i<m; i++) { 1096383922c3SLisandro Dalcin y_l = m - i - 1.0; 1097383922c3SLisandro Dalcin y_r = y_l + 1.0; 1098bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1099383922c3SLisandro Dalcin x_l = a->j[j]; 1100383922c3SLisandro Dalcin x_r = x_l + 1.0; 1101b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 1102b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 11030513a670SBarry Smith count++; 11040513a670SBarry Smith } 11050513a670SBarry Smith } 1106383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 11070513a670SBarry Smith } 1108480ef9eaSBarry Smith PetscFunctionReturn(0); 1109480ef9eaSBarry Smith } 1110cddf8d76SBarry Smith 11119804daf3SBarry Smith #include <petscdraw.h> 1112dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 1113480ef9eaSBarry Smith { 1114dfbe8321SBarry Smith PetscErrorCode ierr; 1115b0a32e0cSBarry Smith PetscDraw draw; 111636db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1117ace3abfcSBarry Smith PetscBool isnull; 1118480ef9eaSBarry Smith 1119480ef9eaSBarry Smith PetscFunctionBegin; 1120b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1121b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1122480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1123480ef9eaSBarry Smith 1124d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1125480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1126b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1127832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1128b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 11290298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1130832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 11313a40ed3dSBarry Smith PetscFunctionReturn(0); 1132416022c9SBarry Smith } 1133416022c9SBarry Smith 1134dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1135416022c9SBarry Smith { 1136dfbe8321SBarry Smith PetscErrorCode ierr; 1137ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1138416022c9SBarry Smith 11393a40ed3dSBarry Smith PetscFunctionBegin; 1140251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1141251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1142251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1143c45a1595SBarry Smith if (iascii) { 11443a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 11450f5bd95cSBarry Smith } else if (isbinary) { 11463a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 11470f5bd95cSBarry Smith } else if (isdraw) { 11483a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 114911aeaf0aSBarry Smith } 11504108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 11513a40ed3dSBarry Smith PetscFunctionReturn(0); 115217ab2063SBarry Smith } 115319bcc07fSBarry Smith 1154dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 115517ab2063SBarry Smith { 1156416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11576849ba73SBarry Smith PetscErrorCode ierr; 1158580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1159d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 116054f21887SBarry Smith MatScalar *aa = a->a,*ap; 11613447b6efSHong Zhang PetscReal ratio = 0.6; 116217ab2063SBarry Smith 11633a40ed3dSBarry Smith PetscFunctionBegin; 11643a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1165071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1166b215bc84SStefano Zampini if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) { 1167b215bc84SStefano Zampini /* we need to respect users asking to use or not the inodes routine in between matrix assemblies */ 1168b215bc84SStefano Zampini ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 1169b215bc84SStefano Zampini PetscFunctionReturn(0); 1170b215bc84SStefano Zampini } 117117ab2063SBarry Smith 117243ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 117317ab2063SBarry Smith for (i=1; i<m; i++) { 1174416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 117517ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 117694a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 117717ab2063SBarry Smith if (fshift) { 1178bfeeae90SHong Zhang ip = aj + ai[i]; 1179bfeeae90SHong Zhang ap = aa + ai[i]; 118017ab2063SBarry Smith N = ailen[i]; 1181580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1182580bdb30SBarry Smith if (!A->structure_only) { 1183580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 118417ab2063SBarry Smith } 118517ab2063SBarry Smith } 118617ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 118717ab2063SBarry Smith } 118817ab2063SBarry Smith if (m) { 118917ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 119017ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 119117ab2063SBarry Smith } 11927b083b7cSBarry Smith 119317ab2063SBarry Smith /* reset ilen and imax for each row */ 11947b083b7cSBarry Smith a->nonzerorowcnt = 0; 1195396832f4SHong Zhang if (A->structure_only) { 1196071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1197071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1198396832f4SHong Zhang } else { /* !A->structure_only */ 119917ab2063SBarry Smith for (i=0; i<m; i++) { 120017ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 12017b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 120217ab2063SBarry Smith } 1203396832f4SHong Zhang } 1204bfeeae90SHong Zhang a->nz = ai[m]; 120565e19b50SBarry 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); 120617ab2063SBarry Smith 120709f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1208d0f46423SBarry 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); 1209ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1210ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 12112205254eSKarl Rupp 12128e58a170SBarry Smith A->info.mallocs += a->reallocs; 1213dd5f02e7SSatish Balay a->reallocs = 0; 12146712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 121536db0b34SBarry Smith a->rmax = rmax; 12164e220ebcSLois Curfman McInnes 1217396832f4SHong Zhang if (!A->structure_only) { 121811e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1219396832f4SHong Zhang } 12204108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 12213a40ed3dSBarry Smith PetscFunctionReturn(0); 122217ab2063SBarry Smith } 122317ab2063SBarry Smith 122499cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 122599cafbc1SBarry Smith { 122699cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 122799cafbc1SBarry Smith PetscInt i,nz = a->nz; 12282e5835c6SStefano Zampini MatScalar *aa; 1229acf2f550SJed Brown PetscErrorCode ierr; 123099cafbc1SBarry Smith 123199cafbc1SBarry Smith PetscFunctionBegin; 12322e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 123399cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 12342e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1235acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12368c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1237c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1238e2cf4d64SStefano Zampini #endif 123999cafbc1SBarry Smith PetscFunctionReturn(0); 124099cafbc1SBarry Smith } 124199cafbc1SBarry Smith 124299cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 124399cafbc1SBarry Smith { 124499cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 124599cafbc1SBarry Smith PetscInt i,nz = a->nz; 12462e5835c6SStefano Zampini MatScalar *aa; 1247acf2f550SJed Brown PetscErrorCode ierr; 124899cafbc1SBarry Smith 124999cafbc1SBarry Smith PetscFunctionBegin; 12502e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 125199cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 12522e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1253acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12548c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1255c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1256e2cf4d64SStefano Zampini #endif 125799cafbc1SBarry Smith PetscFunctionReturn(0); 125899cafbc1SBarry Smith } 125999cafbc1SBarry Smith 1260dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 126117ab2063SBarry Smith { 1262416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1263dfbe8321SBarry Smith PetscErrorCode ierr; 12643a40ed3dSBarry Smith 12653a40ed3dSBarry Smith PetscFunctionBegin; 1266580bdb30SBarry Smith ierr = PetscArrayzero(a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 1267acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12688c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1269c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1270e2cf4d64SStefano Zampini #endif 12713a40ed3dSBarry Smith PetscFunctionReturn(0); 127217ab2063SBarry Smith } 1273416022c9SBarry Smith 1274dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 127517ab2063SBarry Smith { 1276416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1277dfbe8321SBarry Smith PetscErrorCode ierr; 1278d5d45c9bSBarry Smith 12793a40ed3dSBarry Smith PetscFunctionBegin; 1280aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1281d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 128217ab2063SBarry Smith #endif 1283e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 12846bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 12856bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 128605b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1287d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1288071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1289071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1290846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 129171f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 129205b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 12936bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 129405b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 1295cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 1296a30b2313SHong Zhang 12974108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1298bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1299901853e0SKris Buschelman 13006718818eSStefano Zampini /* MatMatMultNumeric_SeqAIJ_SeqAIJ_Sorted may allocate this. 13016718818eSStefano Zampini That function is so heavily used (sometimes in an hidden way through multnumeric function pointers) 13026718818eSStefano Zampini that is hard to properly add this data to the MatProduct data. We free it here to avoid 13036718818eSStefano Zampini users reusing the matrix object with different data to incur in obscure segmentation faults 13046718818eSStefano Zampini due to different matrix sizes */ 13056718818eSStefano Zampini ierr = PetscObjectCompose((PetscObject)A,"__PETSc__ab_dense",NULL);CHKERRQ(ierr); 13066718818eSStefano Zampini 1307f4259b30SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)A,NULL);CHKERRQ(ierr); 1308bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1309bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1310bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1311bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1312bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1313bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 13144222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA) 13154222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 1316e6e9a74fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",NULL);CHKERRQ(ierr); 1317fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 13184222ddf1SHong Zhang #endif 13193d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 13203d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijkokkos_C",NULL);CHKERRQ(ierr); 13213d0639e7SStefano Zampini #endif 13224222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL);CHKERRQ(ierr); 1323af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1324af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1325af8000cdSHong Zhang #endif 1326d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 1327d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_scalapack_C",NULL);CHKERRQ(ierr); 1328d24d4204SJose E. Roman #endif 132963c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 133063c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 13314222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 133263c07aadSStefano Zampini #endif 1333b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1334c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1335c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1336bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1337bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1338846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1339bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1340bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 13414222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL);CHKERRQ(ierr); 13424222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 13434222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 13443a40ed3dSBarry Smith PetscFunctionReturn(0); 134517ab2063SBarry Smith } 134617ab2063SBarry Smith 1347ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 134817ab2063SBarry Smith { 1349416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13504846f1f5SKris Buschelman PetscErrorCode ierr; 13513a40ed3dSBarry Smith 13523a40ed3dSBarry Smith PetscFunctionBegin; 1353a65d3064SKris Buschelman switch (op) { 1354a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 13554e0d8c25SBarry Smith a->roworiented = flg; 1356a65d3064SKris Buschelman break; 1357a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1358a9817697SBarry Smith a->keepnonzeropattern = flg; 1359a65d3064SKris Buschelman break; 1360512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1361512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1362a65d3064SKris Buschelman break; 1363a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 13644e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1365a65d3064SKris Buschelman break; 1366a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 13674e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1368a65d3064SKris Buschelman break; 136928b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 137028b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 137128b2fa4aSMatthew Knepley break; 1372a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 13734e0d8c25SBarry Smith a->ignorezeroentries = flg; 13740df259c2SBarry Smith break; 13753d472b54SHong Zhang case MAT_SPD: 1376b1646e73SJed Brown case MAT_SYMMETRIC: 1377b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1378b1646e73SJed Brown case MAT_HERMITIAN: 1379b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1380957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 13815021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 13825021d80fSJed Brown break; 13838c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 1384a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1385a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1386290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1387a65d3064SKris Buschelman break; 1388b87ac2d8SJed Brown case MAT_USE_INODES: 1389b215bc84SStefano Zampini ierr = MatSetOption_SeqAIJ_Inode(A,MAT_USE_INODES,flg);CHKERRQ(ierr); 1390b87ac2d8SJed Brown break; 1391c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1392c10200c1SHong Zhang A->submat_singleis = flg; 1393c10200c1SHong Zhang break; 1394071fcb05SBarry Smith case MAT_SORTED_FULL: 1395071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1396071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1397071fcb05SBarry Smith break; 13981a2c6b5cSJunchao Zhang case MAT_FORM_EXPLICIT_TRANSPOSE: 13991a2c6b5cSJunchao Zhang A->form_explicit_transpose = flg; 14001a2c6b5cSJunchao Zhang break; 1401a65d3064SKris Buschelman default: 1402e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1403a65d3064SKris Buschelman } 14043a40ed3dSBarry Smith PetscFunctionReturn(0); 140517ab2063SBarry Smith } 140617ab2063SBarry Smith 1407dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 140817ab2063SBarry Smith { 1409416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14106849ba73SBarry Smith PetscErrorCode ierr; 1411fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1412c898d852SStefano Zampini PetscScalar *x; 1413c898d852SStefano Zampini const PetscScalar *aa; 141417ab2063SBarry Smith 14153a40ed3dSBarry Smith PetscFunctionBegin; 1416d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1417e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1418c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 1419d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1420d3e70bfaSHong Zhang PetscInt *diag=a->diag; 1421fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 14222c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 1423fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1424c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 142535e7444dSHong Zhang PetscFunctionReturn(0); 142635e7444dSHong Zhang } 142735e7444dSHong Zhang 1428fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 142935e7444dSHong Zhang for (i=0; i<n; i++) { 1430fdc842d1SBarry Smith x[i] = 0.0; 143135e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 143235e7444dSHong Zhang if (aj[j] == i) { 143335e7444dSHong Zhang x[i] = aa[j]; 143417ab2063SBarry Smith break; 143517ab2063SBarry Smith } 143617ab2063SBarry Smith } 143717ab2063SBarry Smith } 1438fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1439c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 14403a40ed3dSBarry Smith PetscFunctionReturn(0); 144117ab2063SBarry Smith } 144217ab2063SBarry Smith 1443c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1444dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 144517ab2063SBarry Smith { 1446416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1447d9ca1df4SBarry Smith PetscScalar *y; 1448d9ca1df4SBarry Smith const PetscScalar *x; 1449dfbe8321SBarry Smith PetscErrorCode ierr; 1450d0f46423SBarry Smith PetscInt m = A->rmap->n; 14515c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1452d9ca1df4SBarry Smith const MatScalar *v; 1453a77337e4SBarry Smith PetscScalar alpha; 1454d9ca1df4SBarry Smith PetscInt n,i,j; 1455d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 14563447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1457ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 14585c897100SBarry Smith #endif 145917ab2063SBarry Smith 14603a40ed3dSBarry Smith PetscFunctionBegin; 14612e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1462d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14631ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 14645c897100SBarry Smith 14655c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1466bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 14675c897100SBarry Smith #else 14683447b6efSHong Zhang if (usecprow) { 14693447b6efSHong Zhang m = cprow.nrows; 14703447b6efSHong Zhang ii = cprow.i; 14717b2bb3b9SHong Zhang ridx = cprow.rindex; 14723447b6efSHong Zhang } else { 14733447b6efSHong Zhang ii = a->i; 14743447b6efSHong Zhang } 147517ab2063SBarry Smith for (i=0; i<m; i++) { 14763447b6efSHong Zhang idx = a->j + ii[i]; 14773447b6efSHong Zhang v = a->a + ii[i]; 14783447b6efSHong Zhang n = ii[i+1] - ii[i]; 14793447b6efSHong Zhang if (usecprow) { 14807b2bb3b9SHong Zhang alpha = x[ridx[i]]; 14813447b6efSHong Zhang } else { 148217ab2063SBarry Smith alpha = x[i]; 14833447b6efSHong Zhang } 148404fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 148517ab2063SBarry Smith } 14865c897100SBarry Smith #endif 1487dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1488d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14891ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14903a40ed3dSBarry Smith PetscFunctionReturn(0); 149117ab2063SBarry Smith } 149217ab2063SBarry Smith 1493dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 14945c897100SBarry Smith { 1495dfbe8321SBarry Smith PetscErrorCode ierr; 14965c897100SBarry Smith 14975c897100SBarry Smith PetscFunctionBegin; 1498170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 14995c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 15005c897100SBarry Smith PetscFunctionReturn(0); 15015c897100SBarry Smith } 15025c897100SBarry Smith 1503c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 150478b84d54SShri Abhyankar 1505dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 150617ab2063SBarry Smith { 1507416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1508d9fead3dSBarry Smith PetscScalar *y; 150954f21887SBarry Smith const PetscScalar *x; 151054f21887SBarry Smith const MatScalar *aa; 1511dfbe8321SBarry Smith PetscErrorCode ierr; 1512003131ecSBarry Smith PetscInt m=A->rmap->n; 15130298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 15147b083b7cSBarry Smith PetscInt n,i; 1515362ced78SSatish Balay PetscScalar sum; 1516ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 151717ab2063SBarry Smith 1518b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 151997952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1520fee21e36SBarry Smith #endif 1521fee21e36SBarry Smith 15223a40ed3dSBarry Smith PetscFunctionBegin; 1523b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1524b215bc84SStefano Zampini ierr = MatMult_SeqAIJ_Inode(A,xx,yy);CHKERRQ(ierr); 1525b215bc84SStefano Zampini PetscFunctionReturn(0); 1526b215bc84SStefano Zampini } 15273649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 15281ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1529416022c9SBarry Smith ii = a->i; 15304eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1531580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 153297952fefSHong Zhang m = a->compressedrow.nrows; 153397952fefSHong Zhang ii = a->compressedrow.i; 153497952fefSHong Zhang ridx = a->compressedrow.rindex; 153597952fefSHong Zhang for (i=0; i<m; i++) { 153697952fefSHong Zhang n = ii[i+1] - ii[i]; 153797952fefSHong Zhang aj = a->j + ii[i]; 153897952fefSHong Zhang aa = a->a + ii[i]; 153997952fefSHong Zhang sum = 0.0; 1540003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1541003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 154297952fefSHong Zhang y[*ridx++] = sum; 154397952fefSHong Zhang } 154497952fefSHong Zhang } else { /* do not use compressed row format */ 1545b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 15463d3eaba7SBarry Smith aj = a->j; 15473d3eaba7SBarry Smith aa = a->a; 1548b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1549b05257ddSBarry Smith #else 155017ab2063SBarry Smith for (i=0; i<m; i++) { 1551003131ecSBarry Smith n = ii[i+1] - ii[i]; 1552003131ecSBarry Smith aj = a->j + ii[i]; 1553003131ecSBarry Smith aa = a->a + ii[i]; 155417ab2063SBarry Smith sum = 0.0; 1555003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 155617ab2063SBarry Smith y[i] = sum; 155717ab2063SBarry Smith } 15588d195f9aSBarry Smith #endif 1559b05257ddSBarry Smith } 15607b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 15613649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15621ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15633a40ed3dSBarry Smith PetscFunctionReturn(0); 156417ab2063SBarry Smith } 156517ab2063SBarry Smith 1566b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1567b434eb95SMatthew G. Knepley { 1568b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1569b434eb95SMatthew G. Knepley PetscScalar *y; 1570b434eb95SMatthew G. Knepley const PetscScalar *x; 1571b434eb95SMatthew G. Knepley const MatScalar *aa; 1572b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1573b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1574b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1575b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1576b434eb95SMatthew G. Knepley PetscScalar sum; 1577b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1578b434eb95SMatthew G. Knepley 1579b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1580b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1581b434eb95SMatthew G. Knepley #endif 1582b434eb95SMatthew G. Knepley 1583b434eb95SMatthew G. Knepley PetscFunctionBegin; 1584b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1585b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1586b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1587b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1588b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1589b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1590b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1591b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1592b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1593b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1594b434eb95SMatthew G. Knepley sum = 0.0; 1595b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1596b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1597b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1598b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1599b434eb95SMatthew G. Knepley } 1600b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16013d3eaba7SBarry Smith ii = a->i; 1602b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1603b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1604b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1605b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1606b434eb95SMatthew G. Knepley sum = 0.0; 1607b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1608b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1609b434eb95SMatthew G. Knepley y[i] = sum; 1610b434eb95SMatthew G. Knepley } 1611b434eb95SMatthew G. Knepley } 1612b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1613b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1614b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1615b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1616b434eb95SMatthew G. Knepley } 1617b434eb95SMatthew G. Knepley 1618b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1619b434eb95SMatthew G. Knepley { 1620b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1621b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1622b434eb95SMatthew G. Knepley const PetscScalar *x; 1623b434eb95SMatthew G. Knepley const MatScalar *aa; 1624b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1625b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1626b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1627b434eb95SMatthew G. Knepley PetscScalar sum; 1628b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1629b434eb95SMatthew G. Knepley 1630b434eb95SMatthew G. Knepley PetscFunctionBegin; 1631b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1632d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1633b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1634b434eb95SMatthew G. Knepley if (zz != yy) { 1635580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1636b434eb95SMatthew G. Knepley } 1637b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1638b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1639b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1640b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1641b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1642b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1643b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1644b434eb95SMatthew G. Knepley sum = y[*ridx]; 1645b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1646b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1647b434eb95SMatthew G. Knepley } 1648b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16493d3eaba7SBarry Smith ii = a->i; 1650b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1651b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1652b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1653b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1654b434eb95SMatthew G. Knepley sum = y[i]; 1655b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1656b434eb95SMatthew G. Knepley z[i] = sum; 1657b434eb95SMatthew G. Knepley } 1658b434eb95SMatthew G. Knepley } 1659b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1660b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1661d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1662b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1663b434eb95SMatthew G. Knepley } 1664b434eb95SMatthew G. Knepley 1665c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1666dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 166717ab2063SBarry Smith { 1668416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1669f15663dcSBarry Smith PetscScalar *y,*z; 1670f15663dcSBarry Smith const PetscScalar *x; 167154f21887SBarry Smith const MatScalar *aa; 1672dfbe8321SBarry Smith PetscErrorCode ierr; 1673d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1674d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1675362ced78SSatish Balay PetscScalar sum; 1676ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 16779ea0dfa2SSatish Balay 16783a40ed3dSBarry Smith PetscFunctionBegin; 1679b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1680b215bc84SStefano Zampini ierr = MatMultAdd_SeqAIJ_Inode(A,xx,yy,zz);CHKERRQ(ierr); 1681b215bc84SStefano Zampini PetscFunctionReturn(0); 1682b215bc84SStefano Zampini } 1683f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1684d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 16854eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 16864eb6d288SHong Zhang if (zz != yy) { 1687580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 16884eb6d288SHong Zhang } 168997952fefSHong Zhang m = a->compressedrow.nrows; 169097952fefSHong Zhang ii = a->compressedrow.i; 169197952fefSHong Zhang ridx = a->compressedrow.rindex; 169297952fefSHong Zhang for (i=0; i<m; i++) { 169397952fefSHong Zhang n = ii[i+1] - ii[i]; 169497952fefSHong Zhang aj = a->j + ii[i]; 169597952fefSHong Zhang aa = a->a + ii[i]; 169697952fefSHong Zhang sum = y[*ridx]; 1697f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 169897952fefSHong Zhang z[*ridx++] = sum; 169997952fefSHong Zhang } 170097952fefSHong Zhang } else { /* do not use compressed row format */ 17013d3eaba7SBarry Smith ii = a->i; 1702f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 17033d3eaba7SBarry Smith aj = a->j; 17043d3eaba7SBarry Smith aa = a->a; 1705f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1706f15663dcSBarry Smith #else 170717ab2063SBarry Smith for (i=0; i<m; i++) { 1708f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1709f15663dcSBarry Smith aj = a->j + ii[i]; 1710f15663dcSBarry Smith aa = a->a + ii[i]; 171117ab2063SBarry Smith sum = y[i]; 1712f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 171317ab2063SBarry Smith z[i] = sum; 171417ab2063SBarry Smith } 171502ab625aSSatish Balay #endif 1716f15663dcSBarry Smith } 1717dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1718f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1719d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 17203a40ed3dSBarry Smith PetscFunctionReturn(0); 172117ab2063SBarry Smith } 172217ab2063SBarry Smith 172317ab2063SBarry Smith /* 172417ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 172517ab2063SBarry Smith */ 1726dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 172717ab2063SBarry Smith { 1728416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17296849ba73SBarry Smith PetscErrorCode ierr; 1730d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 173117ab2063SBarry Smith 17323a40ed3dSBarry Smith PetscFunctionBegin; 173309f38230SBarry Smith if (!a->diag) { 1734785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 17353bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 173609f38230SBarry Smith } 1737d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 173809f38230SBarry Smith a->diag[i] = a->i[i+1]; 1739bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1740bfeeae90SHong Zhang if (a->j[j] == i) { 174109f38230SBarry Smith a->diag[i] = j; 174217ab2063SBarry Smith break; 174317ab2063SBarry Smith } 174417ab2063SBarry Smith } 174517ab2063SBarry Smith } 17463a40ed3dSBarry Smith PetscFunctionReturn(0); 174717ab2063SBarry Smith } 174817ab2063SBarry Smith 174961ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 175061ecd0c6SBarry Smith { 175161ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 175261ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 175361ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 175461ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 175561ecd0c6SBarry Smith PetscErrorCode ierr; 175661ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 175761ecd0c6SBarry Smith 175861ecd0c6SBarry Smith PetscFunctionBegin; 175961ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 176061ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 176161ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 176261ecd0c6SBarry Smith PetscFunctionReturn(0); 176361ecd0c6SBarry Smith } 176461ecd0c6SBarry Smith 176561ecd0c6SBarry Smith if (a->diagonaldense) { 176661ecd0c6SBarry Smith cnt = 0; 176761ecd0c6SBarry Smith } else { 176861ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 176961ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 177061ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 177161ecd0c6SBarry Smith cnt++; 177261ecd0c6SBarry Smith mdiag[i] = 1; 177361ecd0c6SBarry Smith } 177461ecd0c6SBarry Smith } 177561ecd0c6SBarry Smith } 177661ecd0c6SBarry Smith if (!cnt) { 177761ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 177861ecd0c6SBarry Smith } else { 1779b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1780b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 178161ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 178261ecd0c6SBarry Smith 178361ecd0c6SBarry Smith a->a = NULL; 178461ecd0c6SBarry Smith a->j = NULL; 178561ecd0c6SBarry Smith a->i = NULL; 178661ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 178761ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 178861ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1789447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 179061ecd0c6SBarry Smith } 179161ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 179261ecd0c6SBarry Smith 179361ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 179461ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 179561ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1796447d62f5SStefano Zampini if (i < A->cmap->n) { 179761ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 179861ecd0c6SBarry Smith } 1799447d62f5SStefano Zampini } 180061ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 180161ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 180261ecd0c6SBarry Smith if (singlemalloc) { 180361ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 180461ecd0c6SBarry Smith } else { 180561ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 180661ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 180761ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 180861ecd0c6SBarry Smith } 180961ecd0c6SBarry Smith } 181061ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 181161ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 181261ecd0c6SBarry Smith PetscFunctionReturn(0); 181361ecd0c6SBarry Smith } 181461ecd0c6SBarry Smith 1815be5855fcSBarry Smith /* 1816be5855fcSBarry Smith Checks for missing diagonals 1817be5855fcSBarry Smith */ 1818ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1819be5855fcSBarry Smith { 1820be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18217734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1822994fe344SLisandro Dalcin PetscErrorCode ierr; 1823be5855fcSBarry Smith 1824be5855fcSBarry Smith PetscFunctionBegin; 182509f38230SBarry Smith *missing = PETSC_FALSE; 18267734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 182709f38230SBarry Smith *missing = PETSC_TRUE; 182809f38230SBarry Smith if (d) *d = 0; 1829994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 183009f38230SBarry Smith } else { 183101445905SHong Zhang PetscInt n; 183201445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1833f1e2ffcdSBarry Smith diag = a->diag; 183401445905SHong Zhang for (i=0; i<n; i++) { 18357734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 183609f38230SBarry Smith *missing = PETSC_TRUE; 183709f38230SBarry Smith if (d) *d = i; 1838994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1839358d2f5dSShri Abhyankar break; 184009f38230SBarry Smith } 1841be5855fcSBarry Smith } 1842be5855fcSBarry Smith } 1843be5855fcSBarry Smith PetscFunctionReturn(0); 1844be5855fcSBarry Smith } 1845be5855fcSBarry Smith 18460da83c2eSBarry Smith #include <petscblaslapack.h> 18470da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 18480da83c2eSBarry Smith 18490da83c2eSBarry Smith /* 18500da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 18510da83c2eSBarry Smith */ 18520da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 18530da83c2eSBarry Smith { 18540da83c2eSBarry Smith PetscErrorCode ierr; 18550da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 18560da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 18570da83c2eSBarry Smith const PetscReal shift = 0.0; 18580da83c2eSBarry Smith PetscInt ipvt[5]; 18590da83c2eSBarry Smith PetscScalar work[25],*v_work; 18600da83c2eSBarry Smith 18610da83c2eSBarry Smith PetscFunctionBegin; 18620da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 18630da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 18640da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 18650da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18660da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 18670da83c2eSBarry Smith } 18680da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 18690da83c2eSBarry Smith if (bsizemax > 7) { 18700da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 18710da83c2eSBarry Smith } 18720da83c2eSBarry Smith ncnt = 0; 18730da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18740da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 18750da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 18760da83c2eSBarry Smith switch (bsizes[i]) { 18770da83c2eSBarry Smith case 1: 18780da83c2eSBarry Smith *diag = 1.0/(*diag); 18790da83c2eSBarry Smith break; 18800da83c2eSBarry Smith case 2: 18810da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18820da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18830da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 18840da83c2eSBarry Smith break; 18850da83c2eSBarry Smith case 3: 18860da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18870da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18880da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 18890da83c2eSBarry Smith break; 18900da83c2eSBarry Smith case 4: 18910da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18920da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18930da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 18940da83c2eSBarry Smith break; 18950da83c2eSBarry Smith case 5: 18960da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18970da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18980da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 18990da83c2eSBarry Smith break; 19000da83c2eSBarry Smith case 6: 19010da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19020da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19030da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 19040da83c2eSBarry Smith break; 19050da83c2eSBarry Smith case 7: 19060da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19070da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19080da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 19090da83c2eSBarry Smith break; 19100da83c2eSBarry Smith default: 19110da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19120da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19130da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 19140da83c2eSBarry Smith } 19150da83c2eSBarry Smith ncnt += bsizes[i]; 19160da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 19170da83c2eSBarry Smith } 19180da83c2eSBarry Smith if (bsizemax > 7) { 19190da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 19200da83c2eSBarry Smith } 19210da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 19220da83c2eSBarry Smith PetscFunctionReturn(0); 19230da83c2eSBarry Smith } 19240da83c2eSBarry Smith 1925422a814eSBarry Smith /* 1926422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1927422a814eSBarry Smith */ 19287087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 192971f1c65dSBarry Smith { 193071f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 193171f1c65dSBarry Smith PetscErrorCode ierr; 1932d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 19332e5835c6SStefano Zampini const MatScalar *v; 193454f21887SBarry Smith PetscScalar *idiag,*mdiag; 193571f1c65dSBarry Smith 193671f1c65dSBarry Smith PetscFunctionBegin; 193771f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 193871f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 193971f1c65dSBarry Smith diag = a->diag; 194071f1c65dSBarry Smith if (!a->idiag) { 1941dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 19423bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,3*m*sizeof(PetscScalar));CHKERRQ(ierr); 194371f1c65dSBarry Smith } 19442e5835c6SStefano Zampini 194571f1c65dSBarry Smith mdiag = a->mdiag; 194671f1c65dSBarry Smith idiag = a->idiag; 19472e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 1948422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 194971f1c65dSBarry Smith for (i=0; i<m; i++) { 195071f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1951899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1952899639b0SHong Zhang if (PetscRealPart(fshift)) { 1953899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 19547b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19557b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 19567b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1957a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1958899639b0SHong Zhang } 195971f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 196071f1c65dSBarry Smith } 196171f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 196271f1c65dSBarry Smith } else { 196371f1c65dSBarry Smith for (i=0; i<m; i++) { 196471f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 196571f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 196671f1c65dSBarry Smith } 1967dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 196871f1c65dSBarry Smith } 196971f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 19702e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 197171f1c65dSBarry Smith PetscFunctionReturn(0); 197271f1c65dSBarry Smith } 197371f1c65dSBarry Smith 1974c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 197541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 197617ab2063SBarry Smith { 1977416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1978e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 19792e5835c6SStefano Zampini const MatScalar *v,*idiag=NULL,*mdiag,*aa; 198054f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1981dfbe8321SBarry Smith PetscErrorCode ierr; 19823d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 198397f1f81fSBarry Smith const PetscInt *idx,*diag; 198417ab2063SBarry Smith 19853a40ed3dSBarry Smith PetscFunctionBegin; 1986b215bc84SStefano Zampini if (a->inode.use && a->inode.checked && omega == 1.0 && fshift == 0.0) { 1987b215bc84SStefano Zampini ierr = MatSOR_SeqAIJ_Inode(A,bb,omega,flag,fshift,its,lits,xx);CHKERRQ(ierr); 1988b215bc84SStefano Zampini PetscFunctionReturn(0); 1989b215bc84SStefano Zampini } 1990b965ef7fSBarry Smith its = its*lits; 199191723122SBarry Smith 199271f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 199371f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 199471f1c65dSBarry Smith a->fshift = fshift; 199571f1c65dSBarry Smith a->omega = omega; 1996ed480e8bSBarry Smith 199771f1c65dSBarry Smith diag = a->diag; 199871f1c65dSBarry Smith t = a->ssor_work; 1999ed480e8bSBarry Smith idiag = a->idiag; 200071f1c65dSBarry Smith mdiag = a->mdiag; 2001ed480e8bSBarry Smith 20022e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 20031ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 20043649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 2005ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 200617ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 200717ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 2008ed480e8bSBarry Smith bs = b; 200917ab2063SBarry Smith for (i=0; i<m; i++) { 201071f1c65dSBarry Smith d = fshift + mdiag[i]; 2011416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2012ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20132e5835c6SStefano Zampini v = aa + diag[i] + 1; 201417ab2063SBarry Smith sum = b[i]*d/omega; 2015003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 201617ab2063SBarry Smith x[i] = sum; 201717ab2063SBarry Smith } 20181ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20193649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20202e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 2021efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20223a40ed3dSBarry Smith PetscFunctionReturn(0); 202317ab2063SBarry Smith } 2024c783ea89SBarry Smith 20252205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 20262205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 20274c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 2028887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 202917ab2063SBarry Smith 203017ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 203117ab2063SBarry Smith 2032887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 203317ab2063SBarry Smith */ 203417ab2063SBarry Smith scale = (2.0/omega) - 1.0; 203517ab2063SBarry Smith 203617ab2063SBarry Smith /* x = (E + U)^{-1} b */ 203717ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2038416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2039ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20402e5835c6SStefano Zampini v = aa + diag[i] + 1; 204117ab2063SBarry Smith sum = b[i]; 2042e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2043ed480e8bSBarry Smith x[i] = sum*idiag[i]; 204417ab2063SBarry Smith } 204517ab2063SBarry Smith 204617ab2063SBarry Smith /* t = b - (2*E - D)x */ 20472e5835c6SStefano Zampini v = aa; 20482205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 204917ab2063SBarry Smith 205017ab2063SBarry Smith /* t = (E + L)^{-1}t */ 2051ed480e8bSBarry Smith ts = t; 2052416022c9SBarry Smith diag = a->diag; 205317ab2063SBarry Smith for (i=0; i<m; i++) { 2054416022c9SBarry Smith n = diag[i] - a->i[i]; 2055ed480e8bSBarry Smith idx = a->j + a->i[i]; 20562e5835c6SStefano Zampini v = aa + a->i[i]; 205717ab2063SBarry Smith sum = t[i]; 2058003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 2059ed480e8bSBarry Smith t[i] = sum*idiag[i]; 2060733d66baSBarry Smith /* x = x + t */ 2061733d66baSBarry Smith x[i] += t[i]; 206217ab2063SBarry Smith } 206317ab2063SBarry Smith 2064dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 20651ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20663649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20673a40ed3dSBarry Smith PetscFunctionReturn(0); 206817ab2063SBarry Smith } 206917ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 207017ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 207117ab2063SBarry Smith for (i=0; i<m; i++) { 2072416022c9SBarry Smith n = diag[i] - a->i[i]; 2073ed480e8bSBarry Smith idx = a->j + a->i[i]; 20742e5835c6SStefano Zampini v = aa + a->i[i]; 207517ab2063SBarry Smith sum = b[i]; 2076e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20775c99c7daSBarry Smith t[i] = sum; 2078ed480e8bSBarry Smith x[i] = sum*idiag[i]; 207917ab2063SBarry Smith } 20805c99c7daSBarry Smith xb = t; 2081efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20823a40ed3dSBarry Smith } else xb = b; 208317ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 208417ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2085416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2086ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20872e5835c6SStefano Zampini v = aa + diag[i] + 1; 208817ab2063SBarry Smith sum = xb[i]; 2089e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20905c99c7daSBarry Smith if (xb == b) { 2091ed480e8bSBarry Smith x[i] = sum*idiag[i]; 20925c99c7daSBarry Smith } else { 2093b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 209417ab2063SBarry Smith } 20955c99c7daSBarry Smith } 2096b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 209717ab2063SBarry Smith } 209817ab2063SBarry Smith its--; 209917ab2063SBarry Smith } 210017ab2063SBarry Smith while (its--) { 210117ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 210217ab2063SBarry Smith for (i=0; i<m; i++) { 2103b19a5dc2SMark Adams /* lower */ 2104b19a5dc2SMark Adams n = diag[i] - a->i[i]; 2105ed480e8bSBarry Smith idx = a->j + a->i[i]; 21062e5835c6SStefano Zampini v = aa + a->i[i]; 210717ab2063SBarry Smith sum = b[i]; 2108e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2109b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 2110b19a5dc2SMark Adams /* upper */ 2111b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2112b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21132e5835c6SStefano Zampini v = aa + diag[i] + 1; 2114b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2115b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 211617ab2063SBarry Smith } 2117b19a5dc2SMark Adams xb = t; 21189f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2119b19a5dc2SMark Adams } else xb = b; 212017ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 212117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2122b19a5dc2SMark Adams sum = xb[i]; 2123b19a5dc2SMark Adams if (xb == b) { 2124b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 2125416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 2126ed480e8bSBarry Smith idx = a->j + a->i[i]; 21272e5835c6SStefano Zampini v = aa + a->i[i]; 2128e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2129ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 2130b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 2131b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2132b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21332e5835c6SStefano Zampini v = aa + diag[i] + 1; 2134b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2135b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 213617ab2063SBarry Smith } 2137b19a5dc2SMark Adams } 2138b19a5dc2SMark Adams if (xb == b) { 21399f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2140b19a5dc2SMark Adams } else { 2141b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 2142b19a5dc2SMark Adams } 214317ab2063SBarry Smith } 214417ab2063SBarry Smith } 21452e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 21461ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 21473649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 2148365a8a9eSBarry Smith PetscFunctionReturn(0); 214917ab2063SBarry Smith } 215017ab2063SBarry Smith 21512af78befSBarry Smith 2152dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 215317ab2063SBarry Smith { 2154416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21554e220ebcSLois Curfman McInnes 21563a40ed3dSBarry Smith PetscFunctionBegin; 21574e220ebcSLois Curfman McInnes info->block_size = 1.0; 21583966268fSBarry Smith info->nz_allocated = a->maxnz; 21593966268fSBarry Smith info->nz_used = a->nz; 21603966268fSBarry Smith info->nz_unneeded = (a->maxnz - a->nz); 21613966268fSBarry Smith info->assemblies = A->num_ass; 21623966268fSBarry Smith info->mallocs = A->info.mallocs; 21637adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2164d5f3da31SBarry Smith if (A->factortype) { 21654e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 21664e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 21674e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 21684e220ebcSLois Curfman McInnes } else { 21694e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 21704e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 21714e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 21724e220ebcSLois Curfman McInnes } 21733a40ed3dSBarry Smith PetscFunctionReturn(0); 217417ab2063SBarry Smith } 217517ab2063SBarry Smith 21762b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 217717ab2063SBarry Smith { 2178416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2179c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 21806849ba73SBarry Smith PetscErrorCode ierr; 218197b48c8fSBarry Smith const PetscScalar *xx; 21822e5835c6SStefano Zampini PetscScalar *bb,*aa; 2183c7da8527SEric Chamberland PetscInt d = 0; 218417ab2063SBarry Smith 21853a40ed3dSBarry Smith PetscFunctionBegin; 218697b48c8fSBarry Smith if (x && b) { 218797b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 218897b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 218997b48c8fSBarry Smith for (i=0; i<N; i++) { 219097b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2191447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 219297b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 219397b48c8fSBarry Smith } 219497b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 219597b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 219697b48c8fSBarry Smith } 219797b48c8fSBarry Smith 21982e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 2199a9817697SBarry Smith if (a->keepnonzeropattern) { 2200f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2201e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22022e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2203f1e2ffcdSBarry Smith } 2204f4df32b1SMatthew Knepley if (diag != 0.0) { 2205c7da8527SEric Chamberland for (i=0; i<N; i++) { 2206c7da8527SEric Chamberland d = rows[i]; 2207447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2208c7da8527SEric 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); 2209c7da8527SEric Chamberland } 2210f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2211447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 22122e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 2213f1e2ffcdSBarry Smith } 2214f1e2ffcdSBarry Smith } 2215f1e2ffcdSBarry Smith } else { 2216f4df32b1SMatthew Knepley if (diag != 0.0) { 221717ab2063SBarry Smith for (i=0; i<N; i++) { 2218e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22197ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2220447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2221447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2222447d62f5SStefano Zampini } else { 2223416022c9SBarry Smith a->ilen[rows[i]] = 1; 22242e5835c6SStefano Zampini aa[a->i[rows[i]]] = diag; 2225bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2226447d62f5SStefano Zampini } 2227447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2228f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 222917ab2063SBarry Smith } 223017ab2063SBarry Smith } 22313a40ed3dSBarry Smith } else { 223217ab2063SBarry Smith for (i=0; i<N; i++) { 2233e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2234416022c9SBarry Smith a->ilen[rows[i]] = 0; 223517ab2063SBarry Smith } 223617ab2063SBarry Smith } 2237e56f5c9eSBarry Smith A->nonzerostate++; 2238f1e2ffcdSBarry Smith } 22392e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 22408c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2241c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2242e2cf4d64SStefano Zampini #endif 22434099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22443a40ed3dSBarry Smith PetscFunctionReturn(0); 224517ab2063SBarry Smith } 224617ab2063SBarry Smith 22476e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 22486e169961SBarry Smith { 22496e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22506e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 22516e169961SBarry Smith PetscErrorCode ierr; 22522b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 22536e169961SBarry Smith const PetscScalar *xx; 22542e5835c6SStefano Zampini PetscScalar *bb,*aa; 22556e169961SBarry Smith 22566e169961SBarry Smith PetscFunctionBegin; 22572e5835c6SStefano Zampini if (!N) PetscFunctionReturn(0); 22582e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 22596e169961SBarry Smith if (x && b) { 22606e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 22616e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 22622b40b63fSBarry Smith vecs = PETSC_TRUE; 22636e169961SBarry Smith } 22641795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 22656e169961SBarry Smith for (i=0; i<N; i++) { 22666e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22672e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 22682205254eSKarl Rupp 22696e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 22706e169961SBarry Smith } 22716e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 22726e169961SBarry Smith if (!zeroed[i]) { 22736e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 22744cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 22752e5835c6SStefano Zampini if (vecs) bb[i] -= aa[j]*xx[a->j[j]]; 22762e5835c6SStefano Zampini aa[j] = 0.0; 22776e169961SBarry Smith } 22786e169961SBarry Smith } 22794cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 22806e169961SBarry Smith } 22816e169961SBarry Smith if (x && b) { 22826e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 22836e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 22846e169961SBarry Smith } 22856e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 22866e169961SBarry Smith if (diag != 0.0) { 22876e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 22881d5a398dSstefano_zampini if (missing) { 22891d5a398dSstefano_zampini for (i=0; i<N; i++) { 22904cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 22914cf107fdSStefano 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]); 22921d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 22931d5a398dSstefano_zampini } 22941d5a398dSstefano_zampini } else { 22956e169961SBarry Smith for (i=0; i<N; i++) { 22962e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 22976e169961SBarry Smith } 22986e169961SBarry Smith } 22991d5a398dSstefano_zampini } 23002e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 23018c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2302c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2303e2cf4d64SStefano Zampini #endif 23044099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23056e169961SBarry Smith PetscFunctionReturn(0); 23066e169961SBarry Smith } 23076e169961SBarry Smith 2308a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 230917ab2063SBarry Smith { 2310416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23112e5835c6SStefano Zampini const PetscScalar *aa = a->a; 231297f1f81fSBarry Smith PetscInt *itmp; 23132e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23142e5835c6SStefano Zampini PetscErrorCode ierr; 23152e5835c6SStefano Zampini PetscBool rest = PETSC_FALSE; 23162e5835c6SStefano Zampini #endif 231717ab2063SBarry Smith 23183a40ed3dSBarry Smith PetscFunctionBegin; 23192e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23202e5835c6SStefano Zampini if (v && A->offloadmask == PETSC_OFFLOAD_GPU) { 23212e5835c6SStefano Zampini /* triggers copy to CPU */ 23222e5835c6SStefano Zampini rest = PETSC_TRUE; 23232e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 23242e5835c6SStefano Zampini } else aa = a->a; 23252e5835c6SStefano Zampini #endif 2326416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 23272e5835c6SStefano Zampini if (v) *v = (PetscScalar*)(aa + a->i[row]); 232817ab2063SBarry Smith if (idx) { 2329bfeeae90SHong Zhang itmp = a->j + a->i[row]; 233026fbe8dcSKarl Rupp if (*nz) *idx = itmp; 2331f4259b30SLisandro Dalcin else *idx = NULL; 233217ab2063SBarry Smith } 23332e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23342e5835c6SStefano Zampini if (rest) { 23352e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 23362e5835c6SStefano Zampini } 23372e5835c6SStefano Zampini #endif 23383a40ed3dSBarry Smith PetscFunctionReturn(0); 233917ab2063SBarry Smith } 234017ab2063SBarry Smith 2341a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 234217ab2063SBarry Smith { 23433a40ed3dSBarry Smith PetscFunctionBegin; 2344*cb4a9cd9SHong Zhang if (nz) *nz = 0; 23452e5835c6SStefano Zampini if (idx) *idx = NULL; 23462e5835c6SStefano Zampini if (v) *v = NULL; 23473a40ed3dSBarry Smith PetscFunctionReturn(0); 234817ab2063SBarry Smith } 234917ab2063SBarry Smith 2350dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 235117ab2063SBarry Smith { 2352416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23532e5835c6SStefano Zampini const MatScalar *v; 235436db0b34SBarry Smith PetscReal sum = 0.0; 23556849ba73SBarry Smith PetscErrorCode ierr; 235697f1f81fSBarry Smith PetscInt i,j; 235717ab2063SBarry Smith 23583a40ed3dSBarry Smith PetscFunctionBegin; 23592e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 236017ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2361570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2362570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 236373cf7048SBarry Smith PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&nz,v,&one)); 2364570b7f6dSBarry Smith #else 2365416022c9SBarry Smith for (i=0; i<a->nz; i++) { 236636db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 236717ab2063SBarry Smith } 23688f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2369570b7f6dSBarry Smith #endif 2370ca0c957dSBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 23713a40ed3dSBarry Smith } else if (type == NORM_1) { 237236db0b34SBarry Smith PetscReal *tmp; 237397f1f81fSBarry Smith PetscInt *jj = a->j; 23741795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2375064f8208SBarry Smith *nrm = 0.0; 2376416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2377bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 237817ab2063SBarry Smith } 2379d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2380064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 238117ab2063SBarry Smith } 2382606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 238351f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 23843a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2385064f8208SBarry Smith *nrm = 0.0; 2386d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 23872e5835c6SStefano Zampini const PetscScalar *v2 = v + a->i[j]; 238817ab2063SBarry Smith sum = 0.0; 2389416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 23902e5835c6SStefano Zampini sum += PetscAbsScalar(*v2); v2++; 239117ab2063SBarry Smith } 2392064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 239317ab2063SBarry Smith } 239451f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2395f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 23962e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 23973a40ed3dSBarry Smith PetscFunctionReturn(0); 239817ab2063SBarry Smith } 239917ab2063SBarry Smith 24004e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 24014e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 24024e938277SHong Zhang { 24034e938277SHong Zhang PetscErrorCode ierr; 24044e938277SHong Zhang PetscInt i,j,anzj; 24054e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 24064e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 24074e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 24084e938277SHong Zhang 24094e938277SHong Zhang PetscFunctionBegin; 24104e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2411854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2412785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2413785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 24144e938277SHong Zhang 24154e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 24164e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 241726fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 24184e938277SHong Zhang /* Form ati for csr format of A^T. */ 241926fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 24204e938277SHong Zhang 24214e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2422580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 24234e938277SHong Zhang 24244e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 24254e938277SHong Zhang for (i=0;i<am;i++) { 24264e938277SHong Zhang anzj = ai[i+1] - ai[i]; 24274e938277SHong Zhang for (j=0;j<anzj;j++) { 24284e938277SHong Zhang atj[atfill[*aj]] = i; 24294e938277SHong Zhang atfill[*aj++] += 1; 24304e938277SHong Zhang } 24314e938277SHong Zhang } 24324e938277SHong Zhang 24334e938277SHong Zhang /* Clean up temporary space and complete requests. */ 24344e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2435ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 243633d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2437b5bb3eecSMark Adams ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2438a2f3521dSMark F. Adams 24394e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 24404e938277SHong Zhang b->free_a = PETSC_FALSE; 24414e938277SHong Zhang b->free_ij = PETSC_TRUE; 24424e938277SHong Zhang b->nonew = 0; 24434e938277SHong Zhang PetscFunctionReturn(0); 24444e938277SHong Zhang } 24454e938277SHong Zhang 24467087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2447cd0d46ebSvictorle { 24483d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 244954f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 24502e5835c6SStefano Zampini const MatScalar *va,*vb; 24516849ba73SBarry Smith PetscErrorCode ierr; 245297f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2453cd0d46ebSvictorle 2454cd0d46ebSvictorle PetscFunctionBegin; 2455cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2456cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24575485867bSBarry Smith if (ma!=nb || na!=mb) { 24585485867bSBarry Smith *f = PETSC_FALSE; 24595485867bSBarry Smith PetscFunctionReturn(0); 24605485867bSBarry Smith } 24612e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&va);CHKERRQ(ierr); 24622e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(B,&vb);CHKERRQ(ierr); 2463cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2464cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2465785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2466785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2467cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2468cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2469cd0d46ebSvictorle 2470cd0d46ebSvictorle *f = PETSC_TRUE; 2471cd0d46ebSvictorle for (i=0; i<ma; i++) { 2472cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 247397f1f81fSBarry Smith PetscInt idc,idr; 24745485867bSBarry Smith PetscScalar vc,vr; 2475cd0d46ebSvictorle /* column/row index/value */ 24765485867bSBarry Smith idc = adx[aptr[i]]; 24775485867bSBarry Smith idr = bdx[bptr[idc]]; 24785485867bSBarry Smith vc = va[aptr[i]]; 24795485867bSBarry Smith vr = vb[bptr[idc]]; 24805485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 24815485867bSBarry Smith *f = PETSC_FALSE; 24825485867bSBarry Smith goto done; 2483cd0d46ebSvictorle } else { 24845485867bSBarry Smith aptr[i]++; 24855485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2486cd0d46ebSvictorle } 2487cd0d46ebSvictorle } 2488cd0d46ebSvictorle } 2489cd0d46ebSvictorle done: 2490cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 24913aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 24922e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&va);CHKERRQ(ierr); 24932e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(B,&vb);CHKERRQ(ierr); 2494cd0d46ebSvictorle PetscFunctionReturn(0); 2495cd0d46ebSvictorle } 2496cd0d46ebSvictorle 24977087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 24981cbb95d3SBarry Smith { 24993d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 250054f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 250154f21887SBarry Smith MatScalar *va,*vb; 25021cbb95d3SBarry Smith PetscErrorCode ierr; 25031cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 25041cbb95d3SBarry Smith 25051cbb95d3SBarry Smith PetscFunctionBegin; 25061cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 25071cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 25081cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 25091cbb95d3SBarry Smith *f = PETSC_FALSE; 25101cbb95d3SBarry Smith PetscFunctionReturn(0); 25111cbb95d3SBarry Smith } 25121cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 25131cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 25141cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2515785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2516785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 25171cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 25181cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 25191cbb95d3SBarry Smith 25201cbb95d3SBarry Smith *f = PETSC_TRUE; 25211cbb95d3SBarry Smith for (i=0; i<ma; i++) { 25221cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 25231cbb95d3SBarry Smith PetscInt idc,idr; 25241cbb95d3SBarry Smith PetscScalar vc,vr; 25251cbb95d3SBarry Smith /* column/row index/value */ 25261cbb95d3SBarry Smith idc = adx[aptr[i]]; 25271cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 25281cbb95d3SBarry Smith vc = va[aptr[i]]; 25291cbb95d3SBarry Smith vr = vb[bptr[idc]]; 25301cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 25311cbb95d3SBarry Smith *f = PETSC_FALSE; 25321cbb95d3SBarry Smith goto done; 25331cbb95d3SBarry Smith } else { 25341cbb95d3SBarry Smith aptr[i]++; 25351cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 25361cbb95d3SBarry Smith } 25371cbb95d3SBarry Smith } 25381cbb95d3SBarry Smith } 25391cbb95d3SBarry Smith done: 25401cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 25411cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 25421cbb95d3SBarry Smith PetscFunctionReturn(0); 25431cbb95d3SBarry Smith } 25441cbb95d3SBarry Smith 2545ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25469e29f15eSvictorle { 2547dfbe8321SBarry Smith PetscErrorCode ierr; 25486e111a19SKarl Rupp 25499e29f15eSvictorle PetscFunctionBegin; 25505485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25519e29f15eSvictorle PetscFunctionReturn(0); 25529e29f15eSvictorle } 25539e29f15eSvictorle 2554ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25551cbb95d3SBarry Smith { 25561cbb95d3SBarry Smith PetscErrorCode ierr; 25576e111a19SKarl Rupp 25581cbb95d3SBarry Smith PetscFunctionBegin; 25591cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25601cbb95d3SBarry Smith PetscFunctionReturn(0); 25611cbb95d3SBarry Smith } 25621cbb95d3SBarry Smith 2563dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 256417ab2063SBarry Smith { 2565416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2566fff8e43fSBarry Smith const PetscScalar *l,*r; 2567fff8e43fSBarry Smith PetscScalar x; 256854f21887SBarry Smith MatScalar *v; 2569dfbe8321SBarry Smith PetscErrorCode ierr; 2570fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2571fff8e43fSBarry Smith const PetscInt *jj; 257217ab2063SBarry Smith 25733a40ed3dSBarry Smith PetscFunctionBegin; 257417ab2063SBarry Smith if (ll) { 25753ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 25763ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2577e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2578e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2579fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 25802e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 258117ab2063SBarry Smith for (i=0; i<m; i++) { 258217ab2063SBarry Smith x = l[i]; 2583416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 25842205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 258517ab2063SBarry Smith } 2586fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2587efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 25882e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 258917ab2063SBarry Smith } 259017ab2063SBarry Smith if (rr) { 2591e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2592e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2593fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 25942e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 25952e5835c6SStefano Zampini jj = a->j; 25962205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 25972e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 2598fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2599efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 260017ab2063SBarry Smith } 2601acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 26028c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2603c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2604e2cf4d64SStefano Zampini #endif 26053a40ed3dSBarry Smith PetscFunctionReturn(0); 260617ab2063SBarry Smith } 260717ab2063SBarry Smith 26087dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 260917ab2063SBarry Smith { 2610db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 26116849ba73SBarry Smith PetscErrorCode ierr; 2612d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 261397f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 26145d0c19d7SBarry Smith const PetscInt *irow,*icol; 26152e5835c6SStefano Zampini const PetscScalar *aa; 26165d0c19d7SBarry Smith PetscInt nrows,ncols; 261797f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 261854f21887SBarry Smith MatScalar *a_new,*mat_a; 2619416022c9SBarry Smith Mat C; 2620cdc6f3adSToby Isaac PetscBool stride; 262117ab2063SBarry Smith 26223a40ed3dSBarry Smith PetscFunctionBegin; 262317ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2624b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2625b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 262617ab2063SBarry Smith 2627251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2628ff718158SBarry Smith if (stride) { 2629ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2630ff718158SBarry Smith } else { 2631ff718158SBarry Smith first = 0; 2632ff718158SBarry Smith step = 0; 2633ff718158SBarry Smith } 2634fee21e36SBarry Smith if (stride && step == 1) { 263502834360SBarry Smith /* special case of contiguous rows */ 2636dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 263702834360SBarry Smith /* loop over new rows determining lens and starting points */ 263802834360SBarry Smith for (i=0; i<nrows; i++) { 2639bfeeae90SHong Zhang kstart = ai[irow[i]]; 2640a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2641a91a9bebSLisandro Dalcin starts[i] = kstart; 264202834360SBarry Smith for (k=kstart; k<kend; k++) { 2643bfeeae90SHong Zhang if (aj[k] >= first) { 264402834360SBarry Smith starts[i] = k; 264502834360SBarry Smith break; 264602834360SBarry Smith } 264702834360SBarry Smith } 2648a2744918SBarry Smith sum = 0; 264902834360SBarry Smith while (k < kend) { 2650bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2651a2744918SBarry Smith sum++; 265202834360SBarry Smith } 2653a2744918SBarry Smith lens[i] = sum; 265402834360SBarry Smith } 265502834360SBarry Smith /* create submatrix */ 2656cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 265797f1f81fSBarry Smith PetscInt n_cols,n_rows; 265808480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2659e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2660d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 266108480c60SBarry Smith C = *B; 26623a40ed3dSBarry Smith } else { 26633bef6203SJed Brown PetscInt rbs,cbs; 2664ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2665f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 26663bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 26673bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 26683bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 26697adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2670ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 267108480c60SBarry Smith } 2672db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2673db02288aSLois Curfman McInnes 267402834360SBarry Smith /* loop over rows inserting into submatrix */ 2675db02288aSLois Curfman McInnes a_new = c->a; 2676db02288aSLois Curfman McInnes j_new = c->j; 2677db02288aSLois Curfman McInnes i_new = c->i; 26782e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 267902834360SBarry Smith for (i=0; i<nrows; i++) { 2680a2744918SBarry Smith ii = starts[i]; 2681a2744918SBarry Smith lensi = lens[i]; 2682a2744918SBarry Smith for (k=0; k<lensi; k++) { 2683a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 268402834360SBarry Smith } 26852e5835c6SStefano Zampini ierr = PetscArraycpy(a_new,aa + starts[i],lensi);CHKERRQ(ierr); 2686a2744918SBarry Smith a_new += lensi; 2687a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2688a2744918SBarry Smith c->ilen[i] = lensi; 268902834360SBarry Smith } 26902e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 26910e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 26923a40ed3dSBarry Smith } else { 269302834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 26941795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2695854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 26964dcab191SBarry Smith for (i=0; i<ncols; i++) { 2697d9ef940eSSatish Balay if (PetscUnlikelyDebug(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); 26984dcab191SBarry Smith smap[icol[i]] = i+1; 26994dcab191SBarry Smith } 27004dcab191SBarry Smith 270102834360SBarry Smith /* determine lens of each row */ 270202834360SBarry Smith for (i=0; i<nrows; i++) { 2703bfeeae90SHong Zhang kstart = ai[irow[i]]; 270402834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 270502834360SBarry Smith lens[i] = 0; 270602834360SBarry Smith for (k=kstart; k<kend; k++) { 2707bfeeae90SHong Zhang if (smap[aj[k]]) { 270802834360SBarry Smith lens[i]++; 270902834360SBarry Smith } 271002834360SBarry Smith } 271102834360SBarry Smith } 271217ab2063SBarry Smith /* Create and fill new matrix */ 2713a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2714ace3abfcSBarry Smith PetscBool equal; 27150f5bd95cSBarry Smith 271699141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2717e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2718580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2719f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2720580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 272108480c60SBarry Smith C = *B; 27223a40ed3dSBarry Smith } else { 27233bef6203SJed Brown PetscInt rbs,cbs; 2724ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2725f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 27263bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 27273bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 27283bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 27297adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2730ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 273108480c60SBarry Smith } 27322e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 273399141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 273417ab2063SBarry Smith for (i=0; i<nrows; i++) { 273599141d43SSatish Balay row = irow[i]; 2736bfeeae90SHong Zhang kstart = ai[row]; 273799141d43SSatish Balay kend = kstart + a->ilen[row]; 2738bfeeae90SHong Zhang mat_i = c->i[i]; 273999141d43SSatish Balay mat_j = c->j + mat_i; 274099141d43SSatish Balay mat_a = c->a + mat_i; 274199141d43SSatish Balay mat_ilen = c->ilen + i; 274217ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2743bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2744ed480e8bSBarry Smith *mat_j++ = tcol - 1; 27452e5835c6SStefano Zampini *mat_a++ = aa[k]; 274699141d43SSatish Balay (*mat_ilen)++; 274799141d43SSatish Balay 274817ab2063SBarry Smith } 274917ab2063SBarry Smith } 275017ab2063SBarry Smith } 27512e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 275202834360SBarry Smith /* Free work space */ 275302834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2754606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2755606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2756cdc6f3adSToby Isaac /* sort */ 2757cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2758cdc6f3adSToby Isaac PetscInt ilen; 2759cdc6f3adSToby Isaac 2760cdc6f3adSToby Isaac mat_i = c->i[i]; 2761cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2762cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2763cdc6f3adSToby Isaac ilen = c->ilen[i]; 2764390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2765cdc6f3adSToby Isaac } 276602834360SBarry Smith } 27678c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2768b470e4b4SRichard Tran Mills ierr = MatBindToCPU(C,A->boundtocpu);CHKERRQ(ierr); 2769305c6ccfSStefano Zampini #endif 27706d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27716d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 277217ab2063SBarry Smith 277317ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2774416022c9SBarry Smith *B = C; 27753a40ed3dSBarry Smith PetscFunctionReturn(0); 277617ab2063SBarry Smith } 277717ab2063SBarry Smith 2778fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 277982d44351SHong Zhang { 278082d44351SHong Zhang PetscErrorCode ierr; 278182d44351SHong Zhang Mat B; 278282d44351SHong Zhang 278382d44351SHong Zhang PetscFunctionBegin; 2784c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 278582d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 278682d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 278733d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 278882d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 278982d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 279082d44351SHong Zhang *subMat = B; 2791c2d650bdSHong Zhang } else { 2792c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2793c2d650bdSHong Zhang } 279482d44351SHong Zhang PetscFunctionReturn(0); 279582d44351SHong Zhang } 279682d44351SHong Zhang 27979a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2798a871dcd8SBarry Smith { 279963b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2800dfbe8321SBarry Smith PetscErrorCode ierr; 280163b91edcSBarry Smith Mat outA; 2802ace3abfcSBarry Smith PetscBool row_identity,col_identity; 280363b91edcSBarry Smith 28043a40ed3dSBarry Smith PetscFunctionBegin; 2805e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 28061df811f5SHong Zhang 2807b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2808b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2809a871dcd8SBarry Smith 281063b91edcSBarry Smith outA = inA; 2811d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2812f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2813f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 28142205254eSKarl Rupp 2815c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 28166bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 28172205254eSKarl Rupp 2818c3122656SLisandro Dalcin a->row = row; 28192205254eSKarl Rupp 2820c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 28216bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 28222205254eSKarl Rupp 2823c3122656SLisandro Dalcin a->col = col; 282463b91edcSBarry Smith 282536db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 28266bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 28274c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 28283bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2829f0ec6fceSSatish Balay 283094a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2831854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 28323bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 283394a9d846SBarry Smith } 283463b91edcSBarry Smith 2835f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2836137fb511SHong Zhang if (row_identity && col_identity) { 2837ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2838137fb511SHong Zhang } else { 2839719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2840137fb511SHong Zhang } 28413a40ed3dSBarry Smith PetscFunctionReturn(0); 2842a871dcd8SBarry Smith } 2843a871dcd8SBarry Smith 2844f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2845f0b747eeSBarry Smith { 2846f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2847dfa0f9e5SStefano Zampini PetscScalar *v; 2848efee365bSSatish Balay PetscErrorCode ierr; 2849c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 28503a40ed3dSBarry Smith 28513a40ed3dSBarry Smith PetscFunctionBegin; 2852dfa0f9e5SStefano Zampini ierr = MatSeqAIJGetArray(inA,&v);CHKERRQ(ierr); 2853c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 2854dfa0f9e5SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&alpha,v,&one)); 2855efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2856dfa0f9e5SStefano Zampini ierr = MatSeqAIJRestoreArray(inA,&v);CHKERRQ(ierr); 2857acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 28583a40ed3dSBarry Smith PetscFunctionReturn(0); 2859f0b747eeSBarry Smith } 2860f0b747eeSBarry Smith 2861f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 286216b64355SHong Zhang { 286316b64355SHong Zhang PetscErrorCode ierr; 286416b64355SHong Zhang PetscInt i; 286516b64355SHong Zhang 286616b64355SHong Zhang PetscFunctionBegin; 286716b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 286816b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 286916b64355SHong Zhang 287016b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 287116b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 287216b64355SHong Zhang } 287316b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 287416b64355SHong Zhang 287516b64355SHong Zhang if (submatj->rbuf1) { 287616b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 287716b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 287816b64355SHong Zhang } 287916b64355SHong Zhang 288016b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 288116b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 288216b64355SHong Zhang } 288316b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 288416b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 288516b64355SHong Zhang } 288616b64355SHong Zhang 288716b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 288816b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 288916b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 289016b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 289116b64355SHong Zhang #else 289216b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 289316b64355SHong Zhang #endif 289416b64355SHong Zhang 289516b64355SHong Zhang if (!submatj->allcolumns) { 289616b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 289716b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 289816b64355SHong Zhang #else 289916b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 290016b64355SHong Zhang #endif 290116b64355SHong Zhang } 290216b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 290316b64355SHong Zhang 290416b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 290516b64355SHong Zhang PetscFunctionReturn(0); 290616b64355SHong Zhang } 290716b64355SHong Zhang 29080fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 290916b64355SHong Zhang { 291016b64355SHong Zhang PetscErrorCode ierr; 291116b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 29125c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 291316b64355SHong Zhang 291416b64355SHong Zhang PetscFunctionBegin; 291534136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2916f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 291716b64355SHong Zhang PetscFunctionReturn(0); 291816b64355SHong Zhang } 291916b64355SHong Zhang 29202d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 29212d033e1fSHong Zhang { 29222d033e1fSHong Zhang PetscErrorCode ierr; 29232d033e1fSHong Zhang PetscInt i; 29240fb991dcSHong Zhang Mat C; 29250fb991dcSHong Zhang Mat_SeqAIJ *c; 29260fb991dcSHong Zhang Mat_SubSppt *submatj; 29272d033e1fSHong Zhang 29282d033e1fSHong Zhang PetscFunctionBegin; 29292d033e1fSHong Zhang for (i=0; i<n; i++) { 29300fb991dcSHong Zhang C = (*mat)[i]; 29310fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 29320fb991dcSHong Zhang submatj = c->submatis1; 29332d033e1fSHong Zhang if (submatj) { 2934682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 293534136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2936f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 293734136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 29382d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 29392d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 29402d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2941682e4c99SStefano Zampini } 29422d033e1fSHong Zhang } else { 29432d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 29442d033e1fSHong Zhang } 29452d033e1fSHong Zhang } 294686e85357SHong Zhang 294763a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 294863a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 294963a75b2aSHong Zhang 29502d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 29512d033e1fSHong Zhang PetscFunctionReturn(0); 29522d033e1fSHong Zhang } 29532d033e1fSHong Zhang 29547dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2955cddf8d76SBarry Smith { 2956dfbe8321SBarry Smith PetscErrorCode ierr; 295797f1f81fSBarry Smith PetscInt i; 2958cddf8d76SBarry Smith 29593a40ed3dSBarry Smith PetscFunctionBegin; 2960cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2961df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2962cddf8d76SBarry Smith } 2963cddf8d76SBarry Smith 2964cddf8d76SBarry Smith for (i=0; i<n; i++) { 29657dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2966cddf8d76SBarry Smith } 29673a40ed3dSBarry Smith PetscFunctionReturn(0); 2968cddf8d76SBarry Smith } 2969cddf8d76SBarry Smith 297097f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 29714dcbc457SBarry Smith { 2972e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29736849ba73SBarry Smith PetscErrorCode ierr; 29745d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 29755d0c19d7SBarry Smith const PetscInt *idx; 297697f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2977f1af5d2fSBarry Smith PetscBT table; 2978bbd702dbSSatish Balay 29793a40ed3dSBarry Smith PetscFunctionBegin; 2980d0f46423SBarry Smith m = A->rmap->n; 2981e4d965acSSatish Balay ai = a->i; 2982bfeeae90SHong Zhang aj = a->j; 29838a047759SSatish Balay 2984e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 298506763907SSatish Balay 2986854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 298753b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 298806763907SSatish Balay 2989e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2990b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2991e4d965acSSatish Balay isz = 0; 29926831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2993e4d965acSSatish Balay 2994e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 29954dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2996b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2997e4d965acSSatish Balay 2998dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2999e4d965acSSatish Balay for (j=0; j<n; ++j) { 30002205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 30014dcbc457SBarry Smith } 300206763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 30036bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 3004e4d965acSSatish Balay 300504a348a9SBarry Smith k = 0; 300604a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 300704a348a9SBarry Smith n = isz; 300806763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 3009e4d965acSSatish Balay row = nidx[k]; 3010e4d965acSSatish Balay start = ai[row]; 3011e4d965acSSatish Balay end = ai[row+1]; 301204a348a9SBarry Smith for (l = start; l<end; l++) { 3013efb16452SHong Zhang val = aj[l]; 30142205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 3015e4d965acSSatish Balay } 3016e4d965acSSatish Balay } 3017e4d965acSSatish Balay } 301870b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 3019e4d965acSSatish Balay } 302094bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 3021606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 30223a40ed3dSBarry Smith PetscFunctionReturn(0); 30234dcbc457SBarry Smith } 302417ab2063SBarry Smith 30250513a670SBarry Smith /* -------------------------------------------------------------- */ 3026dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 30270513a670SBarry Smith { 30280513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 30296849ba73SBarry Smith PetscErrorCode ierr; 30303b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 30315d0c19d7SBarry Smith const PetscInt *row,*col; 30325d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 303356cd22aeSBarry Smith IS icolp,irowp; 30340298fd71SBarry Smith PetscInt *cwork = NULL; 30350298fd71SBarry Smith PetscScalar *vwork = NULL; 30360513a670SBarry Smith 30373a40ed3dSBarry Smith PetscFunctionBegin; 30384c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 303956cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 30404c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 304156cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 30420513a670SBarry Smith 30430513a670SBarry Smith /* determine lengths of permuted rows */ 3044854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 30452205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 3046ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 3047f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 304833d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 30497adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 3050ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 3051606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 30520513a670SBarry Smith 3053785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 30540513a670SBarry Smith for (i=0; i<m; i++) { 305532ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30562205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 3057cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 305832ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30590513a670SBarry Smith } 3060606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 30612205254eSKarl Rupp 30623c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 30632205254eSKarl Rupp 30648c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3065b470e4b4SRichard Tran Mills ierr = MatBindToCPU(*B,A->boundtocpu);CHKERRQ(ierr); 30669fe5e383SStefano Zampini #endif 30670513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30680513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 306956cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 307056cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 30716bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 30726bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 30736768869dSprj- if (rowp == colp) { 3074dc29a518SPierre Jolivet ierr = MatPropagateSymmetryOptions(A,*B);CHKERRQ(ierr); 30756768869dSprj- } 30763a40ed3dSBarry Smith PetscFunctionReturn(0); 30770513a670SBarry Smith } 30780513a670SBarry Smith 3079dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 3080cb5b572fSBarry Smith { 3081dfbe8321SBarry Smith PetscErrorCode ierr; 3082cb5b572fSBarry Smith 3083cb5b572fSBarry Smith PetscFunctionBegin; 308433f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 308533f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 3086be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3087be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 30882e5835c6SStefano Zampini const PetscScalar *aa; 3089be6bf707SBarry Smith 30902e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 30914d805d7cSStefano 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]); 30922e5835c6SStefano Zampini ierr = PetscArraycpy(b->a,aa,a->i[A->rmap->n]);CHKERRQ(ierr); 3093cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 30942e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 3095cb5b572fSBarry Smith } else { 3096cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3097cb5b572fSBarry Smith } 3098cb5b572fSBarry Smith PetscFunctionReturn(0); 3099cb5b572fSBarry Smith } 3100cb5b572fSBarry Smith 31014994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 3102273d9f13SBarry Smith { 3103dfbe8321SBarry Smith PetscErrorCode ierr; 3104273d9f13SBarry Smith 3105273d9f13SBarry Smith PetscFunctionBegin; 3106f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 3107273d9f13SBarry Smith PetscFunctionReturn(0); 3108273d9f13SBarry Smith } 3109273d9f13SBarry Smith 3110f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 31116c0721eeSBarry Smith { 31126c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 31136e111a19SKarl Rupp 31146c0721eeSBarry Smith PetscFunctionBegin; 31156c0721eeSBarry Smith *array = a->a; 31166c0721eeSBarry Smith PetscFunctionReturn(0); 31176c0721eeSBarry Smith } 31186c0721eeSBarry Smith 3119f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 31206c0721eeSBarry Smith { 31216c0721eeSBarry Smith PetscFunctionBegin; 3122f38c1e66SStefano Zampini *array = NULL; 31236c0721eeSBarry Smith PetscFunctionReturn(0); 31246c0721eeSBarry Smith } 3125273d9f13SBarry Smith 31268229c054SShri Abhyankar /* 31278229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 31288229c054SShri Abhyankar have different nonzero structure. 31298229c054SShri Abhyankar */ 3130b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 3131ec7775f6SShri Abhyankar { 3132b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 3133ec7775f6SShri Abhyankar 3134ec7775f6SShri Abhyankar PetscFunctionBegin; 3135ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 3136ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 3137b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 3138b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 3139b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 31408af7cee1SJed Brown nnz[i] = 0; 31418af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 3142b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 3143b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 31448af7cee1SJed Brown nnz[i]++; 31458af7cee1SJed Brown } 31468af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 3147ec7775f6SShri Abhyankar } 3148ec7775f6SShri Abhyankar PetscFunctionReturn(0); 3149ec7775f6SShri Abhyankar } 3150ec7775f6SShri Abhyankar 3151b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 3152b264fe52SHong Zhang { 3153b264fe52SHong Zhang PetscInt m = Y->rmap->N; 3154b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 3155b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 3156b264fe52SHong Zhang PetscErrorCode ierr; 3157b264fe52SHong Zhang 3158b264fe52SHong Zhang PetscFunctionBegin; 3159b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 3160b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 3161b264fe52SHong Zhang PetscFunctionReturn(0); 3162b264fe52SHong Zhang } 3163b264fe52SHong Zhang 3164f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 3165ac90fabeSBarry Smith { 3166dfbe8321SBarry Smith PetscErrorCode ierr; 3167ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 3168ac90fabeSBarry Smith 3169ac90fabeSBarry Smith PetscFunctionBegin; 317041f5e1b1SStefano Zampini if (str == UNKNOWN_NONZERO_PATTERN && x->nz == y->nz) { 317181fa06acSBarry Smith PetscBool e; 317281fa06acSBarry Smith ierr = PetscArraycmp(x->i,y->i,Y->rmap->n+1,&e);CHKERRQ(ierr); 317381fa06acSBarry Smith if (e) { 317481fa06acSBarry Smith ierr = PetscArraycmp(x->j,y->j,y->nz,&e);CHKERRQ(ierr); 317581fa06acSBarry Smith if (e) { 317681fa06acSBarry Smith str = SAME_NONZERO_PATTERN; 317781fa06acSBarry Smith } 317881fa06acSBarry Smith } 317981fa06acSBarry Smith } 3180ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 31812e5835c6SStefano Zampini const PetscScalar *xa; 31822e5835c6SStefano Zampini PetscScalar *ya,alpha = a; 318381fa06acSBarry Smith PetscBLASInt one = 1,bnz; 318481fa06acSBarry Smith 318581fa06acSBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 31862e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(Y,&ya);CHKERRQ(ierr); 31872e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(X,&xa);CHKERRQ(ierr); 31882e5835c6SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,xa,&one,ya,&one)); 31892e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(X,&xa);CHKERRQ(ierr); 31902e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(Y,&ya);CHKERRQ(ierr); 319141f5e1b1SStefano Zampini ierr = PetscLogFlops(2.0*bnz);CHKERRQ(ierr); 3192acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 3193a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 3194ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 3195ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 3196ac90fabeSBarry Smith } else { 31978229c054SShri Abhyankar Mat B; 31988229c054SShri Abhyankar PetscInt *nnz; 3199785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 3200ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 3201bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 320281fa06acSBarry Smith ierr = MatSetLayouts(B,Y->rmap,Y->cmap);CHKERRQ(ierr); 32032e5835c6SStefano Zampini ierr = MatSetType(B,((PetscObject)Y)->type_name);CHKERRQ(ierr); 32048229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 3205ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 3206ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 320728be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 32088229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 3209ac90fabeSBarry Smith } 3210ac90fabeSBarry Smith PetscFunctionReturn(0); 3211ac90fabeSBarry Smith } 3212ac90fabeSBarry Smith 32132726fb6dSPierre Jolivet PETSC_INTERN PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3214354c94deSBarry Smith { 3215354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3216354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3217354c94deSBarry Smith PetscInt i,nz; 3218354c94deSBarry Smith PetscScalar *a; 3219ce496241SStefano Zampini PetscErrorCode ierr; 3220354c94deSBarry Smith 3221354c94deSBarry Smith PetscFunctionBegin; 3222354c94deSBarry Smith nz = aij->nz; 3223ce496241SStefano Zampini ierr = MatSeqAIJGetArray(mat,&a);CHKERRQ(ierr); 32242205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 3225ce496241SStefano Zampini ierr = MatSeqAIJRestoreArray(mat,&a);CHKERRQ(ierr); 3226354c94deSBarry Smith #else 3227354c94deSBarry Smith PetscFunctionBegin; 3228354c94deSBarry Smith #endif 3229354c94deSBarry Smith PetscFunctionReturn(0); 3230354c94deSBarry Smith } 3231354c94deSBarry Smith 3232985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3233e34fafa9SBarry Smith { 3234e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3235e34fafa9SBarry Smith PetscErrorCode ierr; 3236d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3237e34fafa9SBarry Smith PetscReal atmp; 3238985db425SBarry Smith PetscScalar *x; 3239ce496241SStefano Zampini const MatScalar *aa,*av; 3240e34fafa9SBarry Smith 3241e34fafa9SBarry Smith PetscFunctionBegin; 3242e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3243ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3244ce496241SStefano Zampini aa = av; 3245e34fafa9SBarry Smith ai = a->i; 3246e34fafa9SBarry Smith aj = a->j; 3247e34fafa9SBarry Smith 3248985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3249475b8b61SHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3250e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3251e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3252e34fafa9SBarry Smith for (i=0; i<m; i++) { 3253e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 3254e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3255985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3256985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3257985db425SBarry Smith aa++; aj++; 3258985db425SBarry Smith } 3259985db425SBarry Smith } 3260475b8b61SHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3261ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3262985db425SBarry Smith PetscFunctionReturn(0); 3263985db425SBarry Smith } 3264985db425SBarry Smith 3265985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3266985db425SBarry Smith { 3267985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3268985db425SBarry Smith PetscErrorCode ierr; 3269d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3270985db425SBarry Smith PetscScalar *x; 3271ce496241SStefano Zampini const MatScalar *aa,*av; 3272985db425SBarry Smith 3273985db425SBarry Smith PetscFunctionBegin; 3274e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3275ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3276ce496241SStefano Zampini aa = av; 3277985db425SBarry Smith ai = a->i; 3278985db425SBarry Smith aj = a->j; 3279985db425SBarry Smith 3280985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3281fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3282985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3283e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3284985db425SBarry Smith for (i=0; i<m; i++) { 3285985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3286d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3287985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3288985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3289985db425SBarry Smith x[i] = 0.0; 3290985db425SBarry Smith if (idx) { 3291985db425SBarry Smith for (j=0; j<ncols; j++) { /* find first implicit 0.0 in the row */ 3292985db425SBarry Smith if (aj[j] > j) { 3293985db425SBarry Smith idx[i] = j; 3294985db425SBarry Smith break; 3295985db425SBarry Smith } 3296985db425SBarry Smith } 32971a254869SHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 32981a254869SHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3299985db425SBarry Smith } 3300985db425SBarry Smith } 3301985db425SBarry Smith for (j=0; j<ncols; j++) { 3302985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3303985db425SBarry Smith aa++; aj++; 3304985db425SBarry Smith } 3305985db425SBarry Smith } 3306fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3307ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3308985db425SBarry Smith PetscFunctionReturn(0); 3309985db425SBarry Smith } 3310985db425SBarry Smith 3311c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3312c87e5d42SMatthew Knepley { 3313c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3314c87e5d42SMatthew Knepley PetscErrorCode ierr; 3315c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3316ce496241SStefano Zampini PetscScalar *x; 3317ce496241SStefano Zampini const MatScalar *aa,*av; 3318c87e5d42SMatthew Knepley 3319c87e5d42SMatthew Knepley PetscFunctionBegin; 3320ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3321ce496241SStefano Zampini aa = av; 3322c87e5d42SMatthew Knepley ai = a->i; 3323c87e5d42SMatthew Knepley aj = a->j; 3324c87e5d42SMatthew Knepley 3325c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3326f07e67edSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3327c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3328f07e67edSHong Zhang if (n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %D vs. %D rows", m, n); 3329c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3330c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3331f07e67edSHong Zhang if (ncols == A->cmap->n) { /* row is dense */ 3332f07e67edSHong Zhang x[i] = *aa; if (idx) idx[i] = 0; 3333f07e67edSHong Zhang } else { /* row is sparse so already KNOW minimum is 0.0 or higher */ 3334f07e67edSHong Zhang x[i] = 0.0; 3335f07e67edSHong Zhang if (idx) { /* find first implicit 0.0 in the row */ 3336289a08f5SMatthew Knepley for (j=0; j<ncols; j++) { 3337f07e67edSHong Zhang if (aj[j] > j) { 3338f07e67edSHong Zhang idx[i] = j; 33392205254eSKarl Rupp break; 33402205254eSKarl Rupp } 3341289a08f5SMatthew Knepley } 3342f07e67edSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3343f07e67edSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3344f07e67edSHong Zhang } 3345289a08f5SMatthew Knepley } 3346c87e5d42SMatthew Knepley for (j=0; j<ncols; j++) { 3347f07e67edSHong Zhang if (PetscAbsScalar(x[i]) > PetscAbsScalar(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3348c87e5d42SMatthew Knepley aa++; aj++; 3349c87e5d42SMatthew Knepley } 3350c87e5d42SMatthew Knepley } 3351f07e67edSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3352ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3353c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3354c87e5d42SMatthew Knepley } 3355c87e5d42SMatthew Knepley 3356985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3357985db425SBarry Smith { 3358985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3359985db425SBarry Smith PetscErrorCode ierr; 3360d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3361d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3362985db425SBarry Smith PetscScalar *x; 3363ce496241SStefano Zampini const MatScalar *aa,*av; 3364985db425SBarry Smith 3365985db425SBarry Smith PetscFunctionBegin; 3366e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3367ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3368ce496241SStefano Zampini aa = av; 3369985db425SBarry Smith ai = a->i; 3370985db425SBarry Smith aj = a->j; 3371985db425SBarry Smith 3372985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3373fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3374985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3375f07e67edSHong Zhang if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3376985db425SBarry Smith for (i=0; i<m; i++) { 3377985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3378d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3379985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3380985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3381985db425SBarry Smith x[i] = 0.0; 3382985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3383985db425SBarry Smith for (j=0; j<ncols; j++) { 3384985db425SBarry Smith if (aj[j] > j) { 3385985db425SBarry Smith idx[i] = j; 3386985db425SBarry Smith break; 3387985db425SBarry Smith } 3388985db425SBarry Smith } 3389fa213d2fSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3390fa213d2fSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3391985db425SBarry Smith } 3392985db425SBarry Smith } 3393985db425SBarry Smith for (j=0; j<ncols; j++) { 3394985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3395985db425SBarry Smith aa++; aj++; 3396e34fafa9SBarry Smith } 3397e34fafa9SBarry Smith } 3398fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3399ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3400e34fafa9SBarry Smith PetscFunctionReturn(0); 3401e34fafa9SBarry Smith } 3402bbead8a2SBarry Smith 3403713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3404bbead8a2SBarry Smith { 3405bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3406bbead8a2SBarry Smith PetscErrorCode ierr; 340733d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3408bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 34090da83c2eSBarry Smith const PetscReal shift = 0.0; 34101a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3411bbead8a2SBarry Smith 3412bbead8a2SBarry Smith PetscFunctionBegin; 3413a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 34144a0d0026SBarry Smith if (a->ibdiagvalid) { 34154a0d0026SBarry Smith if (values) *values = a->ibdiag; 34164a0d0026SBarry Smith PetscFunctionReturn(0); 34174a0d0026SBarry Smith } 3418bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3419bbead8a2SBarry Smith if (!a->ibdiag) { 3420785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 34213bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3422bbead8a2SBarry Smith } 3423bbead8a2SBarry Smith diag = a->ibdiag; 3424bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3425bbead8a2SBarry Smith /* factor and invert each block */ 3426bbead8a2SBarry Smith switch (bs) { 3427bbead8a2SBarry Smith case 1: 3428bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3429bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3430ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3431ec1892c8SHong Zhang if (allowzeropivot) { 34327b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 34337b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 34347b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 34357b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 34367b6c816cSBarry 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); 3437ec1892c8SHong Zhang } 3438bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3439bbead8a2SBarry Smith } 3440bbead8a2SBarry Smith break; 3441bbead8a2SBarry Smith case 2: 3442bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3443bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3444bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3445a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34467b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 344796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3448bbead8a2SBarry Smith diag += 4; 3449bbead8a2SBarry Smith } 3450bbead8a2SBarry Smith break; 3451bbead8a2SBarry Smith case 3: 3452bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3453bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3454bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3455a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34567b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 345796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3458bbead8a2SBarry Smith diag += 9; 3459bbead8a2SBarry Smith } 3460bbead8a2SBarry Smith break; 3461bbead8a2SBarry Smith case 4: 3462bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3463bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3464bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3465a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34667b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 346796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3468bbead8a2SBarry Smith diag += 16; 3469bbead8a2SBarry Smith } 3470bbead8a2SBarry Smith break; 3471bbead8a2SBarry Smith case 5: 3472bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3473bbead8a2SBarry 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; 3474bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3475a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34767b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 347796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3478bbead8a2SBarry Smith diag += 25; 3479bbead8a2SBarry Smith } 3480bbead8a2SBarry Smith break; 3481bbead8a2SBarry Smith case 6: 3482bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3483bbead8a2SBarry 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; 3484bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3485a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34867b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 348796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3488bbead8a2SBarry Smith diag += 36; 3489bbead8a2SBarry Smith } 3490bbead8a2SBarry Smith break; 3491bbead8a2SBarry Smith case 7: 3492bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3493bbead8a2SBarry 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; 3494bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3495a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34967b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 349796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3498bbead8a2SBarry Smith diag += 49; 3499bbead8a2SBarry Smith } 3500bbead8a2SBarry Smith break; 3501bbead8a2SBarry Smith default: 3502dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3503bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3504bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3505bbead8a2SBarry Smith IJ[j] = bs*i + j; 3506bbead8a2SBarry Smith } 3507bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 35085f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 35097b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 351096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3511bbead8a2SBarry Smith diag += bs2; 3512bbead8a2SBarry Smith } 3513bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3514bbead8a2SBarry Smith } 3515bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3516bbead8a2SBarry Smith PetscFunctionReturn(0); 3517bbead8a2SBarry Smith } 3518bbead8a2SBarry Smith 351973a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 352073a71a0fSBarry Smith { 352173a71a0fSBarry Smith PetscErrorCode ierr; 352273a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 352373a71a0fSBarry Smith PetscScalar a; 352473a71a0fSBarry Smith PetscInt m,n,i,j,col; 352573a71a0fSBarry Smith 352673a71a0fSBarry Smith PetscFunctionBegin; 352773a71a0fSBarry Smith if (!x->assembled) { 352873a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 352973a71a0fSBarry Smith for (i=0; i<m; i++) { 353073a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 353173a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 353273a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 353373a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 353473a71a0fSBarry Smith } 353573a71a0fSBarry Smith } 3536e2ce353bSJunchao Zhang } else { 3537e2ce353bSJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aij->a+i);CHKERRQ(ierr);} 3538e2ce353bSJunchao Zhang } 3539ce496241SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 3540ce496241SStefano Zampini if (x->offloadmask != PETSC_OFFLOAD_UNALLOCATED) x->offloadmask = PETSC_OFFLOAD_CPU; 3541ce496241SStefano Zampini #endif 354273a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 354373a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 354473a71a0fSBarry Smith PetscFunctionReturn(0); 354573a71a0fSBarry Smith } 354673a71a0fSBarry Smith 3547679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3548679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3549679944adSJunchao Zhang { 3550679944adSJunchao Zhang PetscErrorCode ierr; 3551679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3552679944adSJunchao Zhang PetscScalar a; 3553679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3554679944adSJunchao Zhang 3555679944adSJunchao Zhang PetscFunctionBegin; 3556679944adSJunchao Zhang nskip = high - low; 3557679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3558679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3559679944adSJunchao Zhang for (i=0; i<m; i++) { 3560679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3561679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3562679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3563679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3564679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3565679944adSJunchao Zhang } 3566e2ce353bSJunchao Zhang } 3567679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3568679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3569679944adSJunchao Zhang PetscFunctionReturn(0); 3570679944adSJunchao Zhang } 3571679944adSJunchao Zhang 3572679944adSJunchao Zhang 3573682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 35740a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3575cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3576cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3577cb5b572fSBarry Smith MatMult_SeqAIJ, 357897304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 35797c922b88SBarry Smith MatMultTranspose_SeqAIJ, 35807c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3581f4259b30SLisandro Dalcin NULL, 3582f4259b30SLisandro Dalcin NULL, 3583f4259b30SLisandro Dalcin NULL, 3584f4259b30SLisandro Dalcin /* 10*/ NULL, 3585cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3586f4259b30SLisandro Dalcin NULL, 358741f059aeSBarry Smith MatSOR_SeqAIJ, 358891e9d3e2SHong Zhang MatTranspose_SeqAIJ, 358997304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3590cb5b572fSBarry Smith MatEqual_SeqAIJ, 3591cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3592cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3593cb5b572fSBarry Smith MatNorm_SeqAIJ, 3594f4259b30SLisandro Dalcin /* 20*/ NULL, 3595cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3596cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3597cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3598d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3599f4259b30SLisandro Dalcin NULL, 3600f4259b30SLisandro Dalcin NULL, 3601f4259b30SLisandro Dalcin NULL, 3602f4259b30SLisandro Dalcin NULL, 36034994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3604f4259b30SLisandro Dalcin NULL, 3605f4259b30SLisandro Dalcin NULL, 3606f4259b30SLisandro Dalcin NULL, 3607f4259b30SLisandro Dalcin NULL, 3608d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3609f4259b30SLisandro Dalcin NULL, 3610f4259b30SLisandro Dalcin NULL, 3611cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3612f4259b30SLisandro Dalcin NULL, 3613d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 36147dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3615cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3616cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3617cb5b572fSBarry Smith MatCopy_SeqAIJ, 3618d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3619cb5b572fSBarry Smith MatScale_SeqAIJ, 36207d68702bSBarry Smith MatShift_SeqAIJ, 362179299369SBarry Smith MatDiagonalSet_SeqAIJ, 36226e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 362373a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 36243b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 36253b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 36263b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3627a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 362893dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3629f4259b30SLisandro Dalcin NULL, 3630f4259b30SLisandro Dalcin NULL, 3631cda55fadSBarry Smith MatPermute_SeqAIJ, 3632f4259b30SLisandro Dalcin NULL, 3633f4259b30SLisandro Dalcin /* 59*/ NULL, 3634b9b97703SBarry Smith MatDestroy_SeqAIJ, 3635b9b97703SBarry Smith MatView_SeqAIJ, 3636f4259b30SLisandro Dalcin NULL, 3637f4259b30SLisandro Dalcin NULL, 3638f4259b30SLisandro Dalcin /* 64*/ NULL, 3639321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3640f4259b30SLisandro Dalcin NULL, 3641f4259b30SLisandro Dalcin NULL, 3642f4259b30SLisandro Dalcin NULL, 3643d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3644c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3645f4259b30SLisandro Dalcin NULL, 3646f4259b30SLisandro Dalcin NULL, 3647f4259b30SLisandro Dalcin NULL, 3648f4259b30SLisandro Dalcin /* 74*/ NULL, 36493acb8795SBarry Smith MatFDColoringApply_AIJ, 3650f4259b30SLisandro Dalcin NULL, 3651f4259b30SLisandro Dalcin NULL, 3652f4259b30SLisandro Dalcin NULL, 36536ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 3654f4259b30SLisandro Dalcin NULL, 3655f4259b30SLisandro Dalcin NULL, 3656f4259b30SLisandro Dalcin NULL, 3657bc011b1eSHong Zhang MatLoad_SeqAIJ, 3658d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 36591cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 3660f4259b30SLisandro Dalcin NULL, 3661f4259b30SLisandro Dalcin NULL, 3662f4259b30SLisandro Dalcin NULL, 3663f4259b30SLisandro Dalcin /* 89*/ NULL, 3664f4259b30SLisandro Dalcin NULL, 366526be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3666f4259b30SLisandro Dalcin NULL, 3667f4259b30SLisandro Dalcin NULL, 36688fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 3669f4259b30SLisandro Dalcin NULL, 3670f4259b30SLisandro Dalcin NULL, 36716fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 3672f4259b30SLisandro Dalcin NULL, 36734222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqAIJ, 3674f4259b30SLisandro Dalcin NULL, 3675f4259b30SLisandro Dalcin NULL, 367687d4246cSBarry Smith MatConjugate_SeqAIJ, 3677f4259b30SLisandro Dalcin NULL, 3678d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 367999cafbc1SBarry Smith MatRealPart_SeqAIJ, 3680f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3681f4259b30SLisandro Dalcin NULL, 3682f4259b30SLisandro Dalcin NULL, 3683cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3684f4259b30SLisandro Dalcin NULL, 36852af78befSBarry Smith MatGetRowMin_SeqAIJ, 3686f4259b30SLisandro Dalcin NULL, 3687599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3688f4259b30SLisandro Dalcin /*114*/ NULL, 3689f4259b30SLisandro Dalcin NULL, 3690f4259b30SLisandro Dalcin NULL, 3691f4259b30SLisandro Dalcin NULL, 3692f4259b30SLisandro Dalcin NULL, 3693f4259b30SLisandro Dalcin /*119*/ NULL, 3694f4259b30SLisandro Dalcin NULL, 3695f4259b30SLisandro Dalcin NULL, 3696f4259b30SLisandro Dalcin NULL, 3697b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 36980716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3699bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 370037868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 37010da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 3702f4259b30SLisandro Dalcin NULL, 3703f4259b30SLisandro Dalcin /*129*/ NULL, 3704f4259b30SLisandro Dalcin NULL, 3705f4259b30SLisandro Dalcin NULL, 370675648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3707b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3708b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 37092b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 3710f4259b30SLisandro Dalcin NULL, 3711f4259b30SLisandro Dalcin NULL, 37123964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 3713f4259b30SLisandro Dalcin /*139*/NULL, 3714f4259b30SLisandro Dalcin NULL, 3715f4259b30SLisandro Dalcin NULL, 37163a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 37179c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 37184222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 37194222ddf1SHong Zhang /*145*/MatDestroySubMatrices_SeqAIJ, 3720f4259b30SLisandro Dalcin NULL, 3721f4259b30SLisandro Dalcin NULL 37229e29f15eSvictorle }; 372317ab2063SBarry Smith 37247087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3725bef8e0ddSBarry Smith { 3726bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 372797f1f81fSBarry Smith PetscInt i,nz,n; 3728bef8e0ddSBarry Smith 3729bef8e0ddSBarry Smith PetscFunctionBegin; 3730bef8e0ddSBarry Smith nz = aij->maxnz; 3731d0f46423SBarry Smith n = mat->rmap->n; 3732bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3733bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3734bef8e0ddSBarry Smith } 3735bef8e0ddSBarry Smith aij->nz = nz; 3736bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3737bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3738bef8e0ddSBarry Smith } 3739bef8e0ddSBarry Smith PetscFunctionReturn(0); 3740bef8e0ddSBarry Smith } 3741bef8e0ddSBarry Smith 3742a3bb6f32SFande Kong /* 3743e8b528d9SFande Kong * When a sparse matrix has many zero columns, we should compact them out to save the space 3744a3bb6f32SFande Kong * This happens in MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3745a3bb6f32SFande Kong * */ 3746a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3747a3bb6f32SFande Kong { 3748a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3749a3bb6f32SFande Kong PetscTable gid1_lid1; 3750a3bb6f32SFande Kong PetscTablePosition tpos; 375125b670f0SStefano Zampini PetscInt gid,lid,i,ec,nz = aij->nz; 375225b670f0SStefano Zampini PetscInt *garray,*jj = aij->j; 3753a3bb6f32SFande Kong PetscErrorCode ierr; 3754a3bb6f32SFande Kong 3755a3bb6f32SFande Kong PetscFunctionBegin; 3756a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3757a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3758a3bb6f32SFande Kong /* use a table */ 3759a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3760a3bb6f32SFande Kong ec = 0; 376125b670f0SStefano Zampini for (i=0; i<nz; i++) { 376225b670f0SStefano Zampini PetscInt data,gid1 = jj[i] + 1; 3763a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3764a3bb6f32SFande Kong if (!data) { 3765a3bb6f32SFande Kong /* one based table */ 3766a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3767a3bb6f32SFande Kong } 3768a3bb6f32SFande Kong } 3769a3bb6f32SFande Kong /* form array of columns we need */ 3770a3bb6f32SFande Kong ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); 3771a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3772a3bb6f32SFande Kong while (tpos) { 3773a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3774a3bb6f32SFande Kong gid--; 3775a3bb6f32SFande Kong lid--; 3776a3bb6f32SFande Kong garray[lid] = gid; 3777a3bb6f32SFande Kong } 3778a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3779a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3780a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3781a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3782a3bb6f32SFande Kong } 3783a3bb6f32SFande Kong /* compact out the extra columns in B */ 378425b670f0SStefano Zampini for (i=0; i<nz; i++) { 378525b670f0SStefano Zampini PetscInt gid1 = jj[i] + 1; 3786a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3787a3bb6f32SFande Kong lid--; 378825b670f0SStefano Zampini jj[i] = lid; 3789a3bb6f32SFande Kong } 3790ca5434daSLawrence Mitchell ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 3791a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 379225b670f0SStefano Zampini ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr); 3793a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3794a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3795a3bb6f32SFande Kong PetscFunctionReturn(0); 3796a3bb6f32SFande Kong } 3797a3bb6f32SFande Kong 3798bef8e0ddSBarry Smith /*@ 3799bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3800bef8e0ddSBarry Smith in the matrix. 3801bef8e0ddSBarry Smith 3802bef8e0ddSBarry Smith Input Parameters: 3803bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3804bef8e0ddSBarry Smith - indices - the column indices 3805bef8e0ddSBarry Smith 380615091d37SBarry Smith Level: advanced 380715091d37SBarry Smith 3808bef8e0ddSBarry Smith Notes: 3809bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3810bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3811bef8e0ddSBarry Smith of the MatSetValues() operation. 3812bef8e0ddSBarry Smith 3813bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3814d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3815bef8e0ddSBarry Smith 3816bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3817bef8e0ddSBarry Smith 3818b9617806SBarry Smith The indices should start with zero, not one. 3819b9617806SBarry Smith 3820bef8e0ddSBarry Smith @*/ 38217087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3822bef8e0ddSBarry Smith { 38234ac538c5SBarry Smith PetscErrorCode ierr; 3824bef8e0ddSBarry Smith 3825bef8e0ddSBarry Smith PetscFunctionBegin; 38260700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 38274482741eSBarry Smith PetscValidPointer(indices,2); 38284ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3829bef8e0ddSBarry Smith PetscFunctionReturn(0); 3830bef8e0ddSBarry Smith } 3831bef8e0ddSBarry Smith 3832be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3833be6bf707SBarry Smith 38347087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3835be6bf707SBarry Smith { 3836be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 38376849ba73SBarry Smith PetscErrorCode ierr; 3838d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3839be6bf707SBarry Smith 3840be6bf707SBarry Smith PetscFunctionBegin; 3841169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3842be6bf707SBarry Smith 3843be6bf707SBarry Smith /* allocate space for values if not already there */ 3844be6bf707SBarry Smith if (!aij->saved_values) { 3845854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 38463bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3847be6bf707SBarry Smith } 3848be6bf707SBarry Smith 3849be6bf707SBarry Smith /* copy values over */ 3850580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3851be6bf707SBarry Smith PetscFunctionReturn(0); 3852be6bf707SBarry Smith } 3853be6bf707SBarry Smith 3854be6bf707SBarry Smith /*@ 3855be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3856be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3857be6bf707SBarry Smith nonlinear portion. 3858be6bf707SBarry Smith 3859be6bf707SBarry Smith Collect on Mat 3860be6bf707SBarry Smith 3861be6bf707SBarry Smith Input Parameters: 38620e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3863be6bf707SBarry Smith 386415091d37SBarry Smith Level: advanced 386515091d37SBarry Smith 3866be6bf707SBarry Smith Common Usage, with SNESSolve(): 3867be6bf707SBarry Smith $ Create Jacobian matrix 3868be6bf707SBarry Smith $ Set linear terms into matrix 3869be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3870be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3871be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3872512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3873be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3874be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3875be6bf707SBarry Smith $ In your Jacobian routine 3876be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3877be6bf707SBarry Smith $ Set nonlinear terms in matrix 3878be6bf707SBarry Smith 3879be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3880be6bf707SBarry Smith $ // build linear portion of Jacobian 3881512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3882be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3883be6bf707SBarry Smith $ loop over nonlinear iterations 3884be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3885be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3886be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3887be6bf707SBarry Smith $ Solve linear system with Jacobian 3888be6bf707SBarry Smith $ endloop 3889be6bf707SBarry Smith 3890be6bf707SBarry Smith Notes: 3891be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3892512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3893be6bf707SBarry Smith calling this routine. 3894be6bf707SBarry Smith 38950c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 38960c468ba9SBarry Smith and does not allocated additional space. 38970c468ba9SBarry Smith 3898be6bf707SBarry Smith .seealso: MatRetrieveValues() 3899be6bf707SBarry Smith 3900be6bf707SBarry Smith @*/ 39017087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3902be6bf707SBarry Smith { 39034ac538c5SBarry Smith PetscErrorCode ierr; 3904be6bf707SBarry Smith 3905be6bf707SBarry Smith PetscFunctionBegin; 39060700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3907e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3908e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 39094ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3910be6bf707SBarry Smith PetscFunctionReturn(0); 3911be6bf707SBarry Smith } 3912be6bf707SBarry Smith 39137087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3914be6bf707SBarry Smith { 3915be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 39166849ba73SBarry Smith PetscErrorCode ierr; 3917d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3918be6bf707SBarry Smith 3919be6bf707SBarry Smith PetscFunctionBegin; 3920169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3921f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3922be6bf707SBarry Smith /* copy values over */ 3923580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3924be6bf707SBarry Smith PetscFunctionReturn(0); 3925be6bf707SBarry Smith } 3926be6bf707SBarry Smith 3927be6bf707SBarry Smith /*@ 3928be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3929be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3930be6bf707SBarry Smith nonlinear portion. 3931be6bf707SBarry Smith 3932be6bf707SBarry Smith Collect on Mat 3933be6bf707SBarry Smith 3934be6bf707SBarry Smith Input Parameters: 3935386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3936be6bf707SBarry Smith 393715091d37SBarry Smith Level: advanced 393815091d37SBarry Smith 3939be6bf707SBarry Smith .seealso: MatStoreValues() 3940be6bf707SBarry Smith 3941be6bf707SBarry Smith @*/ 39427087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3943be6bf707SBarry Smith { 39444ac538c5SBarry Smith PetscErrorCode ierr; 3945be6bf707SBarry Smith 3946be6bf707SBarry Smith PetscFunctionBegin; 39470700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3948e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3949e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 39504ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3951be6bf707SBarry Smith PetscFunctionReturn(0); 3952be6bf707SBarry Smith } 3953be6bf707SBarry Smith 3954f83d6046SBarry Smith 3955be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 395617ab2063SBarry Smith /*@C 3957682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 39580d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 39596e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 396051c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 39612bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 396217ab2063SBarry Smith 3963d083f849SBarry Smith Collective 3964db81eaa0SLois Curfman McInnes 396517ab2063SBarry Smith Input Parameters: 3966db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 396717ab2063SBarry Smith . m - number of rows 396817ab2063SBarry Smith . n - number of columns 396917ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 397051c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39710298fd71SBarry Smith (possibly different for each row) or NULL 397217ab2063SBarry Smith 397317ab2063SBarry Smith Output Parameter: 3974416022c9SBarry Smith . A - the matrix 397517ab2063SBarry Smith 3976175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3977f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3978175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3979175b88e8SBarry Smith 3980b259b22eSLois Curfman McInnes Notes: 398149a6f317SBarry Smith If nnz is given then nz is ignored 398249a6f317SBarry Smith 398317ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 398417ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 39850002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 398644cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 398717ab2063SBarry Smith 398817ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39890298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 39903d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 39916da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 399217ab2063SBarry Smith 3993682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 39944fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3995682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 39966c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 39976c7ebb05SLois Curfman McInnes 39986c7ebb05SLois Curfman McInnes Options Database Keys: 3999698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 40009db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 400117ab2063SBarry Smith 4002027ccd11SLois Curfman McInnes Level: intermediate 4003027ccd11SLois Curfman McInnes 400469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 400536db0b34SBarry Smith 400617ab2063SBarry Smith @*/ 40077087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 400817ab2063SBarry Smith { 4009dfbe8321SBarry Smith PetscErrorCode ierr; 40106945ee14SBarry Smith 40113a40ed3dSBarry Smith PetscFunctionBegin; 4012f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 4013117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 4014c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 4015d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 4016273d9f13SBarry Smith PetscFunctionReturn(0); 4017273d9f13SBarry Smith } 4018273d9f13SBarry Smith 4019273d9f13SBarry Smith /*@C 4020273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 4021273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 4022273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 4023273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 4024273d9f13SBarry Smith 4025d083f849SBarry Smith Collective 4026273d9f13SBarry Smith 4027273d9f13SBarry Smith Input Parameters: 40281c4f3114SJed Brown + B - The matrix 4029273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 4030273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 40310298fd71SBarry Smith (possibly different for each row) or NULL 4032273d9f13SBarry Smith 4033273d9f13SBarry Smith Notes: 403449a6f317SBarry Smith If nnz is given then nz is ignored 403549a6f317SBarry Smith 4036273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 4037273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 4038273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 4039273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 4040273d9f13SBarry Smith 4041273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 40420298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 4043273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 4044273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 4045273d9f13SBarry Smith 4046aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 4047aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 4048aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 4049aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 4050aa95bbe8SBarry Smith 4051a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 4052a96a251dSBarry Smith entries or columns indices 4053a96a251dSBarry Smith 4054273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 4055273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 4056273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 4057273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 4058273d9f13SBarry Smith 4059273d9f13SBarry Smith Options Database Keys: 4060698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 406147b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 4062273d9f13SBarry Smith 4063273d9f13SBarry Smith Level: intermediate 4064273d9f13SBarry Smith 406519b08ed1SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo(), 406619b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation() 4067273d9f13SBarry Smith 4068273d9f13SBarry Smith @*/ 40697087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 4070273d9f13SBarry Smith { 40714ac538c5SBarry Smith PetscErrorCode ierr; 4072a23d5eceSKris Buschelman 4073a23d5eceSKris Buschelman PetscFunctionBegin; 40746ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 40756ba663aaSJed Brown PetscValidType(B,1); 40764ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 4077a23d5eceSKris Buschelman PetscFunctionReturn(0); 4078a23d5eceSKris Buschelman } 4079a23d5eceSKris Buschelman 40807087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 4081a23d5eceSKris Buschelman { 4082273d9f13SBarry Smith Mat_SeqAIJ *b; 40832576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 40846849ba73SBarry Smith PetscErrorCode ierr; 408597f1f81fSBarry Smith PetscInt i; 4086273d9f13SBarry Smith 4087273d9f13SBarry Smith PetscFunctionBegin; 40882576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 4089a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 4090c461c341SBarry Smith skipallocation = PETSC_TRUE; 4091c461c341SBarry Smith nz = 0; 4092c461c341SBarry Smith } 409326283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 409426283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4095899cda47SBarry Smith 4096435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 409760e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 4098cf9c20a2SJed Brown if (PetscUnlikelyDebug(nnz)) { 4099d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 410060e0710aSBarry 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]); 410160e0710aSBarry 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); 4102b73539f3SBarry Smith } 4103b73539f3SBarry Smith } 4104b73539f3SBarry Smith 4105273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 41062205254eSKarl Rupp 4107273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 4108273d9f13SBarry Smith 4109ab93d7beSBarry Smith if (!skipallocation) { 41102ee49352SLisandro Dalcin if (!b->imax) { 4111071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 4112071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4113071fcb05SBarry Smith } 4114071fcb05SBarry Smith if (!b->ilen) { 4115071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 4116071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 4117071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4118071fcb05SBarry Smith } else { 4119071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 41202ee49352SLisandro Dalcin } 4121846b4da1SFande Kong if (!b->ipre) { 4122846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 4123846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4124846b4da1SFande Kong } 4125273d9f13SBarry Smith if (!nnz) { 4126435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 4127c62bd62aSJed Brown else if (nz < 0) nz = 1; 41285d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 4129d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 4130d0f46423SBarry Smith nz = nz*B->rmap->n; 4131273d9f13SBarry Smith } else { 4132c73702f5SBarry Smith PetscInt64 nz64 = 0; 4133c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 4134c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 4135273d9f13SBarry Smith } 4136ab93d7beSBarry Smith 4137273d9f13SBarry Smith /* allocate the matrix space */ 413853dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 41392ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 4140396832f4SHong Zhang if (B->structure_only) { 41415848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 41425848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 4143396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 4144396832f4SHong Zhang } else { 4145dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 41463bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 4147396832f4SHong Zhang } 4148bfeeae90SHong Zhang b->i[0] = 0; 4149d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 41505da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 41515da197adSKris Buschelman } 4152396832f4SHong Zhang if (B->structure_only) { 4153396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 4154396832f4SHong Zhang b->free_a = PETSC_FALSE; 4155396832f4SHong Zhang } else { 4156273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 4157e6b907acSBarry Smith b->free_a = PETSC_TRUE; 4158396832f4SHong Zhang } 4159e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 4160c461c341SBarry Smith } else { 4161e6b907acSBarry Smith b->free_a = PETSC_FALSE; 4162e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 4163c461c341SBarry Smith } 4164273d9f13SBarry Smith 4165846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 4166846b4da1SFande Kong /* reserve user-requested sparsity */ 4167580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 4168846b4da1SFande Kong } 4169846b4da1SFande Kong 4170846b4da1SFande Kong 4171273d9f13SBarry Smith b->nz = 0; 4172273d9f13SBarry Smith b->maxnz = nz; 4173273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 41742205254eSKarl Rupp if (realalloc) { 41752205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 41762205254eSKarl Rupp } 4177cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 4178cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 4179273d9f13SBarry Smith PetscFunctionReturn(0); 4180273d9f13SBarry Smith } 4181273d9f13SBarry Smith 4182846b4da1SFande Kong 4183846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 4184846b4da1SFande Kong { 4185846b4da1SFande Kong Mat_SeqAIJ *a; 4186a5bbaf83SFande Kong PetscInt i; 4187846b4da1SFande Kong PetscErrorCode ierr; 4188846b4da1SFande Kong 4189846b4da1SFande Kong PetscFunctionBegin; 4190846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 419114d0e64fSAlex Lindsay 419214d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 419314d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 419414d0e64fSAlex Lindsay 4195846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 41962c814fdeSFande Kong /* if no saved info, we error out */ 4197fb4dc15dSAlex Lindsay if (!a->ipre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 41982c814fdeSFande Kong 4199fb4dc15dSAlex 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"); 42002c814fdeSFande Kong 4201580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 4202580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 4203846b4da1SFande Kong a->i[0] = 0; 4204846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 4205846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 4206846b4da1SFande Kong } 4207846b4da1SFande Kong A->preallocated = PETSC_TRUE; 4208846b4da1SFande Kong a->nz = 0; 4209846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 4210846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 4211846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 4212846b4da1SFande Kong A->assembled = PETSC_FALSE; 4213846b4da1SFande Kong PetscFunctionReturn(0); 4214846b4da1SFande Kong } 4215846b4da1SFande Kong 421658d36128SBarry Smith /*@ 4217a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 4218a1661176SMatthew Knepley 4219a1661176SMatthew Knepley Input Parameters: 4220a1661176SMatthew Knepley + B - the matrix 4221a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4222a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4223a1661176SMatthew Knepley - v - optional values in the matrix 4224a1661176SMatthew Knepley 4225a1661176SMatthew Knepley Level: developer 4226a1661176SMatthew Knepley 42276a9b8d82SBarry Smith Notes: 422858d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 422958d36128SBarry Smith 42306a9b8d82SBarry Smith This routine may be called multiple times with different nonzero patterns (or the same nonzero pattern). The nonzero 42316a9b8d82SBarry Smith structure will be the union of all the previous nonzero structures. 42326a9b8d82SBarry Smith 42336a9b8d82SBarry Smith Developer Notes: 42346a9b8d82SBarry Smith An optimization could be added to the implementation where it checks if the i, and j are identical to the current i and j and 42356a9b8d82SBarry Smith then just copies the v values directly with PetscMemcpy(). 42366a9b8d82SBarry Smith 42376a9b8d82SBarry Smith This routine could also take a PetscCopyMode argument to allow sharing the values instead of always copying them. 42386a9b8d82SBarry Smith 42396a9b8d82SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ, MatResetPreallocation() 4240a1661176SMatthew Knepley @*/ 4241a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4242a1661176SMatthew Knepley { 4243a1661176SMatthew Knepley PetscErrorCode ierr; 4244a1661176SMatthew Knepley 4245a1661176SMatthew Knepley PetscFunctionBegin; 42460700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 42476ba663aaSJed Brown PetscValidType(B,1); 42484ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 4249a1661176SMatthew Knepley PetscFunctionReturn(0); 4250a1661176SMatthew Knepley } 4251a1661176SMatthew Knepley 42527087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4253a1661176SMatthew Knepley { 4254a1661176SMatthew Knepley PetscInt i; 4255a1661176SMatthew Knepley PetscInt m,n; 4256a1661176SMatthew Knepley PetscInt nz; 42576a9b8d82SBarry Smith PetscInt *nnz; 4258a1661176SMatthew Knepley PetscErrorCode ierr; 4259a1661176SMatthew Knepley 4260a1661176SMatthew Knepley PetscFunctionBegin; 426165e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4262779a8d59SSatish Balay 4263779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4264779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4265779a8d59SSatish Balay 4266779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4267854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 4268a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4269b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 427065e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4271a1661176SMatthew Knepley nnz[i] = nz; 4272a1661176SMatthew Knepley } 4273a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4274a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4275a1661176SMatthew Knepley 4276a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4277071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 4278a1661176SMatthew Knepley } 4279a1661176SMatthew Knepley 4280a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4281a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4282a1661176SMatthew Knepley 42837827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4284a1661176SMatthew Knepley PetscFunctionReturn(0); 4285a1661176SMatthew Knepley } 4286a1661176SMatthew Knepley 4287c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4288af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4289170fe5c8SBarry Smith 4290170fe5c8SBarry Smith /* 4291170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4292170fe5c8SBarry Smith 4293170fe5c8SBarry Smith n p p 42942da392ccSBarry Smith [ ] [ ] [ ] 42952da392ccSBarry Smith m [ A ] * n [ B ] = m [ C ] 42962da392ccSBarry Smith [ ] [ ] [ ] 4297170fe5c8SBarry Smith 4298170fe5c8SBarry Smith */ 4299170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4300170fe5c8SBarry Smith { 4301170fe5c8SBarry Smith PetscErrorCode ierr; 4302170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4303170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4304170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 430586214ceeSStefano Zampini PetscInt i,j,n,m,q,p; 4306170fe5c8SBarry Smith const PetscInt *ii,*idx; 4307170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4308170fe5c8SBarry Smith PetscScalar *c,*c_q; 430986214ceeSStefano Zampini PetscInt clda = sub_c->lda; 431086214ceeSStefano Zampini PetscInt alda = sub_a->lda; 4311170fe5c8SBarry Smith 4312170fe5c8SBarry Smith PetscFunctionBegin; 4313d0f46423SBarry Smith m = A->rmap->n; 4314d0f46423SBarry Smith n = A->cmap->n; 4315d0f46423SBarry Smith p = B->cmap->n; 4316170fe5c8SBarry Smith a = sub_a->v; 4317170fe5c8SBarry Smith b = sub_b->a; 4318170fe5c8SBarry Smith c = sub_c->v; 431986214ceeSStefano Zampini if (clda == m) { 4320580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 432186214ceeSStefano Zampini } else { 432286214ceeSStefano Zampini for (j=0;j<p;j++) 432386214ceeSStefano Zampini for (i=0;i<m;i++) 432486214ceeSStefano Zampini c[j*clda + i] = 0.0; 432586214ceeSStefano Zampini } 4326170fe5c8SBarry Smith ii = sub_b->i; 4327170fe5c8SBarry Smith idx = sub_b->j; 4328170fe5c8SBarry Smith for (i=0; i<n; i++) { 4329170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4330170fe5c8SBarry Smith while (q-->0) { 433186214ceeSStefano Zampini c_q = c + clda*(*idx); 433286214ceeSStefano Zampini a_q = a + alda*i; 4333854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4334170fe5c8SBarry Smith idx++; 4335170fe5c8SBarry Smith b++; 4336170fe5c8SBarry Smith } 4337170fe5c8SBarry Smith } 4338170fe5c8SBarry Smith PetscFunctionReturn(0); 4339170fe5c8SBarry Smith } 4340170fe5c8SBarry Smith 43414222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C) 4342170fe5c8SBarry Smith { 4343170fe5c8SBarry Smith PetscErrorCode ierr; 4344d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 434586214ceeSStefano Zampini PetscBool cisdense; 4346170fe5c8SBarry Smith 4347170fe5c8SBarry Smith PetscFunctionBegin; 434860e0710aSBarry 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); 43494222ddf1SHong Zhang ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr); 43504222ddf1SHong Zhang ierr = MatSetBlockSizesFromMats(C,A,B);CHKERRQ(ierr); 435186214ceeSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr); 435286214ceeSStefano Zampini if (!cisdense) { 435386214ceeSStefano Zampini ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); 435486214ceeSStefano Zampini } 435586214ceeSStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 4356d73949e8SHong Zhang 43574222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 4358170fe5c8SBarry Smith PetscFunctionReturn(0); 4359170fe5c8SBarry Smith } 4360170fe5c8SBarry Smith 4361170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 43620bad9183SKris Buschelman /*MC 4363fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 43640bad9183SKris Buschelman based on compressed sparse row format. 43650bad9183SKris Buschelman 43660bad9183SKris Buschelman Options Database Keys: 43670bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 43680bad9183SKris Buschelman 43690bad9183SKris Buschelman Level: beginner 43700bad9183SKris Buschelman 43710cd7f59aSBarry Smith Notes: 43720cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 43730cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 43740cd7f59aSBarry Smith in the matrix 43750cd7f59aSBarry Smith 43760cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 43770cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 43780cd7f59aSBarry Smith 43790cd7f59aSBarry Smith Developer Notes: 43800cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 43810cd7f59aSBarry Smith 4382f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 43830bad9183SKris Buschelman M*/ 43840bad9183SKris Buschelman 4385ccd284c7SBarry Smith /*MC 4386ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4387ccd284c7SBarry Smith 4388ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4389ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 43900cd7f59aSBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation() is supported 4391ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4392ccd284c7SBarry Smith the above preallocation routines for simplicity. 4393ccd284c7SBarry Smith 4394ccd284c7SBarry Smith Options Database Keys: 4395ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4396ccd284c7SBarry Smith 439795452b02SPatrick Sanan Developer Notes: 4398ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4399ccd284c7SBarry Smith enough exist. 4400ccd284c7SBarry Smith 4401ccd284c7SBarry Smith Level: beginner 4402ccd284c7SBarry Smith 4403ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4404ccd284c7SBarry Smith M*/ 4405ccd284c7SBarry Smith 4406ccd284c7SBarry Smith /*MC 4407ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4408ccd284c7SBarry Smith 4409ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4410ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4411ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4412ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4413ccd284c7SBarry Smith the above preallocation routines for simplicity. 4414ccd284c7SBarry Smith 4415ccd284c7SBarry Smith Options Database Keys: 4416ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4417ccd284c7SBarry Smith 4418ccd284c7SBarry Smith Level: beginner 4419ccd284c7SBarry Smith 4420ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4421ccd284c7SBarry Smith M*/ 4422ccd284c7SBarry Smith 44237906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 44247906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 44257906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 44267906f579SHong Zhang #endif 4427d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4428d24d4204SJose E. Roman PETSC_INTERN PetscErrorCode MatConvert_AIJ_ScaLAPACK(Mat,MatType,MatReuse,Mat*); 4429d24d4204SJose E. Roman #endif 44307906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 44317906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 44327906f579SHong Zhang #endif 44337906f579SHong Zhang 4434d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4435c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 44364222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat); 44377906f579SHong Zhang 44388c778c55SBarry Smith /*@C 44398f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 44408c778c55SBarry Smith 44418c778c55SBarry Smith Not Collective 44428c778c55SBarry Smith 44438c778c55SBarry Smith Input Parameter: 4444579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 44458c778c55SBarry Smith 44468c778c55SBarry Smith Output Parameter: 44478c778c55SBarry Smith . array - pointer to the data 44488c778c55SBarry Smith 44498c778c55SBarry Smith Level: intermediate 44508c778c55SBarry Smith 4451774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 44528c778c55SBarry Smith @*/ 44538c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 44548c778c55SBarry Smith { 44558c778c55SBarry Smith PetscErrorCode ierr; 44568c778c55SBarry Smith 44578c778c55SBarry Smith PetscFunctionBegin; 44588c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 44592e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 44602e5835c6SStefano Zampini if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 44612e5835c6SStefano Zampini #endif 44628c778c55SBarry Smith PetscFunctionReturn(0); 44638c778c55SBarry Smith } 44648c778c55SBarry Smith 446521e72a00SBarry Smith /*@C 44668f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 44678f1ea47aSStefano Zampini 44688f1ea47aSStefano Zampini Not Collective 44698f1ea47aSStefano Zampini 44708f1ea47aSStefano Zampini Input Parameter: 44718f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44728f1ea47aSStefano Zampini 44738f1ea47aSStefano Zampini Output Parameter: 44748f1ea47aSStefano Zampini . array - pointer to the data 44758f1ea47aSStefano Zampini 44768f1ea47aSStefano Zampini Level: intermediate 44778f1ea47aSStefano Zampini 44788f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 44798f1ea47aSStefano Zampini @*/ 44808f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 44818f1ea47aSStefano Zampini { 44828c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4483c70f7ee4SJunchao Zhang PetscOffloadMask oval; 44848f1ea47aSStefano Zampini #endif 44858f1ea47aSStefano Zampini PetscErrorCode ierr; 44868f1ea47aSStefano Zampini 44878f1ea47aSStefano Zampini PetscFunctionBegin; 44888c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4489c70f7ee4SJunchao Zhang oval = A->offloadmask; 44908f1ea47aSStefano Zampini #endif 44918f1ea47aSStefano Zampini ierr = MatSeqAIJGetArray(A,(PetscScalar**)array);CHKERRQ(ierr); 44928c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4493c70f7ee4SJunchao Zhang if (oval == PETSC_OFFLOAD_GPU || oval == PETSC_OFFLOAD_BOTH) A->offloadmask = PETSC_OFFLOAD_BOTH; 44948f1ea47aSStefano Zampini #endif 44958f1ea47aSStefano Zampini PetscFunctionReturn(0); 44968f1ea47aSStefano Zampini } 44978f1ea47aSStefano Zampini 44988f1ea47aSStefano Zampini /*@C 44998f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 45008f1ea47aSStefano Zampini 45018f1ea47aSStefano Zampini Not Collective 45028f1ea47aSStefano Zampini 45038f1ea47aSStefano Zampini Input Parameter: 45048f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 45058f1ea47aSStefano Zampini 45068f1ea47aSStefano Zampini Output Parameter: 45078f1ea47aSStefano Zampini . array - pointer to the data 45088f1ea47aSStefano Zampini 45098f1ea47aSStefano Zampini Level: intermediate 45108f1ea47aSStefano Zampini 45118f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 45128f1ea47aSStefano Zampini @*/ 45138f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 45148f1ea47aSStefano Zampini { 45158c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4516c70f7ee4SJunchao Zhang PetscOffloadMask oval; 45178f1ea47aSStefano Zampini #endif 45188f1ea47aSStefano Zampini PetscErrorCode ierr; 45198f1ea47aSStefano Zampini 45208f1ea47aSStefano Zampini PetscFunctionBegin; 45218c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4522c70f7ee4SJunchao Zhang oval = A->offloadmask; 45238f1ea47aSStefano Zampini #endif 45248f1ea47aSStefano Zampini ierr = MatSeqAIJRestoreArray(A,(PetscScalar**)array);CHKERRQ(ierr); 45258c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4526c70f7ee4SJunchao Zhang A->offloadmask = oval; 45278f1ea47aSStefano Zampini #endif 45288f1ea47aSStefano Zampini PetscFunctionReturn(0); 45298f1ea47aSStefano Zampini } 45308f1ea47aSStefano Zampini 45318f1ea47aSStefano Zampini /*@C 453221e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 453321e72a00SBarry Smith 453421e72a00SBarry Smith Not Collective 453521e72a00SBarry Smith 453621e72a00SBarry Smith Input Parameter: 4537579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 453821e72a00SBarry Smith 453921e72a00SBarry Smith Output Parameter: 454021e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 454121e72a00SBarry Smith 454221e72a00SBarry Smith Level: intermediate 454321e72a00SBarry Smith 454421e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 454521e72a00SBarry Smith @*/ 454621e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 454721e72a00SBarry Smith { 454821e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 454921e72a00SBarry Smith 455021e72a00SBarry Smith PetscFunctionBegin; 455121e72a00SBarry Smith *nz = aij->rmax; 455221e72a00SBarry Smith PetscFunctionReturn(0); 455321e72a00SBarry Smith } 455421e72a00SBarry Smith 45558c778c55SBarry Smith /*@C 4556579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 45578c778c55SBarry Smith 45588c778c55SBarry Smith Not Collective 45598c778c55SBarry Smith 45608c778c55SBarry Smith Input Parameters: 4561a2b725a8SWilliam Gropp + mat - a MATSEQAIJ matrix 4562a2b725a8SWilliam Gropp - array - pointer to the data 45638c778c55SBarry Smith 45648c778c55SBarry Smith Level: intermediate 45658c778c55SBarry Smith 4566774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 45678c778c55SBarry Smith @*/ 45688c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 45698c778c55SBarry Smith { 45708c778c55SBarry Smith PetscErrorCode ierr; 45718c778c55SBarry Smith 45728c778c55SBarry Smith PetscFunctionBegin; 45738c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 45748c778c55SBarry Smith PetscFunctionReturn(0); 45758c778c55SBarry Smith } 45768c778c55SBarry Smith 457734b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 45780ce8acdeSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat); 457902fe1965SBarry Smith #endif 45803d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 45813d0639e7SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJKokkos(Mat); 45823d0639e7SStefano Zampini #endif 458302fe1965SBarry Smith 45848cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4585273d9f13SBarry Smith { 4586273d9f13SBarry Smith Mat_SeqAIJ *b; 4587dfbe8321SBarry Smith PetscErrorCode ierr; 458838baddfdSBarry Smith PetscMPIInt size; 4589273d9f13SBarry Smith 4590273d9f13SBarry Smith PetscFunctionBegin; 4591ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr); 4592e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4593273d9f13SBarry Smith 4594b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 45952205254eSKarl Rupp 4596b0a32e0cSBarry Smith B->data = (void*)b; 45972205254eSKarl Rupp 4598549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4599071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 46002205254eSKarl Rupp 4601f4259b30SLisandro Dalcin b->row = NULL; 4602f4259b30SLisandro Dalcin b->col = NULL; 4603f4259b30SLisandro Dalcin b->icol = NULL; 4604b810aeb4SBarry Smith b->reallocs = 0; 460536db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4606f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4607416022c9SBarry Smith b->nonew = 0; 4608f4259b30SLisandro Dalcin b->diag = NULL; 4609f4259b30SLisandro Dalcin b->solve_work = NULL; 4610f4259b30SLisandro Dalcin B->spptr = NULL; 4611f4259b30SLisandro Dalcin b->saved_values = NULL; 4612f4259b30SLisandro Dalcin b->idiag = NULL; 4613f4259b30SLisandro Dalcin b->mdiag = NULL; 4614f4259b30SLisandro Dalcin b->ssor_work = NULL; 461571f1c65dSBarry Smith b->omega = 1.0; 461671f1c65dSBarry Smith b->fshift = 0.0; 461771f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4618bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4619a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 462017ab2063SBarry Smith 462135d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4622bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4623bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 46248c778c55SBarry Smith 4625b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4626bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4627bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4628b3866ffcSBarry Smith #endif 462917f1a0eaSHong Zhang 4630bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4631bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4632bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4633bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4634bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4635bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 46364dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 46379779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 46384a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4639191b95cbSRichard Tran Mills #endif 464034b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 464102fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 46424222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 4643fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 464402fe1965SBarry Smith #endif 46453d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 46463d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijkokkos_C",MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr); 46473d0639e7SStefano Zampini #endif 4648bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4649af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4650af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4651af8000cdSHong Zhang #endif 4652d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4653d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_scalapack_C",MatConvert_AIJ_ScaLAPACK);CHKERRQ(ierr); 4654d24d4204SJose E. Roman #endif 465563c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 465663c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 46574222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ);CHKERRQ(ierr); 465863c07aadSStefano Zampini #endif 4659b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4660d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4661c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4662bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4663bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4664bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4665846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4666bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4667bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 46684222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ);CHKERRQ(ierr); 46694222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ);CHKERRQ(ierr); 46704222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 46714108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 467217667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 46734099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 46743a40ed3dSBarry Smith PetscFunctionReturn(0); 467517ab2063SBarry Smith } 467617ab2063SBarry Smith 4677b24902e0SBarry Smith /* 4678b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4679b24902e0SBarry Smith */ 4680ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 468117ab2063SBarry Smith { 46822a350339SBarry Smith Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data,*a = (Mat_SeqAIJ*)A->data; 46836849ba73SBarry Smith PetscErrorCode ierr; 4684071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 468517ab2063SBarry Smith 46863a40ed3dSBarry Smith PetscFunctionBegin; 4687ca133879SJose E. Roman if (!A->assembled && cpvalues!=MAT_DO_NOT_COPY_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot duplicate unassembled matrix"); 4688273d9f13SBarry Smith 4689d5f3da31SBarry Smith C->factortype = A->factortype; 4690f4259b30SLisandro Dalcin c->row = NULL; 4691f4259b30SLisandro Dalcin c->col = NULL; 4692f4259b30SLisandro Dalcin c->icol = NULL; 46936ad4291fSHong Zhang c->reallocs = 0; 469417ab2063SBarry Smith 46956ad4291fSHong Zhang C->assembled = PETSC_TRUE; 469617ab2063SBarry Smith 4697aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4698aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4699eec197d1SBarry Smith 4700071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4701071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4702071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4703071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 47043bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 470517ab2063SBarry Smith 470617ab2063SBarry Smith /* allocate the matrix space */ 4707f77e22a1SHong Zhang if (mallocmatspace) { 4708dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 47093bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 47102205254eSKarl Rupp 4711f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 47122205254eSKarl Rupp 4713580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 471417ab2063SBarry Smith if (m > 0) { 4715580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4716be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 47172e5835c6SStefano Zampini const PetscScalar *aa; 47182e5835c6SStefano Zampini 47192e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 47202e5835c6SStefano Zampini ierr = PetscArraycpy(c->a,aa,a->i[m]);CHKERRQ(ierr); 47212e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 4722be6bf707SBarry Smith } else { 4723580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 472417ab2063SBarry Smith } 472508480c60SBarry Smith } 4726f77e22a1SHong Zhang } 472717ab2063SBarry Smith 47286ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4729416022c9SBarry Smith c->roworiented = a->roworiented; 4730416022c9SBarry Smith c->nonew = a->nonew; 4731416022c9SBarry Smith if (a->diag) { 4732854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4733071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 47343bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4735071fcb05SBarry Smith } else c->diag = NULL; 47362205254eSKarl Rupp 4737f4259b30SLisandro Dalcin c->solve_work = NULL; 4738f4259b30SLisandro Dalcin c->saved_values = NULL; 4739f4259b30SLisandro Dalcin c->idiag = NULL; 4740f4259b30SLisandro Dalcin c->ssor_work = NULL; 4741a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4742e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4743e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 47446ad4291fSHong Zhang 4745893ad86cSHong Zhang c->rmax = a->rmax; 4746416022c9SBarry Smith c->nz = a->nz; 47478ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4748273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4749754ec7b1SSatish Balay 47506ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 47516ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4752cd6b891eSBarry Smith if (a->compressedrow.use) { 47536ad4291fSHong Zhang i = a->compressedrow.nrows; 4754dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4755580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4756580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 475727ea64f8SHong Zhang } else { 475827ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 47590298fd71SBarry Smith c->compressedrow.i = NULL; 47600298fd71SBarry Smith c->compressedrow.rindex = NULL; 47616ad4291fSHong Zhang } 4762ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4763e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 47644846f1f5SKris Buschelman 47652205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4766140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 47673a40ed3dSBarry Smith PetscFunctionReturn(0); 476817ab2063SBarry Smith } 476917ab2063SBarry Smith 4770b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4771b24902e0SBarry Smith { 4772b24902e0SBarry Smith PetscErrorCode ierr; 4773b24902e0SBarry Smith 4774b24902e0SBarry Smith PetscFunctionBegin; 4775ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 47764b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4777cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 477833d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4779cfd3f464SBarry Smith } 4780a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4781f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4782b24902e0SBarry Smith PetscFunctionReturn(0); 4783b24902e0SBarry Smith } 4784b24902e0SBarry Smith 4785112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4786fbdbba38SShri Abhyankar { 478752f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 478852f91c60SVaclav Hapla PetscErrorCode ierr; 478952f91c60SVaclav Hapla 479052f91c60SVaclav Hapla PetscFunctionBegin; 479152f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 479252f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4793c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4794c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 479552f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 479652f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 479752f91c60SVaclav Hapla if (isbinary) { 479852f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 479952f91c60SVaclav Hapla } else if (ishdf5) { 480052f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 480152f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 480252f91c60SVaclav Hapla #else 480352f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 480452f91c60SVaclav Hapla #endif 480552f91c60SVaclav Hapla } else { 480652f91c60SVaclav 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); 480752f91c60SVaclav Hapla } 480852f91c60SVaclav Hapla PetscFunctionReturn(0); 480952f91c60SVaclav Hapla } 481052f91c60SVaclav Hapla 48113ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer) 481252f91c60SVaclav Hapla { 48133ea6fe3dSLisandro Dalcin Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 4814fbdbba38SShri Abhyankar PetscErrorCode ierr; 48153ea6fe3dSLisandro Dalcin PetscInt header[4],*rowlens,M,N,nz,sum,rows,cols,i; 4816fbdbba38SShri Abhyankar 4817fbdbba38SShri Abhyankar PetscFunctionBegin; 48183ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4819bbead8a2SBarry Smith 48203ea6fe3dSLisandro Dalcin /* read in matrix header */ 48213ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 48223ea6fe3dSLisandro Dalcin if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 4823fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 48243ea6fe3dSLisandro Dalcin if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M); 48253ea6fe3dSLisandro Dalcin if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N); 4826bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 4827fbdbba38SShri Abhyankar 48283ea6fe3dSLisandro Dalcin /* set block sizes from the viewer's .info file */ 48293ea6fe3dSLisandro Dalcin ierr = MatLoad_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 48303ea6fe3dSLisandro Dalcin /* set local and global sizes if not set already */ 48313ea6fe3dSLisandro Dalcin if (mat->rmap->n < 0) mat->rmap->n = M; 48323ea6fe3dSLisandro Dalcin if (mat->cmap->n < 0) mat->cmap->n = N; 48333ea6fe3dSLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 48343ea6fe3dSLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 48353ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 48363ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 48373ea6fe3dSLisandro Dalcin 48383ea6fe3dSLisandro Dalcin /* check if the matrix sizes are correct */ 48393ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 48403ea6fe3dSLisandro 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); 48413ea6fe3dSLisandro Dalcin 4842fbdbba38SShri Abhyankar /* read in row lengths */ 48433ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(M,&rowlens);CHKERRQ(ierr); 48443ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT);CHKERRQ(ierr); 48453ea6fe3dSLisandro Dalcin /* check if sum(rowlens) is same as nz */ 48463ea6fe3dSLisandro Dalcin sum = 0; for (i=0; i<M; i++) sum += rowlens[i]; 48473ea6fe3dSLisandro 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); 48483ea6fe3dSLisandro Dalcin /* preallocate and check sizes */ 48493ea6fe3dSLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens);CHKERRQ(ierr); 48503ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 485160e0710aSBarry 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); 48523ea6fe3dSLisandro Dalcin /* store row lengths */ 48533ea6fe3dSLisandro Dalcin ierr = PetscArraycpy(a->ilen,rowlens,M);CHKERRQ(ierr); 48543ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 4855fbdbba38SShri Abhyankar 48563ea6fe3dSLisandro Dalcin /* fill in "i" row pointers */ 48573ea6fe3dSLisandro Dalcin a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i]; 48583ea6fe3dSLisandro Dalcin /* read in "j" column indices */ 48593ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 48603ea6fe3dSLisandro Dalcin /* read in "a" nonzero values */ 48613ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4862fbdbba38SShri Abhyankar 48633ea6fe3dSLisandro Dalcin ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 48643ea6fe3dSLisandro Dalcin ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4865fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4866fbdbba38SShri Abhyankar } 4867fbdbba38SShri Abhyankar 4868ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 48697264ac53SSatish Balay { 48707264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4871dfbe8321SBarry Smith PetscErrorCode ierr; 4872eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4873eeffb40dSHong Zhang PetscInt k; 4874eeffb40dSHong Zhang #endif 48757264ac53SSatish Balay 48763a40ed3dSBarry Smith PetscFunctionBegin; 4877bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4878d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4879ca44d042SBarry Smith *flg = PETSC_FALSE; 4880ca44d042SBarry Smith PetscFunctionReturn(0); 4881bcd2baecSBarry Smith } 48827264ac53SSatish Balay 48837264ac53SSatish Balay /* if the a->i are the same */ 4884580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4885abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 48867264ac53SSatish Balay 48877264ac53SSatish Balay /* if a->j are the same */ 4888580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 4889abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4890bcd2baecSBarry Smith 4891bcd2baecSBarry Smith /* if a->a are the same */ 4892eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4893eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4894eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4895eeffb40dSHong Zhang *flg = PETSC_FALSE; 48963a40ed3dSBarry Smith PetscFunctionReturn(0); 4897eeffb40dSHong Zhang } 4898eeffb40dSHong Zhang } 4899eeffb40dSHong Zhang #else 4900580bdb30SBarry Smith ierr = PetscArraycmp(a->a,b->a,a->nz,flg);CHKERRQ(ierr); 4901eeffb40dSHong Zhang #endif 4902eeffb40dSHong Zhang PetscFunctionReturn(0); 49037264ac53SSatish Balay } 490436db0b34SBarry Smith 490505869f15SSatish Balay /*@ 490636db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 490736db0b34SBarry Smith provided by the user. 490836db0b34SBarry Smith 4909d083f849SBarry Smith Collective 491036db0b34SBarry Smith 491136db0b34SBarry Smith Input Parameters: 491236db0b34SBarry Smith + comm - must be an MPI communicator of size 1 491336db0b34SBarry Smith . m - number of rows 491436db0b34SBarry Smith . n - number of columns 4915483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 491636db0b34SBarry Smith . j - column indices 491736db0b34SBarry Smith - a - matrix values 491836db0b34SBarry Smith 491936db0b34SBarry Smith Output Parameter: 492036db0b34SBarry Smith . mat - the matrix 492136db0b34SBarry Smith 492236db0b34SBarry Smith Level: intermediate 492336db0b34SBarry Smith 492436db0b34SBarry Smith Notes: 49250551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4926292fb18eSBarry Smith once the matrix is destroyed and not before 492736db0b34SBarry Smith 492836db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 492936db0b34SBarry Smith 4930bfeeae90SHong Zhang The i and j indices are 0 based 493136db0b34SBarry Smith 4932a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4933a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 49348eef79e4SBarry Smith as shown 4935a4552177SSatish Balay 49368eef79e4SBarry Smith $ 1 0 0 49378eef79e4SBarry Smith $ 2 0 3 49388eef79e4SBarry Smith $ 4 5 6 49398eef79e4SBarry Smith $ 49408eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 49418eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 49428eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4943a4552177SSatish Balay 49449985e31cSBarry Smith 494569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 494636db0b34SBarry Smith 494736db0b34SBarry Smith @*/ 4948c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 494936db0b34SBarry Smith { 4950dfbe8321SBarry Smith PetscErrorCode ierr; 4951cbcfb4deSHong Zhang PetscInt ii; 495236db0b34SBarry Smith Mat_SeqAIJ *aij; 4953cbcfb4deSHong Zhang PetscInt jj; 495436db0b34SBarry Smith 495536db0b34SBarry Smith PetscFunctionBegin; 495641096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4957f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4958f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4959a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4960ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4961f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,NULL);CHKERRQ(ierr); 4962ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4963071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 4964071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 4965ab93d7beSBarry Smith 496636db0b34SBarry Smith aij->i = i; 496736db0b34SBarry Smith aij->j = j; 496836db0b34SBarry Smith aij->a = a; 496936db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 497036db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4971e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4972e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 497336db0b34SBarry Smith 497436db0b34SBarry Smith for (ii=0; ii<m; ii++) { 497536db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 497676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 497760e0710aSBarry 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]); 49789985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4979a061629eSStefano 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); 4980a061629eSStefano 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); 49819985e31cSBarry Smith } 498236db0b34SBarry Smith } 498376bd3646SJed Brown } 498476bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 498536db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 498660e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 498760e0710aSBarry 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]); 498836db0b34SBarry Smith } 498976bd3646SJed Brown } 499036db0b34SBarry Smith 4991b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4992b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 499336db0b34SBarry Smith PetscFunctionReturn(0); 499436db0b34SBarry Smith } 499580ef6e79SMatthew G Knepley /*@C 4996d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 49978a0b0e6bSVictor Minden provided by the user. 49988a0b0e6bSVictor Minden 4999d083f849SBarry Smith Collective 50008a0b0e6bSVictor Minden 50018a0b0e6bSVictor Minden Input Parameters: 50028a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 50038a0b0e6bSVictor Minden . m - number of rows 50048a0b0e6bSVictor Minden . n - number of columns 50058a0b0e6bSVictor Minden . i - row indices 50068a0b0e6bSVictor Minden . j - column indices 50071230e6d1SVictor Minden . a - matrix values 50081230e6d1SVictor Minden . nz - number of nonzeros 50091230e6d1SVictor Minden - idx - 0 or 1 based 50108a0b0e6bSVictor Minden 50118a0b0e6bSVictor Minden Output Parameter: 50128a0b0e6bSVictor Minden . mat - the matrix 50138a0b0e6bSVictor Minden 50148a0b0e6bSVictor Minden Level: intermediate 50158a0b0e6bSVictor Minden 50168a0b0e6bSVictor Minden Notes: 50178a0b0e6bSVictor Minden The i and j indices are 0 based 50188a0b0e6bSVictor Minden 50198a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 50208a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 50218a0b0e6bSVictor Minden as shown: 50228a0b0e6bSVictor Minden 50238a0b0e6bSVictor Minden 1 0 0 50248a0b0e6bSVictor Minden 2 0 3 50258a0b0e6bSVictor Minden 4 5 6 50268a0b0e6bSVictor Minden 50278a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 50288a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 50298a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 50308a0b0e6bSVictor Minden 50318a0b0e6bSVictor Minden 503269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 50338a0b0e6bSVictor Minden 50348a0b0e6bSVictor Minden @*/ 5035c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 50368a0b0e6bSVictor Minden { 50378a0b0e6bSVictor Minden PetscErrorCode ierr; 5038d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 50398a0b0e6bSVictor Minden 50408a0b0e6bSVictor Minden 50418a0b0e6bSVictor Minden PetscFunctionBegin; 50421795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 50431230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 5044c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 50451230e6d1SVictor Minden } 50468a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 50478a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 50488a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 50491230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 50501230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 50511230e6d1SVictor Minden if (idx) { 50521230e6d1SVictor Minden row = i[ii] - 1; 50531230e6d1SVictor Minden col = j[ii] - 1; 50541230e6d1SVictor Minden } else { 50551230e6d1SVictor Minden row = i[ii]; 50561230e6d1SVictor Minden col = j[ii]; 50578a0b0e6bSVictor Minden } 50581230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 50598a0b0e6bSVictor Minden } 50608a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 50618a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5062d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 50638a0b0e6bSVictor Minden PetscFunctionReturn(0); 50648a0b0e6bSVictor Minden } 506536db0b34SBarry Smith 5066acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 5067acf2f550SJed Brown { 5068acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 5069acf2f550SJed Brown PetscErrorCode ierr; 5070acf2f550SJed Brown 5071acf2f550SJed Brown PetscFunctionBegin; 5072acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 5073acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 50742205254eSKarl Rupp 5075acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 5076acf2f550SJed Brown PetscFunctionReturn(0); 5077acf2f550SJed Brown } 5078acf2f550SJed Brown 50799c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 50809c8f2541SHong Zhang { 50819c8f2541SHong Zhang PetscErrorCode ierr; 50828761c3d6SHong Zhang PetscMPIInt size; 50839c8f2541SHong Zhang 50849c8f2541SHong Zhang PetscFunctionBegin; 5085ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 50867bbdc51dSHong Zhang if (size == 1) { 50877bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 50887bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 50897bbdc51dSHong Zhang } else { 50908761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 50917bbdc51dSHong Zhang } 50928761c3d6SHong Zhang } else { 50939c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 50948761c3d6SHong Zhang } 50959c8f2541SHong Zhang PetscFunctionReturn(0); 50969c8f2541SHong Zhang } 50979c8f2541SHong Zhang 509881824310SBarry Smith /* 509953dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 510053dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 510153dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 510253dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 510353dd7562SDmitry Karpeev */ 510453dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 510553dd7562SDmitry Karpeev { 510653dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 510753dd7562SDmitry Karpeev PetscErrorCode ierr; 510853dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 510953dd7562SDmitry Karpeev PetscBool seqaij; 511053dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 511153dd7562SDmitry Karpeev PetscScalar v; 511253dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 511353dd7562SDmitry Karpeev 511453dd7562SDmitry Karpeev PetscFunctionBegin; 511553dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 511653dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 51174099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 511853dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 511953dd7562SDmitry Karpeev if (rowemb) { 512053dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 512153dd7562SDmitry 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); 512253dd7562SDmitry Karpeev } else { 51236c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 512453dd7562SDmitry Karpeev } 512553dd7562SDmitry Karpeev if (colemb) { 512653dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 512753dd7562SDmitry 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); 512853dd7562SDmitry Karpeev } else { 512953dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 513053dd7562SDmitry Karpeev } 513153dd7562SDmitry Karpeev 513253dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 513353dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 513453dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 513553dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 513653dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 513753dd7562SDmitry Karpeev } 513853dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 513953dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 514053dd7562SDmitry Karpeev } 514153dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 514253dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 514353dd7562SDmitry Karpeev } 514453dd7562SDmitry Karpeev count = 0; 514553dd7562SDmitry Karpeev rowindices = NULL; 514653dd7562SDmitry Karpeev colindices = NULL; 514753dd7562SDmitry Karpeev if (rowemb) { 514853dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 514953dd7562SDmitry Karpeev } 515053dd7562SDmitry Karpeev if (colemb) { 515153dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 515253dd7562SDmitry Karpeev } 515353dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 515453dd7562SDmitry Karpeev PetscInt row; 515553dd7562SDmitry Karpeev row = i; 515653dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 515753dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 515853dd7562SDmitry Karpeev PetscInt col; 515953dd7562SDmitry Karpeev col = Baij->j[count]; 516053dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 516153dd7562SDmitry Karpeev v = Baij->a[count]; 516253dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 516353dd7562SDmitry Karpeev ++count; 516453dd7562SDmitry Karpeev } 516553dd7562SDmitry Karpeev } 516653dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 516753dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 516853dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 516953dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 517053dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 517153dd7562SDmitry Karpeev PetscFunctionReturn(0); 517253dd7562SDmitry Karpeev } 517353dd7562SDmitry Karpeev 51744099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 51754099cc6bSBarry Smith 51764099cc6bSBarry Smith /*@C 51774099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 51784099cc6bSBarry Smith 51794099cc6bSBarry Smith Collective on Mat 51804099cc6bSBarry Smith 51814099cc6bSBarry Smith Input Parameters: 51824099cc6bSBarry Smith + mat - the matrix object 51834099cc6bSBarry Smith - matype - matrix type 51844099cc6bSBarry Smith 51854099cc6bSBarry Smith Options Database Key: 51864099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 51874099cc6bSBarry Smith 51884099cc6bSBarry Smith 51894099cc6bSBarry Smith Level: intermediate 51904099cc6bSBarry Smith 51914099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 51924099cc6bSBarry Smith @*/ 51934099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 51944099cc6bSBarry Smith { 5195fd9d3c67SJed Brown PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*); 51964099cc6bSBarry Smith PetscBool sametype; 51974099cc6bSBarry Smith 51984099cc6bSBarry Smith PetscFunctionBegin; 51994099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 52004099cc6bSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 52014099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 52024099cc6bSBarry Smith 52034099cc6bSBarry Smith ierr = PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr); 52044099cc6bSBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 52054099cc6bSBarry Smith ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 52064099cc6bSBarry Smith PetscFunctionReturn(0); 52074099cc6bSBarry Smith } 52084099cc6bSBarry Smith 52094099cc6bSBarry Smith 52104099cc6bSBarry Smith /*@C 52114099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 52124099cc6bSBarry Smith 52134099cc6bSBarry Smith Not Collective 52144099cc6bSBarry Smith 52154099cc6bSBarry Smith Input Parameters: 52164099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 52174099cc6bSBarry Smith - function - routine to convert to subtype 52184099cc6bSBarry Smith 52194099cc6bSBarry Smith Notes: 52204099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 52214099cc6bSBarry Smith 52224099cc6bSBarry Smith 52234099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 52244099cc6bSBarry Smith $ -mat_seqaij_type my_mat 52254099cc6bSBarry Smith 52264099cc6bSBarry Smith Level: advanced 52274099cc6bSBarry Smith 52284099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 52294099cc6bSBarry Smith 52304099cc6bSBarry Smith 52314099cc6bSBarry Smith Level: advanced 52324099cc6bSBarry Smith @*/ 5233388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 52344099cc6bSBarry Smith { 52354099cc6bSBarry Smith PetscErrorCode ierr; 52364099cc6bSBarry Smith 52374099cc6bSBarry Smith PetscFunctionBegin; 52389cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 52394099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 52404099cc6bSBarry Smith PetscFunctionReturn(0); 52414099cc6bSBarry Smith } 52424099cc6bSBarry Smith 52434099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 52444099cc6bSBarry Smith 52454099cc6bSBarry Smith /*@C 52464099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 52474099cc6bSBarry Smith 52484099cc6bSBarry Smith Not Collective 52494099cc6bSBarry Smith 52504099cc6bSBarry Smith Level: advanced 52514099cc6bSBarry Smith 5252f719121fSJed Brown Developers Note: CUSPARSE does not yet support the MatConvert_SeqAIJ..() paradigm and thus cannot be registered here 52534099cc6bSBarry Smith 52544099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 52554099cc6bSBarry Smith @*/ 52564099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 52574099cc6bSBarry Smith { 52584099cc6bSBarry Smith PetscErrorCode ierr; 52594099cc6bSBarry Smith 52604099cc6bSBarry Smith PetscFunctionBegin; 52614099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 52624099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 52634099cc6bSBarry Smith 52644099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 52654099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 52664dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 52679779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 52686b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 5269485f9817SRichard Tran Mills #endif 52704099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 52714099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 52724099cc6bSBarry Smith #endif 52734099cc6bSBarry Smith PetscFunctionReturn(0); 52744099cc6bSBarry Smith } 527553dd7562SDmitry Karpeev 527653dd7562SDmitry Karpeev /* 527781824310SBarry Smith Special version for direct calls from Fortran 527881824310SBarry Smith */ 5279af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 528081824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 528181824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 528281824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 528381824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 528481824310SBarry Smith #endif 528581824310SBarry Smith 528681824310SBarry Smith /* Change these macros so can be used in void function */ 528781824310SBarry Smith #undef CHKERRQ 5288ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 528981824310SBarry Smith #undef SETERRQ2 5290e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 52914994cf47SJed Brown #undef SETERRQ3 52924994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 529381824310SBarry Smith 529419caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 529581824310SBarry Smith { 529681824310SBarry Smith Mat A = *AA; 529781824310SBarry Smith PetscInt m = *mm, n = *nn; 529881824310SBarry Smith InsertMode is = *isis; 529981824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 530081824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 530181824310SBarry Smith PetscInt *imax,*ai,*ailen; 530281824310SBarry Smith PetscErrorCode ierr; 530381824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 530454f21887SBarry Smith MatScalar *ap,value,*aa; 5305ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5306ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 530781824310SBarry Smith 530881824310SBarry Smith PetscFunctionBegin; 53094994cf47SJed Brown MatCheckPreallocated(A,1); 531081824310SBarry Smith imax = a->imax; 531181824310SBarry Smith ai = a->i; 531281824310SBarry Smith ailen = a->ilen; 531381824310SBarry Smith aj = a->j; 531481824310SBarry Smith aa = a->a; 531581824310SBarry Smith 531681824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 531781824310SBarry Smith row = im[k]; 531881824310SBarry Smith if (row < 0) continue; 5319cf9c20a2SJed Brown if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 532081824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 532181824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 532281824310SBarry Smith low = 0; 532381824310SBarry Smith high = nrow; 532481824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 532581824310SBarry Smith if (in[l] < 0) continue; 5326cf9c20a2SJed Brown if (PetscUnlikelyDebug(in[l] >= A->cmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 532781824310SBarry Smith col = in[l]; 53282205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 53292205254eSKarl Rupp else value = v[k + l*m]; 53302205254eSKarl Rupp 533181824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 533281824310SBarry Smith 53332205254eSKarl Rupp if (col <= lastcol) low = 0; 53342205254eSKarl Rupp else high = nrow; 533581824310SBarry Smith lastcol = col; 533681824310SBarry Smith while (high-low > 5) { 533781824310SBarry Smith t = (low+high)/2; 533881824310SBarry Smith if (rp[t] > col) high = t; 533981824310SBarry Smith else low = t; 534081824310SBarry Smith } 534181824310SBarry Smith for (i=low; i<high; i++) { 534281824310SBarry Smith if (rp[i] > col) break; 534381824310SBarry Smith if (rp[i] == col) { 534481824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 534581824310SBarry Smith else ap[i] = value; 534681824310SBarry Smith goto noinsert; 534781824310SBarry Smith } 534881824310SBarry Smith } 534981824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 535081824310SBarry Smith if (nonew == 1) goto noinsert; 5351ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5352fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 535381824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 535481824310SBarry Smith /* shift up all the later entries in this row */ 535581824310SBarry Smith for (ii=N; ii>=i; ii--) { 535681824310SBarry Smith rp[ii+1] = rp[ii]; 535781824310SBarry Smith ap[ii+1] = ap[ii]; 535881824310SBarry Smith } 535981824310SBarry Smith rp[i] = col; 536081824310SBarry Smith ap[i] = value; 5361e56f5c9eSBarry Smith A->nonzerostate++; 536281824310SBarry Smith noinsert:; 536381824310SBarry Smith low = i + 1; 536481824310SBarry Smith } 536581824310SBarry Smith ailen[row] = nrow; 536681824310SBarry Smith } 536781824310SBarry Smith PetscFunctionReturnVoid(); 536881824310SBarry Smith } 5369