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; 448d8cdefa3SHong Zhang MatScalar *ap=NULL,value=0.0,*aa = a->a; 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; 45617ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 457416022c9SBarry Smith row = im[k]; 4585ef9f2a5SBarry Smith if (row < 0) continue; 459cf9c20a2SJed 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); 460720833daSHong Zhang rp = aj + ai[row]; 461876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 46217ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 463416022c9SBarry Smith low = 0; 464c71e6ed7SBarry Smith high = nrow; 46517ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4665ef9f2a5SBarry Smith if (in[l] < 0) continue; 467cf9c20a2SJed 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); 468bfeeae90SHong Zhang col = in[l]; 469071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 470071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 47136db0b34SBarry Smith 4722205254eSKarl Rupp if (col <= lastcol) low = 0; 4732205254eSKarl Rupp else high = nrow; 474e2ee6c50SBarry Smith lastcol = col; 475416022c9SBarry Smith while (high-low > 5) { 476416022c9SBarry Smith t = (low+high)/2; 477416022c9SBarry Smith if (rp[t] > col) high = t; 478416022c9SBarry Smith else low = t; 47917ab2063SBarry Smith } 480416022c9SBarry Smith for (i=low; i<high; i++) { 48117ab2063SBarry Smith if (rp[i] > col) break; 48217ab2063SBarry Smith if (rp[i] == col) { 483876c6284SHong Zhang if (!A->structure_only) { 4840c0d7e18SFande Kong if (is == ADD_VALUES) { 4850c0d7e18SFande Kong ap[i] += value; 4860c0d7e18SFande Kong (void)PetscLogFlops(1.0); 4870c0d7e18SFande Kong } 48817ab2063SBarry Smith else ap[i] = value; 4898c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 490e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 491e2cf4d64SStefano Zampini #endif 492720833daSHong Zhang } 493e44c0bd4SBarry Smith low = i + 1; 49417ab2063SBarry Smith goto noinsert; 49517ab2063SBarry Smith } 49617ab2063SBarry Smith } 497dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 498c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 499e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 500720833daSHong Zhang if (A->structure_only) { 501876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 502720833daSHong Zhang } else { 503fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 504720833daSHong Zhang } 505c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 506416022c9SBarry Smith /* shift up all the later entries in this row */ 507580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 50817ab2063SBarry Smith rp[i] = col; 509580bdb30SBarry Smith if (!A->structure_only){ 510580bdb30SBarry Smith ierr = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr); 511580bdb30SBarry Smith ap[i] = value; 512580bdb30SBarry Smith } 513416022c9SBarry Smith low = i + 1; 514e56f5c9eSBarry Smith A->nonzerostate++; 5158c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 516e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 517e2cf4d64SStefano Zampini #endif 518e44c0bd4SBarry Smith noinsert:; 51917ab2063SBarry Smith } 52017ab2063SBarry Smith ailen[row] = nrow; 52117ab2063SBarry Smith } 5228c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 523c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && inserted) A->offloadmask = PETSC_OFFLOAD_CPU; 524e2cf4d64SStefano Zampini #endif 5253a40ed3dSBarry Smith PetscFunctionReturn(0); 52617ab2063SBarry Smith } 52717ab2063SBarry Smith 52819b08ed1SBarry Smith 52919b08ed1SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFullNoPreallocation(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 53019b08ed1SBarry Smith { 53119b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 53219b08ed1SBarry Smith PetscInt *rp,k,row; 53319b08ed1SBarry Smith PetscInt *ai = a->i; 53419b08ed1SBarry Smith PetscErrorCode ierr; 53519b08ed1SBarry Smith PetscInt *aj = a->j; 53619b08ed1SBarry Smith MatScalar *aa = a->a,*ap; 53719b08ed1SBarry Smith 53819b08ed1SBarry Smith PetscFunctionBegin; 53919b08ed1SBarry Smith if (A->was_assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call on assembled matrix."); 54019b08ed1SBarry 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); 54119b08ed1SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 54219b08ed1SBarry Smith row = im[k]; 54319b08ed1SBarry Smith rp = aj + ai[row]; 54419b08ed1SBarry Smith ap = aa + ai[row]; 54519b08ed1SBarry Smith 54619b08ed1SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 54719b08ed1SBarry Smith if (!A->structure_only) { 54819b08ed1SBarry Smith if (v) { 54919b08ed1SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 55019b08ed1SBarry Smith v += n; 55119b08ed1SBarry Smith } else { 55219b08ed1SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 55319b08ed1SBarry Smith } 55419b08ed1SBarry Smith } 55519b08ed1SBarry Smith a->ilen[row] = n; 55619b08ed1SBarry Smith a->imax[row] = n; 55719b08ed1SBarry Smith a->i[row+1] = a->i[row]+n; 55819b08ed1SBarry Smith a->nz += n; 55919b08ed1SBarry Smith } 5608c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 56119b08ed1SBarry Smith if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 56219b08ed1SBarry Smith #endif 56319b08ed1SBarry Smith PetscFunctionReturn(0); 56419b08ed1SBarry Smith } 56519b08ed1SBarry Smith 56619b08ed1SBarry Smith /*@ 56719b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation - Sets an upper bound on the total number of expected nonzeros in the matrix. 56819b08ed1SBarry Smith 56919b08ed1SBarry Smith Input Parameters: 57019b08ed1SBarry Smith + A - the SeqAIJ matrix 57119b08ed1SBarry Smith - nztotal - bound on the number of nonzeros 57219b08ed1SBarry Smith 57319b08ed1SBarry Smith Level: advanced 57419b08ed1SBarry Smith 57519b08ed1SBarry Smith Notes: 57619b08ed1SBarry 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. 57719b08ed1SBarry Smith Simply call MatSetValues() after this call to provide the matrix entries in the usual manner. This matrix may be used 57819b08ed1SBarry Smith as always with multiple matrix assemblies. 57919b08ed1SBarry Smith 58019b08ed1SBarry Smith .seealso: MatSetOption(), MAT_SORTED_FULL, MatSetValues(), MatSeqAIJSetPreallocation() 58119b08ed1SBarry Smith @*/ 58219b08ed1SBarry Smith 58319b08ed1SBarry Smith PetscErrorCode MatSeqAIJSetTotalPreallocation(Mat A,PetscInt nztotal) 58419b08ed1SBarry Smith { 58519b08ed1SBarry Smith PetscErrorCode ierr; 58619b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 58719b08ed1SBarry Smith 58819b08ed1SBarry Smith PetscFunctionBegin; 58919b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 59019b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 59119b08ed1SBarry Smith a->maxnz = nztotal; 59219b08ed1SBarry Smith if (!a->imax) { 59319b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->imax);CHKERRQ(ierr); 59419b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 59519b08ed1SBarry Smith } 59619b08ed1SBarry Smith if (!a->ilen) { 59719b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->ilen);CHKERRQ(ierr); 59819b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 59919b08ed1SBarry Smith } else { 60019b08ed1SBarry Smith ierr = PetscMemzero(a->ilen,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 60119b08ed1SBarry Smith } 60219b08ed1SBarry Smith 60319b08ed1SBarry Smith /* allocate the matrix space */ 60419b08ed1SBarry Smith if (A->structure_only) { 60519b08ed1SBarry Smith ierr = PetscMalloc1(nztotal,&a->j);CHKERRQ(ierr); 60619b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&a->i);CHKERRQ(ierr); 60719b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*sizeof(PetscInt));CHKERRQ(ierr); 60819b08ed1SBarry Smith } else { 60919b08ed1SBarry Smith ierr = PetscMalloc3(nztotal,&a->a,nztotal,&a->j,A->rmap->n+1,&a->i);CHKERRQ(ierr); 61019b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 61119b08ed1SBarry Smith } 61219b08ed1SBarry Smith a->i[0] = 0; 61319b08ed1SBarry Smith if (A->structure_only) { 61419b08ed1SBarry Smith a->singlemalloc = PETSC_FALSE; 61519b08ed1SBarry Smith a->free_a = PETSC_FALSE; 61619b08ed1SBarry Smith } else { 61719b08ed1SBarry Smith a->singlemalloc = PETSC_TRUE; 61819b08ed1SBarry Smith a->free_a = PETSC_TRUE; 61919b08ed1SBarry Smith } 62019b08ed1SBarry Smith a->free_ij = PETSC_TRUE; 62119b08ed1SBarry Smith A->ops->setvalues = MatSetValues_SeqAIJ_SortedFullNoPreallocation; 62219b08ed1SBarry Smith A->preallocated = PETSC_TRUE; 62319b08ed1SBarry Smith PetscFunctionReturn(0); 62419b08ed1SBarry Smith } 62519b08ed1SBarry Smith 626071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 627071fcb05SBarry Smith { 628071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 629071fcb05SBarry Smith PetscInt *rp,k,row; 630071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 631071fcb05SBarry Smith PetscErrorCode ierr; 632071fcb05SBarry Smith PetscInt *aj = a->j; 633071fcb05SBarry Smith MatScalar *aa = a->a,*ap; 634071fcb05SBarry Smith 635071fcb05SBarry Smith PetscFunctionBegin; 636071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 637071fcb05SBarry Smith row = im[k]; 63819b08ed1SBarry 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); 639071fcb05SBarry Smith rp = aj + ai[row]; 640071fcb05SBarry Smith ap = aa + ai[row]; 641071fcb05SBarry Smith if (!A->was_assembled) { 642071fcb05SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 643071fcb05SBarry Smith } 644071fcb05SBarry Smith if (!A->structure_only) { 645071fcb05SBarry Smith if (v) { 646071fcb05SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 647071fcb05SBarry Smith v += n; 648071fcb05SBarry Smith } else { 649071fcb05SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 650071fcb05SBarry Smith } 651071fcb05SBarry Smith } 652071fcb05SBarry Smith ailen[row] = n; 653071fcb05SBarry Smith a->nz += n; 654071fcb05SBarry Smith } 6558c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 656c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 657e2cf4d64SStefano Zampini #endif 658071fcb05SBarry Smith PetscFunctionReturn(0); 659071fcb05SBarry Smith } 660071fcb05SBarry Smith 66181824310SBarry Smith 662a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 6637eb43aa7SLois Curfman McInnes { 6647eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 66597f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 66697f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 66754f21887SBarry Smith MatScalar *ap,*aa = a->a; 6687eb43aa7SLois Curfman McInnes 6693a40ed3dSBarry Smith PetscFunctionBegin; 6707eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 6717eb43aa7SLois Curfman McInnes row = im[k]; 672e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 673e32f2f54SBarry 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); 674bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 6757eb43aa7SLois Curfman McInnes nrow = ailen[row]; 6767eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 677e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 678e32f2f54SBarry 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); 679bfeeae90SHong Zhang col = in[l]; 6807eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 6817eb43aa7SLois Curfman McInnes while (high-low > 5) { 6827eb43aa7SLois Curfman McInnes t = (low+high)/2; 6837eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 6847eb43aa7SLois Curfman McInnes else low = t; 6857eb43aa7SLois Curfman McInnes } 6867eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 6877eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 6887eb43aa7SLois Curfman McInnes if (rp[i] == col) { 689b49de8d1SLois Curfman McInnes *v++ = ap[i]; 6907eb43aa7SLois Curfman McInnes goto finished; 6917eb43aa7SLois Curfman McInnes } 6927eb43aa7SLois Curfman McInnes } 69397e567efSBarry Smith *v++ = 0.0; 6947eb43aa7SLois Curfman McInnes finished:; 6957eb43aa7SLois Curfman McInnes } 6967eb43aa7SLois Curfman McInnes } 6973a40ed3dSBarry Smith PetscFunctionReturn(0); 6987eb43aa7SLois Curfman McInnes } 6997eb43aa7SLois Curfman McInnes 7003ea6fe3dSLisandro Dalcin PetscErrorCode MatView_SeqAIJ_Binary(Mat mat,PetscViewer viewer) 70117ab2063SBarry Smith { 7023ea6fe3dSLisandro Dalcin Mat_SeqAIJ *A = (Mat_SeqAIJ*)mat->data; 703c898d852SStefano Zampini const PetscScalar *av; 7043ea6fe3dSLisandro Dalcin PetscInt header[4],M,N,m,nz,i; 7053ea6fe3dSLisandro Dalcin PetscInt *rowlens; 7066849ba73SBarry Smith PetscErrorCode ierr; 70717ab2063SBarry Smith 7083a40ed3dSBarry Smith PetscFunctionBegin; 7093ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 7102205254eSKarl Rupp 7113ea6fe3dSLisandro Dalcin M = mat->rmap->N; 7123ea6fe3dSLisandro Dalcin N = mat->cmap->N; 7133ea6fe3dSLisandro Dalcin m = mat->rmap->n; 7143ea6fe3dSLisandro Dalcin nz = A->nz; 715416022c9SBarry Smith 7163ea6fe3dSLisandro Dalcin /* write matrix header */ 7173ea6fe3dSLisandro Dalcin header[0] = MAT_FILE_CLASSID; 7183ea6fe3dSLisandro Dalcin header[1] = M; header[2] = N; header[3] = nz; 7193ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr); 720416022c9SBarry Smith 7213ea6fe3dSLisandro Dalcin /* fill in and store row lengths */ 7223ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(m,&rowlens);CHKERRQ(ierr); 7233ea6fe3dSLisandro Dalcin for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i]; 7243ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT);CHKERRQ(ierr); 7253ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 7263ea6fe3dSLisandro Dalcin /* store column indices */ 7273ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT);CHKERRQ(ierr); 728416022c9SBarry Smith /* store nonzero values */ 729c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(mat,&av);CHKERRQ(ierr); 730c898d852SStefano Zampini ierr = PetscViewerBinaryWrite(viewer,av,nz,PETSC_SCALAR);CHKERRQ(ierr); 731c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(mat,&av);CHKERRQ(ierr); 732b37d52dbSMark F. Adams 7333ea6fe3dSLisandro Dalcin /* write block size option to the viewer's .info file */ 7343ea6fe3dSLisandro Dalcin ierr = MatView_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 7353a40ed3dSBarry Smith PetscFunctionReturn(0); 73617ab2063SBarry Smith } 737416022c9SBarry Smith 7387dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 7397dc0baabSHong Zhang { 7407dc0baabSHong Zhang PetscErrorCode ierr; 7417dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7427dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 7437dc0baabSHong Zhang 7447dc0baabSHong Zhang PetscFunctionBegin; 7457dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7467dc0baabSHong Zhang for (i=0; i<m; i++) { 7477dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 7487dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 7497dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 7507dc0baabSHong Zhang } 7517dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 7527dc0baabSHong Zhang } 7537dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7547dc0baabSHong Zhang PetscFunctionReturn(0); 7557dc0baabSHong Zhang } 7567dc0baabSHong Zhang 75709573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 758cd155464SBarry Smith 759dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 760416022c9SBarry Smith { 761416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 762c898d852SStefano Zampini const PetscScalar *av; 763dfbe8321SBarry Smith PetscErrorCode ierr; 76460e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 765e060cb09SBarry Smith const char *name; 766f3ef73ceSBarry Smith PetscViewerFormat format; 76717ab2063SBarry Smith 7683a40ed3dSBarry Smith PetscFunctionBegin; 7697dc0baabSHong Zhang if (A->structure_only) { 7707dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 7717dc0baabSHong Zhang PetscFunctionReturn(0); 7727dc0baabSHong Zhang } 77343e49210SHong Zhang 774b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 7752e5835c6SStefano Zampini if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 7762e5835c6SStefano Zampini 777c898d852SStefano Zampini /* trigger copy to CPU if needed */ 778c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 779c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 78071c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 78197f1f81fSBarry Smith PetscInt nofinalvalue = 0; 78260e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 783c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 784d00d2cf4SBarry Smith nofinalvalue = 1; 785d00d2cf4SBarry Smith } 786d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 787d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 78877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 789fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 790fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 791fbfe6fa7SJed Brown #else 79277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 793fbfe6fa7SJed Brown #endif 794b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 79517ab2063SBarry Smith 79617ab2063SBarry Smith for (i=0; i<m; i++) { 79760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 798aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 799a9bf72d8SJed 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); 80017ab2063SBarry Smith #else 80160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 80217ab2063SBarry Smith #endif 80317ab2063SBarry Smith } 80417ab2063SBarry Smith } 805d00d2cf4SBarry Smith if (nofinalvalue) { 806c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 807c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 808c337ccceSJed Brown #else 809d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 810c337ccceSJed Brown #endif 811d00d2cf4SBarry Smith } 812317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 813fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 814d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 815fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 816d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 81744cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 81877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 81960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 820aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 82136db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 82260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 82336db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 82460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 82536db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 82660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 8276831982aSBarry Smith } 82844cd7ae7SLois Curfman McInnes #else 82960e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 83044cd7ae7SLois Curfman McInnes #endif 83144cd7ae7SLois Curfman McInnes } 832b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 83344cd7ae7SLois Curfman McInnes } 834d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 835fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 83697f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 837d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 838854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 839496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 840496be53dSLois Curfman McInnes sptr[i] = nzd+1; 84160e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 842496be53dSLois Curfman McInnes if (a->j[j] >= i) { 843aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 84436db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 845496be53dSLois Curfman McInnes #else 846496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 847496be53dSLois Curfman McInnes #endif 848496be53dSLois Curfman McInnes } 849496be53dSLois Curfman McInnes } 850496be53dSLois Curfman McInnes } 8512e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 85277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 8532e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 8542205254eSKarl Rupp if (i+4<m) { 8552205254eSKarl 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); 8562205254eSKarl Rupp } else if (i+3<m) { 8572205254eSKarl 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); 8582205254eSKarl Rupp } else if (i+2<m) { 8592205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 8602205254eSKarl Rupp } else if (i+1<m) { 8612205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 8622205254eSKarl Rupp } else if (i<m) { 8632205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 8642205254eSKarl Rupp } else { 8652205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 8662205254eSKarl Rupp } 867496be53dSLois Curfman McInnes } 868b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 869606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 870496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 87160e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 87277431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 873496be53dSLois Curfman McInnes } 874b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 875496be53dSLois Curfman McInnes } 876b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 877496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 87860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 879496be53dSLois Curfman McInnes if (a->j[j] >= i) { 880aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 88136db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 88260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8836831982aSBarry Smith } 884496be53dSLois Curfman McInnes #else 88560e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 886496be53dSLois Curfman McInnes #endif 887496be53dSLois Curfman McInnes } 888496be53dSLois Curfman McInnes } 889b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 890496be53dSLois Curfman McInnes } 891d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 892fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 89397f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 89487828ca2SBarry Smith PetscScalar value; 89568f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 89668f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 89768f1ed48SBarry Smith 89868f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 89968f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 90068f1ed48SBarry Smith realonly = PETSC_FALSE; 90168f1ed48SBarry Smith break; 90268f1ed48SBarry Smith } 90368f1ed48SBarry Smith } 90468f1ed48SBarry Smith #endif 90502594712SBarry Smith 906d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 90702594712SBarry Smith for (i=0; i<m; i++) { 90802594712SBarry Smith jcnt = 0; 909d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 910e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 91102594712SBarry Smith value = a->a[cnt++]; 912e24b481bSBarry Smith jcnt++; 91302594712SBarry Smith } else { 91402594712SBarry Smith value = 0.0; 91502594712SBarry Smith } 916aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 91768f1ed48SBarry Smith if (realonly) { 91860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 91968f1ed48SBarry Smith } else { 92060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 92168f1ed48SBarry Smith } 92202594712SBarry Smith #else 92360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 92402594712SBarry Smith #endif 92502594712SBarry Smith } 926b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 92702594712SBarry Smith } 928d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9293c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 930150b93efSMatthew G. Knepley PetscInt fshift=1; 931d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 9323c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 93319303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 9343c215bfdSMatthew Knepley #else 93519303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 9363c215bfdSMatthew Knepley #endif 937d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 9383c215bfdSMatthew Knepley for (i=0; i<m; i++) { 93960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 9403c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 941a9a0e077SKarl 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); 9423c215bfdSMatthew Knepley #else 943150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 9443c215bfdSMatthew Knepley #endif 9453c215bfdSMatthew Knepley } 9463c215bfdSMatthew Knepley } 947d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9483a40ed3dSBarry Smith } else { 949d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 950d5f3da31SBarry Smith if (A->factortype) { 95116cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 95216cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 95316cd7e1dSShri Abhyankar /* L part */ 95460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 95516cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 95616cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 95760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 95816cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9596712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 96016cd7e1dSShri Abhyankar } else { 96160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 96216cd7e1dSShri Abhyankar } 96316cd7e1dSShri Abhyankar #else 96460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 96516cd7e1dSShri Abhyankar #endif 96616cd7e1dSShri Abhyankar } 96716cd7e1dSShri Abhyankar /* diagonal */ 96816cd7e1dSShri Abhyankar j = a->diag[i]; 96916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 97016cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 97160e0710aSBarry 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); 97216cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9736712e2f1SBarry 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); 97416cd7e1dSShri Abhyankar } else { 97560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 97616cd7e1dSShri Abhyankar } 97716cd7e1dSShri Abhyankar #else 97860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 97916cd7e1dSShri Abhyankar #endif 98016cd7e1dSShri Abhyankar 98116cd7e1dSShri Abhyankar /* U part */ 98260e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 98316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 98416cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 98560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 98616cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 98722ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 98816cd7e1dSShri Abhyankar } else { 98960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 99016cd7e1dSShri Abhyankar } 99116cd7e1dSShri Abhyankar #else 99260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 99316cd7e1dSShri Abhyankar #endif 99416cd7e1dSShri Abhyankar } 99516cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 99616cd7e1dSShri Abhyankar } 99716cd7e1dSShri Abhyankar } else { 99817ab2063SBarry Smith for (i=0; i<m; i++) { 99977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 100060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 1001aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 100236db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 100360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 100436db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 100560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 10063a40ed3dSBarry Smith } else { 100760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 100817ab2063SBarry Smith } 100917ab2063SBarry Smith #else 101060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 101117ab2063SBarry Smith #endif 101217ab2063SBarry Smith } 1013b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 101417ab2063SBarry Smith } 101516cd7e1dSShri Abhyankar } 1016d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 101717ab2063SBarry Smith } 1018b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 10193a40ed3dSBarry Smith PetscFunctionReturn(0); 1020416022c9SBarry Smith } 1021416022c9SBarry Smith 10229804daf3SBarry Smith #include <petscdraw.h> 1023dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 1024416022c9SBarry Smith { 1025480ef9eaSBarry Smith Mat A = (Mat) Aa; 1026416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1027dfbe8321SBarry Smith PetscErrorCode ierr; 1028383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 1029383922c3SLisandro Dalcin int color; 1030b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1031b0a32e0cSBarry Smith PetscViewer viewer; 1032f3ef73ceSBarry Smith PetscViewerFormat format; 1033cddf8d76SBarry Smith 10343a40ed3dSBarry Smith PetscFunctionBegin; 1035480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 1036b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1037b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1038383922c3SLisandro Dalcin 1039416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 10400513a670SBarry Smith 1041fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1042383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10430513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 1044b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1045416022c9SBarry Smith for (i=0; i<m; i++) { 1046cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1047bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1048bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 104936db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 1050b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1051cddf8d76SBarry Smith } 1052cddf8d76SBarry Smith } 1053b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 1054cddf8d76SBarry Smith for (i=0; i<m; i++) { 1055cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1056bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1057bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1058cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 1059b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1060cddf8d76SBarry Smith } 1061cddf8d76SBarry Smith } 1062b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1063cddf8d76SBarry Smith for (i=0; i<m; i++) { 1064cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1065bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1066bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 106736db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 1068b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1069416022c9SBarry Smith } 1070416022c9SBarry Smith } 1071383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10720513a670SBarry Smith } else { 10730513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 10740513a670SBarry Smith /* first determine max of all nonzero values */ 1075b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1076383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 1077b0a32e0cSBarry Smith PetscDraw popup; 10780513a670SBarry Smith 10790513a670SBarry Smith for (i=0; i<nz; i++) { 10800513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 10810513a670SBarry Smith } 1082383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 1083b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 108445f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 1085383922c3SLisandro Dalcin 1086383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10870513a670SBarry Smith for (i=0; i<m; i++) { 1088383922c3SLisandro Dalcin y_l = m - i - 1.0; 1089383922c3SLisandro Dalcin y_r = y_l + 1.0; 1090bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1091383922c3SLisandro Dalcin x_l = a->j[j]; 1092383922c3SLisandro Dalcin x_r = x_l + 1.0; 1093b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 1094b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 10950513a670SBarry Smith count++; 10960513a670SBarry Smith } 10970513a670SBarry Smith } 1098383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10990513a670SBarry Smith } 1100480ef9eaSBarry Smith PetscFunctionReturn(0); 1101480ef9eaSBarry Smith } 1102cddf8d76SBarry Smith 11039804daf3SBarry Smith #include <petscdraw.h> 1104dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 1105480ef9eaSBarry Smith { 1106dfbe8321SBarry Smith PetscErrorCode ierr; 1107b0a32e0cSBarry Smith PetscDraw draw; 110836db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1109ace3abfcSBarry Smith PetscBool isnull; 1110480ef9eaSBarry Smith 1111480ef9eaSBarry Smith PetscFunctionBegin; 1112b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1113b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1114480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1115480ef9eaSBarry Smith 1116d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1117480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1118b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1119832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1120b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 11210298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1122832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 11233a40ed3dSBarry Smith PetscFunctionReturn(0); 1124416022c9SBarry Smith } 1125416022c9SBarry Smith 1126dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1127416022c9SBarry Smith { 1128dfbe8321SBarry Smith PetscErrorCode ierr; 1129ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1130416022c9SBarry Smith 11313a40ed3dSBarry Smith PetscFunctionBegin; 1132251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1133251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1134251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1135c45a1595SBarry Smith if (iascii) { 11363a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 11370f5bd95cSBarry Smith } else if (isbinary) { 11383a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 11390f5bd95cSBarry Smith } else if (isdraw) { 11403a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 114111aeaf0aSBarry Smith } 11424108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 11433a40ed3dSBarry Smith PetscFunctionReturn(0); 114417ab2063SBarry Smith } 114519bcc07fSBarry Smith 1146dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 114717ab2063SBarry Smith { 1148416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11496849ba73SBarry Smith PetscErrorCode ierr; 1150580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1151d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 115254f21887SBarry Smith MatScalar *aa = a->a,*ap; 11533447b6efSHong Zhang PetscReal ratio = 0.6; 115417ab2063SBarry Smith 11553a40ed3dSBarry Smith PetscFunctionBegin; 11563a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1157071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1158b215bc84SStefano Zampini if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) { 1159b215bc84SStefano Zampini /* we need to respect users asking to use or not the inodes routine in between matrix assemblies */ 1160b215bc84SStefano Zampini ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 1161b215bc84SStefano Zampini PetscFunctionReturn(0); 1162b215bc84SStefano Zampini } 116317ab2063SBarry Smith 116443ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 116517ab2063SBarry Smith for (i=1; i<m; i++) { 1166416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 116717ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 116894a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 116917ab2063SBarry Smith if (fshift) { 1170bfeeae90SHong Zhang ip = aj + ai[i]; 1171bfeeae90SHong Zhang ap = aa + ai[i]; 117217ab2063SBarry Smith N = ailen[i]; 1173580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1174580bdb30SBarry Smith if (!A->structure_only) { 1175580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 117617ab2063SBarry Smith } 117717ab2063SBarry Smith } 117817ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 117917ab2063SBarry Smith } 118017ab2063SBarry Smith if (m) { 118117ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 118217ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 118317ab2063SBarry Smith } 11847b083b7cSBarry Smith 118517ab2063SBarry Smith /* reset ilen and imax for each row */ 11867b083b7cSBarry Smith a->nonzerorowcnt = 0; 1187396832f4SHong Zhang if (A->structure_only) { 1188071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1189071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1190396832f4SHong Zhang } else { /* !A->structure_only */ 119117ab2063SBarry Smith for (i=0; i<m; i++) { 119217ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 11937b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 119417ab2063SBarry Smith } 1195396832f4SHong Zhang } 1196bfeeae90SHong Zhang a->nz = ai[m]; 119765e19b50SBarry 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); 119817ab2063SBarry Smith 119909f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1200d0f46423SBarry 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); 1201ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1202ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 12032205254eSKarl Rupp 12048e58a170SBarry Smith A->info.mallocs += a->reallocs; 1205dd5f02e7SSatish Balay a->reallocs = 0; 12066712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 120736db0b34SBarry Smith a->rmax = rmax; 12084e220ebcSLois Curfman McInnes 1209396832f4SHong Zhang if (!A->structure_only) { 121011e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1211396832f4SHong Zhang } 12124108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 12133a40ed3dSBarry Smith PetscFunctionReturn(0); 121417ab2063SBarry Smith } 121517ab2063SBarry Smith 121699cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 121799cafbc1SBarry Smith { 121899cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 121999cafbc1SBarry Smith PetscInt i,nz = a->nz; 12202e5835c6SStefano Zampini MatScalar *aa; 1221acf2f550SJed Brown PetscErrorCode ierr; 122299cafbc1SBarry Smith 122399cafbc1SBarry Smith PetscFunctionBegin; 12242e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 122599cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 12262e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1227acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12288c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1229c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1230e2cf4d64SStefano Zampini #endif 123199cafbc1SBarry Smith PetscFunctionReturn(0); 123299cafbc1SBarry Smith } 123399cafbc1SBarry Smith 123499cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 123599cafbc1SBarry Smith { 123699cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 123799cafbc1SBarry Smith PetscInt i,nz = a->nz; 12382e5835c6SStefano Zampini MatScalar *aa; 1239acf2f550SJed Brown PetscErrorCode ierr; 124099cafbc1SBarry Smith 124199cafbc1SBarry Smith PetscFunctionBegin; 12422e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 124399cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 12442e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1245acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12468c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1247c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1248e2cf4d64SStefano Zampini #endif 124999cafbc1SBarry Smith PetscFunctionReturn(0); 125099cafbc1SBarry Smith } 125199cafbc1SBarry Smith 1252dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 125317ab2063SBarry Smith { 1254416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1255dfbe8321SBarry Smith PetscErrorCode ierr; 12563a40ed3dSBarry Smith 12573a40ed3dSBarry Smith PetscFunctionBegin; 1258580bdb30SBarry Smith ierr = PetscArrayzero(a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 1259acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12608c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1261c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1262e2cf4d64SStefano Zampini #endif 12633a40ed3dSBarry Smith PetscFunctionReturn(0); 126417ab2063SBarry Smith } 1265416022c9SBarry Smith 1266dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 126717ab2063SBarry Smith { 1268416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1269dfbe8321SBarry Smith PetscErrorCode ierr; 1270d5d45c9bSBarry Smith 12713a40ed3dSBarry Smith PetscFunctionBegin; 1272aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1273d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 127417ab2063SBarry Smith #endif 1275e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 12766bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 12776bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 127805b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1279d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1280071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1281071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1282846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 128371f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 128405b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 12856bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 128605b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 1287cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 1288a30b2313SHong Zhang 12894108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1290bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1291901853e0SKris Buschelman 12926718818eSStefano Zampini /* MatMatMultNumeric_SeqAIJ_SeqAIJ_Sorted may allocate this. 12936718818eSStefano Zampini That function is so heavily used (sometimes in an hidden way through multnumeric function pointers) 12946718818eSStefano Zampini that is hard to properly add this data to the MatProduct data. We free it here to avoid 12956718818eSStefano Zampini users reusing the matrix object with different data to incur in obscure segmentation faults 12966718818eSStefano Zampini due to different matrix sizes */ 12976718818eSStefano Zampini ierr = PetscObjectCompose((PetscObject)A,"__PETSc__ab_dense",NULL);CHKERRQ(ierr); 12986718818eSStefano Zampini 1299f4259b30SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)A,NULL);CHKERRQ(ierr); 1300bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1301bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1302bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1303bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1304bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1305bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 13064222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA) 13074222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 1308e6e9a74fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",NULL);CHKERRQ(ierr); 1309fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 13104222ddf1SHong Zhang #endif 13113d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 13123d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijkokkos_C",NULL);CHKERRQ(ierr); 13133d0639e7SStefano Zampini #endif 13144222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL);CHKERRQ(ierr); 1315af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1316af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1317af8000cdSHong Zhang #endif 1318d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 1319d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_scalapack_C",NULL);CHKERRQ(ierr); 1320d24d4204SJose E. Roman #endif 132163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 132263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 13234222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 132463c07aadSStefano Zampini #endif 1325b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1326c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1327c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1328bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1329bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1330846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1331bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1332bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 13334222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL);CHKERRQ(ierr); 13344222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 13354222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 13363a40ed3dSBarry Smith PetscFunctionReturn(0); 133717ab2063SBarry Smith } 133817ab2063SBarry Smith 1339ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 134017ab2063SBarry Smith { 1341416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13424846f1f5SKris Buschelman PetscErrorCode ierr; 13433a40ed3dSBarry Smith 13443a40ed3dSBarry Smith PetscFunctionBegin; 1345a65d3064SKris Buschelman switch (op) { 1346a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 13474e0d8c25SBarry Smith a->roworiented = flg; 1348a65d3064SKris Buschelman break; 1349a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1350a9817697SBarry Smith a->keepnonzeropattern = flg; 1351a65d3064SKris Buschelman break; 1352512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1353512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1354a65d3064SKris Buschelman break; 1355a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 13564e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1357a65d3064SKris Buschelman break; 1358a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 13594e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1360a65d3064SKris Buschelman break; 136128b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 136228b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 136328b2fa4aSMatthew Knepley break; 1364a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 13654e0d8c25SBarry Smith a->ignorezeroentries = flg; 13660df259c2SBarry Smith break; 13673d472b54SHong Zhang case MAT_SPD: 1368b1646e73SJed Brown case MAT_SYMMETRIC: 1369b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1370b1646e73SJed Brown case MAT_HERMITIAN: 1371b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1372957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 13735021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 13745021d80fSJed Brown break; 13758c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 1376a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1377a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1378290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1379a65d3064SKris Buschelman break; 1380b87ac2d8SJed Brown case MAT_USE_INODES: 1381b215bc84SStefano Zampini ierr = MatSetOption_SeqAIJ_Inode(A,MAT_USE_INODES,flg);CHKERRQ(ierr); 1382b87ac2d8SJed Brown break; 1383c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1384c10200c1SHong Zhang A->submat_singleis = flg; 1385c10200c1SHong Zhang break; 1386071fcb05SBarry Smith case MAT_SORTED_FULL: 1387071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1388071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1389071fcb05SBarry Smith break; 1390a65d3064SKris Buschelman default: 1391e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1392a65d3064SKris Buschelman } 13933a40ed3dSBarry Smith PetscFunctionReturn(0); 139417ab2063SBarry Smith } 139517ab2063SBarry Smith 1396dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 139717ab2063SBarry Smith { 1398416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13996849ba73SBarry Smith PetscErrorCode ierr; 1400fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1401c898d852SStefano Zampini PetscScalar *x; 1402c898d852SStefano Zampini const PetscScalar *aa; 140317ab2063SBarry Smith 14043a40ed3dSBarry Smith PetscFunctionBegin; 1405d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1406e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1407c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 1408d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1409d3e70bfaSHong Zhang PetscInt *diag=a->diag; 1410fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 14112c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 1412fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1413c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 141435e7444dSHong Zhang PetscFunctionReturn(0); 141535e7444dSHong Zhang } 141635e7444dSHong Zhang 1417fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 141835e7444dSHong Zhang for (i=0; i<n; i++) { 1419fdc842d1SBarry Smith x[i] = 0.0; 142035e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 142135e7444dSHong Zhang if (aj[j] == i) { 142235e7444dSHong Zhang x[i] = aa[j]; 142317ab2063SBarry Smith break; 142417ab2063SBarry Smith } 142517ab2063SBarry Smith } 142617ab2063SBarry Smith } 1427fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1428c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 14293a40ed3dSBarry Smith PetscFunctionReturn(0); 143017ab2063SBarry Smith } 143117ab2063SBarry Smith 1432c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1433dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 143417ab2063SBarry Smith { 1435416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1436d9ca1df4SBarry Smith PetscScalar *y; 1437d9ca1df4SBarry Smith const PetscScalar *x; 1438dfbe8321SBarry Smith PetscErrorCode ierr; 1439d0f46423SBarry Smith PetscInt m = A->rmap->n; 14405c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1441d9ca1df4SBarry Smith const MatScalar *v; 1442a77337e4SBarry Smith PetscScalar alpha; 1443d9ca1df4SBarry Smith PetscInt n,i,j; 1444d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 14453447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1446ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 14475c897100SBarry Smith #endif 144817ab2063SBarry Smith 14493a40ed3dSBarry Smith PetscFunctionBegin; 14502e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1451d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14521ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 14535c897100SBarry Smith 14545c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1455bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 14565c897100SBarry Smith #else 14573447b6efSHong Zhang if (usecprow) { 14583447b6efSHong Zhang m = cprow.nrows; 14593447b6efSHong Zhang ii = cprow.i; 14607b2bb3b9SHong Zhang ridx = cprow.rindex; 14613447b6efSHong Zhang } else { 14623447b6efSHong Zhang ii = a->i; 14633447b6efSHong Zhang } 146417ab2063SBarry Smith for (i=0; i<m; i++) { 14653447b6efSHong Zhang idx = a->j + ii[i]; 14663447b6efSHong Zhang v = a->a + ii[i]; 14673447b6efSHong Zhang n = ii[i+1] - ii[i]; 14683447b6efSHong Zhang if (usecprow) { 14697b2bb3b9SHong Zhang alpha = x[ridx[i]]; 14703447b6efSHong Zhang } else { 147117ab2063SBarry Smith alpha = x[i]; 14723447b6efSHong Zhang } 147304fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 147417ab2063SBarry Smith } 14755c897100SBarry Smith #endif 1476dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1477d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14781ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14793a40ed3dSBarry Smith PetscFunctionReturn(0); 148017ab2063SBarry Smith } 148117ab2063SBarry Smith 1482dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 14835c897100SBarry Smith { 1484dfbe8321SBarry Smith PetscErrorCode ierr; 14855c897100SBarry Smith 14865c897100SBarry Smith PetscFunctionBegin; 1487170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 14885c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 14895c897100SBarry Smith PetscFunctionReturn(0); 14905c897100SBarry Smith } 14915c897100SBarry Smith 1492c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 149378b84d54SShri Abhyankar 1494dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 149517ab2063SBarry Smith { 1496416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1497d9fead3dSBarry Smith PetscScalar *y; 149854f21887SBarry Smith const PetscScalar *x; 149954f21887SBarry Smith const MatScalar *aa; 1500dfbe8321SBarry Smith PetscErrorCode ierr; 1501003131ecSBarry Smith PetscInt m=A->rmap->n; 15020298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 15037b083b7cSBarry Smith PetscInt n,i; 1504362ced78SSatish Balay PetscScalar sum; 1505ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 150617ab2063SBarry Smith 1507b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 150897952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1509fee21e36SBarry Smith #endif 1510fee21e36SBarry Smith 15113a40ed3dSBarry Smith PetscFunctionBegin; 1512b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1513b215bc84SStefano Zampini ierr = MatMult_SeqAIJ_Inode(A,xx,yy);CHKERRQ(ierr); 1514b215bc84SStefano Zampini PetscFunctionReturn(0); 1515b215bc84SStefano Zampini } 15163649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 15171ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1518416022c9SBarry Smith ii = a->i; 15194eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1520580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 152197952fefSHong Zhang m = a->compressedrow.nrows; 152297952fefSHong Zhang ii = a->compressedrow.i; 152397952fefSHong Zhang ridx = a->compressedrow.rindex; 152497952fefSHong Zhang for (i=0; i<m; i++) { 152597952fefSHong Zhang n = ii[i+1] - ii[i]; 152697952fefSHong Zhang aj = a->j + ii[i]; 152797952fefSHong Zhang aa = a->a + ii[i]; 152897952fefSHong Zhang sum = 0.0; 1529003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1530003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 153197952fefSHong Zhang y[*ridx++] = sum; 153297952fefSHong Zhang } 153397952fefSHong Zhang } else { /* do not use compressed row format */ 1534b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 15353d3eaba7SBarry Smith aj = a->j; 15363d3eaba7SBarry Smith aa = a->a; 1537b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1538b05257ddSBarry Smith #else 153917ab2063SBarry Smith for (i=0; i<m; i++) { 1540003131ecSBarry Smith n = ii[i+1] - ii[i]; 1541003131ecSBarry Smith aj = a->j + ii[i]; 1542003131ecSBarry Smith aa = a->a + ii[i]; 154317ab2063SBarry Smith sum = 0.0; 1544003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 154517ab2063SBarry Smith y[i] = sum; 154617ab2063SBarry Smith } 15478d195f9aSBarry Smith #endif 1548b05257ddSBarry Smith } 15497b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 15503649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15511ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15523a40ed3dSBarry Smith PetscFunctionReturn(0); 155317ab2063SBarry Smith } 155417ab2063SBarry Smith 1555b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1556b434eb95SMatthew G. Knepley { 1557b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1558b434eb95SMatthew G. Knepley PetscScalar *y; 1559b434eb95SMatthew G. Knepley const PetscScalar *x; 1560b434eb95SMatthew G. Knepley const MatScalar *aa; 1561b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1562b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1563b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1564b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1565b434eb95SMatthew G. Knepley PetscScalar sum; 1566b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1567b434eb95SMatthew G. Knepley 1568b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1569b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1570b434eb95SMatthew G. Knepley #endif 1571b434eb95SMatthew G. Knepley 1572b434eb95SMatthew G. Knepley PetscFunctionBegin; 1573b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1574b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1575b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1576b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1577b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1578b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1579b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1580b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1581b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1582b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1583b434eb95SMatthew G. Knepley sum = 0.0; 1584b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1585b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1586b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1587b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1588b434eb95SMatthew G. Knepley } 1589b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 15903d3eaba7SBarry Smith ii = a->i; 1591b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1592b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1593b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1594b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1595b434eb95SMatthew G. Knepley sum = 0.0; 1596b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1597b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1598b434eb95SMatthew G. Knepley y[i] = sum; 1599b434eb95SMatthew G. Knepley } 1600b434eb95SMatthew G. Knepley } 1601b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1602b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1603b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1604b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1605b434eb95SMatthew G. Knepley } 1606b434eb95SMatthew G. Knepley 1607b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1608b434eb95SMatthew G. Knepley { 1609b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1610b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1611b434eb95SMatthew G. Knepley const PetscScalar *x; 1612b434eb95SMatthew G. Knepley const MatScalar *aa; 1613b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1614b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1615b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1616b434eb95SMatthew G. Knepley PetscScalar sum; 1617b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1618b434eb95SMatthew G. Knepley 1619b434eb95SMatthew G. Knepley PetscFunctionBegin; 1620b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1621d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1622b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1623b434eb95SMatthew G. Knepley if (zz != yy) { 1624580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1625b434eb95SMatthew G. Knepley } 1626b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1627b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1628b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1629b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1630b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1631b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1632b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1633b434eb95SMatthew G. Knepley sum = y[*ridx]; 1634b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1635b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1636b434eb95SMatthew G. Knepley } 1637b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16383d3eaba7SBarry Smith ii = a->i; 1639b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1640b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1641b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1642b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1643b434eb95SMatthew G. Knepley sum = y[i]; 1644b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1645b434eb95SMatthew G. Knepley z[i] = sum; 1646b434eb95SMatthew G. Knepley } 1647b434eb95SMatthew G. Knepley } 1648b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1649b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1650d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1651b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1652b434eb95SMatthew G. Knepley } 1653b434eb95SMatthew G. Knepley 1654c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1655dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 165617ab2063SBarry Smith { 1657416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1658f15663dcSBarry Smith PetscScalar *y,*z; 1659f15663dcSBarry Smith const PetscScalar *x; 166054f21887SBarry Smith const MatScalar *aa; 1661dfbe8321SBarry Smith PetscErrorCode ierr; 1662d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1663d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1664362ced78SSatish Balay PetscScalar sum; 1665ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 16669ea0dfa2SSatish Balay 16673a40ed3dSBarry Smith PetscFunctionBegin; 1668b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1669b215bc84SStefano Zampini ierr = MatMultAdd_SeqAIJ_Inode(A,xx,yy,zz);CHKERRQ(ierr); 1670b215bc84SStefano Zampini PetscFunctionReturn(0); 1671b215bc84SStefano Zampini } 1672f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1673d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 16744eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 16754eb6d288SHong Zhang if (zz != yy) { 1676580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 16774eb6d288SHong Zhang } 167897952fefSHong Zhang m = a->compressedrow.nrows; 167997952fefSHong Zhang ii = a->compressedrow.i; 168097952fefSHong Zhang ridx = a->compressedrow.rindex; 168197952fefSHong Zhang for (i=0; i<m; i++) { 168297952fefSHong Zhang n = ii[i+1] - ii[i]; 168397952fefSHong Zhang aj = a->j + ii[i]; 168497952fefSHong Zhang aa = a->a + ii[i]; 168597952fefSHong Zhang sum = y[*ridx]; 1686f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 168797952fefSHong Zhang z[*ridx++] = sum; 168897952fefSHong Zhang } 168997952fefSHong Zhang } else { /* do not use compressed row format */ 16903d3eaba7SBarry Smith ii = a->i; 1691f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 16923d3eaba7SBarry Smith aj = a->j; 16933d3eaba7SBarry Smith aa = a->a; 1694f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1695f15663dcSBarry Smith #else 169617ab2063SBarry Smith for (i=0; i<m; i++) { 1697f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1698f15663dcSBarry Smith aj = a->j + ii[i]; 1699f15663dcSBarry Smith aa = a->a + ii[i]; 170017ab2063SBarry Smith sum = y[i]; 1701f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 170217ab2063SBarry Smith z[i] = sum; 170317ab2063SBarry Smith } 170402ab625aSSatish Balay #endif 1705f15663dcSBarry Smith } 1706dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1707f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1708d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 17093a40ed3dSBarry Smith PetscFunctionReturn(0); 171017ab2063SBarry Smith } 171117ab2063SBarry Smith 171217ab2063SBarry Smith /* 171317ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 171417ab2063SBarry Smith */ 1715dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 171617ab2063SBarry Smith { 1717416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17186849ba73SBarry Smith PetscErrorCode ierr; 1719d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 172017ab2063SBarry Smith 17213a40ed3dSBarry Smith PetscFunctionBegin; 172209f38230SBarry Smith if (!a->diag) { 1723785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 17243bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 172509f38230SBarry Smith } 1726d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 172709f38230SBarry Smith a->diag[i] = a->i[i+1]; 1728bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1729bfeeae90SHong Zhang if (a->j[j] == i) { 173009f38230SBarry Smith a->diag[i] = j; 173117ab2063SBarry Smith break; 173217ab2063SBarry Smith } 173317ab2063SBarry Smith } 173417ab2063SBarry Smith } 17353a40ed3dSBarry Smith PetscFunctionReturn(0); 173617ab2063SBarry Smith } 173717ab2063SBarry Smith 173861ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 173961ecd0c6SBarry Smith { 174061ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 174161ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 174261ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 174361ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 174461ecd0c6SBarry Smith PetscErrorCode ierr; 174561ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 174661ecd0c6SBarry Smith 174761ecd0c6SBarry Smith PetscFunctionBegin; 174861ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 174961ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 175061ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 175161ecd0c6SBarry Smith PetscFunctionReturn(0); 175261ecd0c6SBarry Smith } 175361ecd0c6SBarry Smith 175461ecd0c6SBarry Smith if (a->diagonaldense) { 175561ecd0c6SBarry Smith cnt = 0; 175661ecd0c6SBarry Smith } else { 175761ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 175861ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 175961ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 176061ecd0c6SBarry Smith cnt++; 176161ecd0c6SBarry Smith mdiag[i] = 1; 176261ecd0c6SBarry Smith } 176361ecd0c6SBarry Smith } 176461ecd0c6SBarry Smith } 176561ecd0c6SBarry Smith if (!cnt) { 176661ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 176761ecd0c6SBarry Smith } else { 1768b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1769b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 177061ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 177161ecd0c6SBarry Smith 177261ecd0c6SBarry Smith a->a = NULL; 177361ecd0c6SBarry Smith a->j = NULL; 177461ecd0c6SBarry Smith a->i = NULL; 177561ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 177661ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 177761ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1778447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 177961ecd0c6SBarry Smith } 178061ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 178161ecd0c6SBarry Smith 178261ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 178361ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 178461ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1785447d62f5SStefano Zampini if (i < A->cmap->n) { 178661ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 178761ecd0c6SBarry Smith } 1788447d62f5SStefano Zampini } 178961ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179061ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179161ecd0c6SBarry Smith if (singlemalloc) { 179261ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 179361ecd0c6SBarry Smith } else { 179461ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 179561ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 179661ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 179761ecd0c6SBarry Smith } 179861ecd0c6SBarry Smith } 179961ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 180061ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 180161ecd0c6SBarry Smith PetscFunctionReturn(0); 180261ecd0c6SBarry Smith } 180361ecd0c6SBarry Smith 1804be5855fcSBarry Smith /* 1805be5855fcSBarry Smith Checks for missing diagonals 1806be5855fcSBarry Smith */ 1807ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1808be5855fcSBarry Smith { 1809be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18107734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1811994fe344SLisandro Dalcin PetscErrorCode ierr; 1812be5855fcSBarry Smith 1813be5855fcSBarry Smith PetscFunctionBegin; 181409f38230SBarry Smith *missing = PETSC_FALSE; 18157734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 181609f38230SBarry Smith *missing = PETSC_TRUE; 181709f38230SBarry Smith if (d) *d = 0; 1818994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 181909f38230SBarry Smith } else { 182001445905SHong Zhang PetscInt n; 182101445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1822f1e2ffcdSBarry Smith diag = a->diag; 182301445905SHong Zhang for (i=0; i<n; i++) { 18247734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 182509f38230SBarry Smith *missing = PETSC_TRUE; 182609f38230SBarry Smith if (d) *d = i; 1827994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1828358d2f5dSShri Abhyankar break; 182909f38230SBarry Smith } 1830be5855fcSBarry Smith } 1831be5855fcSBarry Smith } 1832be5855fcSBarry Smith PetscFunctionReturn(0); 1833be5855fcSBarry Smith } 1834be5855fcSBarry Smith 18350da83c2eSBarry Smith #include <petscblaslapack.h> 18360da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 18370da83c2eSBarry Smith 18380da83c2eSBarry Smith /* 18390da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 18400da83c2eSBarry Smith */ 18410da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 18420da83c2eSBarry Smith { 18430da83c2eSBarry Smith PetscErrorCode ierr; 18440da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 18450da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 18460da83c2eSBarry Smith const PetscReal shift = 0.0; 18470da83c2eSBarry Smith PetscInt ipvt[5]; 18480da83c2eSBarry Smith PetscScalar work[25],*v_work; 18490da83c2eSBarry Smith 18500da83c2eSBarry Smith PetscFunctionBegin; 18510da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 18520da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 18530da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 18540da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18550da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 18560da83c2eSBarry Smith } 18570da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 18580da83c2eSBarry Smith if (bsizemax > 7) { 18590da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 18600da83c2eSBarry Smith } 18610da83c2eSBarry Smith ncnt = 0; 18620da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18630da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 18640da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 18650da83c2eSBarry Smith switch (bsizes[i]) { 18660da83c2eSBarry Smith case 1: 18670da83c2eSBarry Smith *diag = 1.0/(*diag); 18680da83c2eSBarry Smith break; 18690da83c2eSBarry Smith case 2: 18700da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18710da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18720da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 18730da83c2eSBarry Smith break; 18740da83c2eSBarry Smith case 3: 18750da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18760da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18770da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 18780da83c2eSBarry Smith break; 18790da83c2eSBarry Smith case 4: 18800da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18810da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18820da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 18830da83c2eSBarry Smith break; 18840da83c2eSBarry Smith case 5: 18850da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18860da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18870da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 18880da83c2eSBarry Smith break; 18890da83c2eSBarry Smith case 6: 18900da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18910da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18920da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 18930da83c2eSBarry Smith break; 18940da83c2eSBarry Smith case 7: 18950da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18960da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18970da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 18980da83c2eSBarry Smith break; 18990da83c2eSBarry Smith default: 19000da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19010da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19020da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 19030da83c2eSBarry Smith } 19040da83c2eSBarry Smith ncnt += bsizes[i]; 19050da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 19060da83c2eSBarry Smith } 19070da83c2eSBarry Smith if (bsizemax > 7) { 19080da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 19090da83c2eSBarry Smith } 19100da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 19110da83c2eSBarry Smith PetscFunctionReturn(0); 19120da83c2eSBarry Smith } 19130da83c2eSBarry Smith 1914422a814eSBarry Smith /* 1915422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1916422a814eSBarry Smith */ 19177087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 191871f1c65dSBarry Smith { 191971f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 192071f1c65dSBarry Smith PetscErrorCode ierr; 1921d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 19222e5835c6SStefano Zampini const MatScalar *v; 192354f21887SBarry Smith PetscScalar *idiag,*mdiag; 192471f1c65dSBarry Smith 192571f1c65dSBarry Smith PetscFunctionBegin; 192671f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 192771f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 192871f1c65dSBarry Smith diag = a->diag; 192971f1c65dSBarry Smith if (!a->idiag) { 1930dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 19313bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,3*m*sizeof(PetscScalar));CHKERRQ(ierr); 193271f1c65dSBarry Smith } 19332e5835c6SStefano Zampini 193471f1c65dSBarry Smith mdiag = a->mdiag; 193571f1c65dSBarry Smith idiag = a->idiag; 19362e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 1937422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 193871f1c65dSBarry Smith for (i=0; i<m; i++) { 193971f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1940899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1941899639b0SHong Zhang if (PetscRealPart(fshift)) { 1942899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 19437b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19447b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 19457b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1946a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1947899639b0SHong Zhang } 194871f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 194971f1c65dSBarry Smith } 195071f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 195171f1c65dSBarry Smith } else { 195271f1c65dSBarry Smith for (i=0; i<m; i++) { 195371f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 195471f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 195571f1c65dSBarry Smith } 1956dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 195771f1c65dSBarry Smith } 195871f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 19592e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 196071f1c65dSBarry Smith PetscFunctionReturn(0); 196171f1c65dSBarry Smith } 196271f1c65dSBarry Smith 1963c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 196441f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 196517ab2063SBarry Smith { 1966416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1967e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 19682e5835c6SStefano Zampini const MatScalar *v,*idiag=NULL,*mdiag,*aa; 196954f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1970dfbe8321SBarry Smith PetscErrorCode ierr; 19713d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 197297f1f81fSBarry Smith const PetscInt *idx,*diag; 197317ab2063SBarry Smith 19743a40ed3dSBarry Smith PetscFunctionBegin; 1975b215bc84SStefano Zampini if (a->inode.use && a->inode.checked && omega == 1.0 && fshift == 0.0) { 1976b215bc84SStefano Zampini ierr = MatSOR_SeqAIJ_Inode(A,bb,omega,flag,fshift,its,lits,xx);CHKERRQ(ierr); 1977b215bc84SStefano Zampini PetscFunctionReturn(0); 1978b215bc84SStefano Zampini } 1979b965ef7fSBarry Smith its = its*lits; 198091723122SBarry Smith 198171f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 198271f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 198371f1c65dSBarry Smith a->fshift = fshift; 198471f1c65dSBarry Smith a->omega = omega; 1985ed480e8bSBarry Smith 198671f1c65dSBarry Smith diag = a->diag; 198771f1c65dSBarry Smith t = a->ssor_work; 1988ed480e8bSBarry Smith idiag = a->idiag; 198971f1c65dSBarry Smith mdiag = a->mdiag; 1990ed480e8bSBarry Smith 19912e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 19921ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 19933649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1994ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 199517ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 199617ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1997ed480e8bSBarry Smith bs = b; 199817ab2063SBarry Smith for (i=0; i<m; i++) { 199971f1c65dSBarry Smith d = fshift + mdiag[i]; 2000416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2001ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20022e5835c6SStefano Zampini v = aa + diag[i] + 1; 200317ab2063SBarry Smith sum = b[i]*d/omega; 2004003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 200517ab2063SBarry Smith x[i] = sum; 200617ab2063SBarry Smith } 20071ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20083649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20092e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 2010efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20113a40ed3dSBarry Smith PetscFunctionReturn(0); 201217ab2063SBarry Smith } 2013c783ea89SBarry Smith 20142205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 20152205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 20164c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 2017887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 201817ab2063SBarry Smith 201917ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 202017ab2063SBarry Smith 2021887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 202217ab2063SBarry Smith */ 202317ab2063SBarry Smith scale = (2.0/omega) - 1.0; 202417ab2063SBarry Smith 202517ab2063SBarry Smith /* x = (E + U)^{-1} b */ 202617ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2027416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2028ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20292e5835c6SStefano Zampini v = aa + diag[i] + 1; 203017ab2063SBarry Smith sum = b[i]; 2031e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2032ed480e8bSBarry Smith x[i] = sum*idiag[i]; 203317ab2063SBarry Smith } 203417ab2063SBarry Smith 203517ab2063SBarry Smith /* t = b - (2*E - D)x */ 20362e5835c6SStefano Zampini v = aa; 20372205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 203817ab2063SBarry Smith 203917ab2063SBarry Smith /* t = (E + L)^{-1}t */ 2040ed480e8bSBarry Smith ts = t; 2041416022c9SBarry Smith diag = a->diag; 204217ab2063SBarry Smith for (i=0; i<m; i++) { 2043416022c9SBarry Smith n = diag[i] - a->i[i]; 2044ed480e8bSBarry Smith idx = a->j + a->i[i]; 20452e5835c6SStefano Zampini v = aa + a->i[i]; 204617ab2063SBarry Smith sum = t[i]; 2047003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 2048ed480e8bSBarry Smith t[i] = sum*idiag[i]; 2049733d66baSBarry Smith /* x = x + t */ 2050733d66baSBarry Smith x[i] += t[i]; 205117ab2063SBarry Smith } 205217ab2063SBarry Smith 2053dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 20541ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20553649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20563a40ed3dSBarry Smith PetscFunctionReturn(0); 205717ab2063SBarry Smith } 205817ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 205917ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 206017ab2063SBarry Smith for (i=0; i<m; i++) { 2061416022c9SBarry Smith n = diag[i] - a->i[i]; 2062ed480e8bSBarry Smith idx = a->j + a->i[i]; 20632e5835c6SStefano Zampini v = aa + a->i[i]; 206417ab2063SBarry Smith sum = b[i]; 2065e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20665c99c7daSBarry Smith t[i] = sum; 2067ed480e8bSBarry Smith x[i] = sum*idiag[i]; 206817ab2063SBarry Smith } 20695c99c7daSBarry Smith xb = t; 2070efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20713a40ed3dSBarry Smith } else xb = b; 207217ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 207317ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2074416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2075ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20762e5835c6SStefano Zampini v = aa + diag[i] + 1; 207717ab2063SBarry Smith sum = xb[i]; 2078e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20795c99c7daSBarry Smith if (xb == b) { 2080ed480e8bSBarry Smith x[i] = sum*idiag[i]; 20815c99c7daSBarry Smith } else { 2082b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 208317ab2063SBarry Smith } 20845c99c7daSBarry Smith } 2085b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 208617ab2063SBarry Smith } 208717ab2063SBarry Smith its--; 208817ab2063SBarry Smith } 208917ab2063SBarry Smith while (its--) { 209017ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 209117ab2063SBarry Smith for (i=0; i<m; i++) { 2092b19a5dc2SMark Adams /* lower */ 2093b19a5dc2SMark Adams n = diag[i] - a->i[i]; 2094ed480e8bSBarry Smith idx = a->j + a->i[i]; 20952e5835c6SStefano Zampini v = aa + a->i[i]; 209617ab2063SBarry Smith sum = b[i]; 2097e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2098b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 2099b19a5dc2SMark Adams /* upper */ 2100b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2101b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21022e5835c6SStefano Zampini v = aa + diag[i] + 1; 2103b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2104b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 210517ab2063SBarry Smith } 2106b19a5dc2SMark Adams xb = t; 21079f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2108b19a5dc2SMark Adams } else xb = b; 210917ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 211017ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2111b19a5dc2SMark Adams sum = xb[i]; 2112b19a5dc2SMark Adams if (xb == b) { 2113b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 2114416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 2115ed480e8bSBarry Smith idx = a->j + a->i[i]; 21162e5835c6SStefano Zampini v = aa + a->i[i]; 2117e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2118ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 2119b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 2120b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2121b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21222e5835c6SStefano Zampini v = aa + diag[i] + 1; 2123b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2124b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 212517ab2063SBarry Smith } 2126b19a5dc2SMark Adams } 2127b19a5dc2SMark Adams if (xb == b) { 21289f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2129b19a5dc2SMark Adams } else { 2130b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 2131b19a5dc2SMark Adams } 213217ab2063SBarry Smith } 213317ab2063SBarry Smith } 21342e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 21351ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 21363649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 2137365a8a9eSBarry Smith PetscFunctionReturn(0); 213817ab2063SBarry Smith } 213917ab2063SBarry Smith 21402af78befSBarry Smith 2141dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 214217ab2063SBarry Smith { 2143416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21444e220ebcSLois Curfman McInnes 21453a40ed3dSBarry Smith PetscFunctionBegin; 21464e220ebcSLois Curfman McInnes info->block_size = 1.0; 21473966268fSBarry Smith info->nz_allocated = a->maxnz; 21483966268fSBarry Smith info->nz_used = a->nz; 21493966268fSBarry Smith info->nz_unneeded = (a->maxnz - a->nz); 21503966268fSBarry Smith info->assemblies = A->num_ass; 21513966268fSBarry Smith info->mallocs = A->info.mallocs; 21527adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2153d5f3da31SBarry Smith if (A->factortype) { 21544e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 21554e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 21564e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 21574e220ebcSLois Curfman McInnes } else { 21584e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 21594e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 21604e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 21614e220ebcSLois Curfman McInnes } 21623a40ed3dSBarry Smith PetscFunctionReturn(0); 216317ab2063SBarry Smith } 216417ab2063SBarry Smith 21652b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 216617ab2063SBarry Smith { 2167416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2168c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 21696849ba73SBarry Smith PetscErrorCode ierr; 217097b48c8fSBarry Smith const PetscScalar *xx; 21712e5835c6SStefano Zampini PetscScalar *bb,*aa; 2172c7da8527SEric Chamberland PetscInt d = 0; 217317ab2063SBarry Smith 21743a40ed3dSBarry Smith PetscFunctionBegin; 217597b48c8fSBarry Smith if (x && b) { 217697b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 217797b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 217897b48c8fSBarry Smith for (i=0; i<N; i++) { 217997b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2180447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 218197b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 218297b48c8fSBarry Smith } 218397b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 218497b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 218597b48c8fSBarry Smith } 218697b48c8fSBarry Smith 21872e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 2188a9817697SBarry Smith if (a->keepnonzeropattern) { 2189f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2190e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 21912e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2192f1e2ffcdSBarry Smith } 2193f4df32b1SMatthew Knepley if (diag != 0.0) { 2194c7da8527SEric Chamberland for (i=0; i<N; i++) { 2195c7da8527SEric Chamberland d = rows[i]; 2196447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2197c7da8527SEric 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); 2198c7da8527SEric Chamberland } 2199f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2200447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 22012e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 2202f1e2ffcdSBarry Smith } 2203f1e2ffcdSBarry Smith } 2204f1e2ffcdSBarry Smith } else { 2205f4df32b1SMatthew Knepley if (diag != 0.0) { 220617ab2063SBarry Smith for (i=0; i<N; i++) { 2207e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22087ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2209447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2210447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2211447d62f5SStefano Zampini } else { 2212416022c9SBarry Smith a->ilen[rows[i]] = 1; 22132e5835c6SStefano Zampini aa[a->i[rows[i]]] = diag; 2214bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2215447d62f5SStefano Zampini } 2216447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2217f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 221817ab2063SBarry Smith } 221917ab2063SBarry Smith } 22203a40ed3dSBarry Smith } else { 222117ab2063SBarry Smith for (i=0; i<N; i++) { 2222e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2223416022c9SBarry Smith a->ilen[rows[i]] = 0; 222417ab2063SBarry Smith } 222517ab2063SBarry Smith } 2226e56f5c9eSBarry Smith A->nonzerostate++; 2227f1e2ffcdSBarry Smith } 22282e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 22298c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2230c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2231e2cf4d64SStefano Zampini #endif 22324099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22333a40ed3dSBarry Smith PetscFunctionReturn(0); 223417ab2063SBarry Smith } 223517ab2063SBarry Smith 22366e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 22376e169961SBarry Smith { 22386e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22396e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 22406e169961SBarry Smith PetscErrorCode ierr; 22412b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 22426e169961SBarry Smith const PetscScalar *xx; 22432e5835c6SStefano Zampini PetscScalar *bb,*aa; 22446e169961SBarry Smith 22456e169961SBarry Smith PetscFunctionBegin; 22462e5835c6SStefano Zampini if (!N) PetscFunctionReturn(0); 22472e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 22486e169961SBarry Smith if (x && b) { 22496e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 22506e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 22512b40b63fSBarry Smith vecs = PETSC_TRUE; 22526e169961SBarry Smith } 22531795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 22546e169961SBarry Smith for (i=0; i<N; i++) { 22556e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22562e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 22572205254eSKarl Rupp 22586e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 22596e169961SBarry Smith } 22606e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 22616e169961SBarry Smith if (!zeroed[i]) { 22626e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 22634cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 22642e5835c6SStefano Zampini if (vecs) bb[i] -= aa[j]*xx[a->j[j]]; 22652e5835c6SStefano Zampini aa[j] = 0.0; 22666e169961SBarry Smith } 22676e169961SBarry Smith } 22684cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 22696e169961SBarry Smith } 22706e169961SBarry Smith if (x && b) { 22716e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 22726e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 22736e169961SBarry Smith } 22746e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 22756e169961SBarry Smith if (diag != 0.0) { 22766e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 22771d5a398dSstefano_zampini if (missing) { 22781d5a398dSstefano_zampini for (i=0; i<N; i++) { 22794cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 22804cf107fdSStefano 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]); 22811d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 22821d5a398dSstefano_zampini } 22831d5a398dSstefano_zampini } else { 22846e169961SBarry Smith for (i=0; i<N; i++) { 22852e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 22866e169961SBarry Smith } 22876e169961SBarry Smith } 22881d5a398dSstefano_zampini } 22892e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 22908c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2291c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2292e2cf4d64SStefano Zampini #endif 22934099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22946e169961SBarry Smith PetscFunctionReturn(0); 22956e169961SBarry Smith } 22966e169961SBarry Smith 2297a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 229817ab2063SBarry Smith { 2299416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23002e5835c6SStefano Zampini const PetscScalar *aa = a->a; 230197f1f81fSBarry Smith PetscInt *itmp; 23022e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23032e5835c6SStefano Zampini PetscErrorCode ierr; 23042e5835c6SStefano Zampini PetscBool rest = PETSC_FALSE; 23052e5835c6SStefano Zampini #endif 230617ab2063SBarry Smith 23073a40ed3dSBarry Smith PetscFunctionBegin; 23082e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23092e5835c6SStefano Zampini if (v && A->offloadmask == PETSC_OFFLOAD_GPU) { 23102e5835c6SStefano Zampini /* triggers copy to CPU */ 23112e5835c6SStefano Zampini rest = PETSC_TRUE; 23122e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 23132e5835c6SStefano Zampini } else aa = a->a; 23142e5835c6SStefano Zampini #endif 2315416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 23162e5835c6SStefano Zampini if (v) *v = (PetscScalar*)(aa + a->i[row]); 231717ab2063SBarry Smith if (idx) { 2318bfeeae90SHong Zhang itmp = a->j + a->i[row]; 231926fbe8dcSKarl Rupp if (*nz) *idx = itmp; 2320f4259b30SLisandro Dalcin else *idx = NULL; 232117ab2063SBarry Smith } 23222e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23232e5835c6SStefano Zampini if (rest) { 23242e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 23252e5835c6SStefano Zampini } 23262e5835c6SStefano Zampini #endif 23273a40ed3dSBarry Smith PetscFunctionReturn(0); 232817ab2063SBarry Smith } 232917ab2063SBarry Smith 2330a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 233117ab2063SBarry Smith { 23323a40ed3dSBarry Smith PetscFunctionBegin; 23332e5835c6SStefano Zampini *nz = 0; 23342e5835c6SStefano Zampini if (idx) *idx = NULL; 23352e5835c6SStefano Zampini if (v) *v = NULL; 23363a40ed3dSBarry Smith PetscFunctionReturn(0); 233717ab2063SBarry Smith } 233817ab2063SBarry Smith 2339dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 234017ab2063SBarry Smith { 2341416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23422e5835c6SStefano Zampini const MatScalar *v; 234336db0b34SBarry Smith PetscReal sum = 0.0; 23446849ba73SBarry Smith PetscErrorCode ierr; 234597f1f81fSBarry Smith PetscInt i,j; 234617ab2063SBarry Smith 23473a40ed3dSBarry Smith PetscFunctionBegin; 23482e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 234917ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2350570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2351570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 235273cf7048SBarry Smith PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&nz,v,&one)); 2353570b7f6dSBarry Smith #else 2354416022c9SBarry Smith for (i=0; i<a->nz; i++) { 235536db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 235617ab2063SBarry Smith } 23578f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2358570b7f6dSBarry Smith #endif 2359ca0c957dSBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 23603a40ed3dSBarry Smith } else if (type == NORM_1) { 236136db0b34SBarry Smith PetscReal *tmp; 236297f1f81fSBarry Smith PetscInt *jj = a->j; 23631795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2364064f8208SBarry Smith *nrm = 0.0; 2365416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2366bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 236717ab2063SBarry Smith } 2368d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2369064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 237017ab2063SBarry Smith } 2371606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 237251f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 23733a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2374064f8208SBarry Smith *nrm = 0.0; 2375d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 23762e5835c6SStefano Zampini const PetscScalar *v2 = v + a->i[j]; 237717ab2063SBarry Smith sum = 0.0; 2378416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 23792e5835c6SStefano Zampini sum += PetscAbsScalar(*v2); v2++; 238017ab2063SBarry Smith } 2381064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 238217ab2063SBarry Smith } 238351f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2384f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 23852e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 23863a40ed3dSBarry Smith PetscFunctionReturn(0); 238717ab2063SBarry Smith } 238817ab2063SBarry Smith 23894e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 23904e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 23914e938277SHong Zhang { 23924e938277SHong Zhang PetscErrorCode ierr; 23934e938277SHong Zhang PetscInt i,j,anzj; 23944e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 23954e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 23964e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 23974e938277SHong Zhang 23984e938277SHong Zhang PetscFunctionBegin; 23994e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2400854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2401785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2402785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 24034e938277SHong Zhang 24044e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 24054e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 240626fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 24074e938277SHong Zhang /* Form ati for csr format of A^T. */ 240826fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 24094e938277SHong Zhang 24104e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2411580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 24124e938277SHong Zhang 24134e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 24144e938277SHong Zhang for (i=0;i<am;i++) { 24154e938277SHong Zhang anzj = ai[i+1] - ai[i]; 24164e938277SHong Zhang for (j=0;j<anzj;j++) { 24174e938277SHong Zhang atj[atfill[*aj]] = i; 24184e938277SHong Zhang atfill[*aj++] += 1; 24194e938277SHong Zhang } 24204e938277SHong Zhang } 24214e938277SHong Zhang 24224e938277SHong Zhang /* Clean up temporary space and complete requests. */ 24234e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2424ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 242533d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2426b5bb3eecSMark Adams ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2427a2f3521dSMark F. Adams 24284e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 24294e938277SHong Zhang b->free_a = PETSC_FALSE; 24304e938277SHong Zhang b->free_ij = PETSC_TRUE; 24314e938277SHong Zhang b->nonew = 0; 24324e938277SHong Zhang PetscFunctionReturn(0); 24334e938277SHong Zhang } 24344e938277SHong Zhang 24357087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2436cd0d46ebSvictorle { 24373d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 243854f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 24392e5835c6SStefano Zampini const MatScalar *va,*vb; 24406849ba73SBarry Smith PetscErrorCode ierr; 244197f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2442cd0d46ebSvictorle 2443cd0d46ebSvictorle PetscFunctionBegin; 2444cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2445cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24465485867bSBarry Smith if (ma!=nb || na!=mb) { 24475485867bSBarry Smith *f = PETSC_FALSE; 24485485867bSBarry Smith PetscFunctionReturn(0); 24495485867bSBarry Smith } 24502e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&va);CHKERRQ(ierr); 24512e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(B,&vb);CHKERRQ(ierr); 2452cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2453cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2454785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2455785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2456cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2457cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2458cd0d46ebSvictorle 2459cd0d46ebSvictorle *f = PETSC_TRUE; 2460cd0d46ebSvictorle for (i=0; i<ma; i++) { 2461cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 246297f1f81fSBarry Smith PetscInt idc,idr; 24635485867bSBarry Smith PetscScalar vc,vr; 2464cd0d46ebSvictorle /* column/row index/value */ 24655485867bSBarry Smith idc = adx[aptr[i]]; 24665485867bSBarry Smith idr = bdx[bptr[idc]]; 24675485867bSBarry Smith vc = va[aptr[i]]; 24685485867bSBarry Smith vr = vb[bptr[idc]]; 24695485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 24705485867bSBarry Smith *f = PETSC_FALSE; 24715485867bSBarry Smith goto done; 2472cd0d46ebSvictorle } else { 24735485867bSBarry Smith aptr[i]++; 24745485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2475cd0d46ebSvictorle } 2476cd0d46ebSvictorle } 2477cd0d46ebSvictorle } 2478cd0d46ebSvictorle done: 2479cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 24803aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 24812e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&va);CHKERRQ(ierr); 24822e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(B,&vb);CHKERRQ(ierr); 2483cd0d46ebSvictorle PetscFunctionReturn(0); 2484cd0d46ebSvictorle } 2485cd0d46ebSvictorle 24867087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 24871cbb95d3SBarry Smith { 24883d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 248954f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 249054f21887SBarry Smith MatScalar *va,*vb; 24911cbb95d3SBarry Smith PetscErrorCode ierr; 24921cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 24931cbb95d3SBarry Smith 24941cbb95d3SBarry Smith PetscFunctionBegin; 24951cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 24961cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24971cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 24981cbb95d3SBarry Smith *f = PETSC_FALSE; 24991cbb95d3SBarry Smith PetscFunctionReturn(0); 25001cbb95d3SBarry Smith } 25011cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 25021cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 25031cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2504785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2505785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 25061cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 25071cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 25081cbb95d3SBarry Smith 25091cbb95d3SBarry Smith *f = PETSC_TRUE; 25101cbb95d3SBarry Smith for (i=0; i<ma; i++) { 25111cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 25121cbb95d3SBarry Smith PetscInt idc,idr; 25131cbb95d3SBarry Smith PetscScalar vc,vr; 25141cbb95d3SBarry Smith /* column/row index/value */ 25151cbb95d3SBarry Smith idc = adx[aptr[i]]; 25161cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 25171cbb95d3SBarry Smith vc = va[aptr[i]]; 25181cbb95d3SBarry Smith vr = vb[bptr[idc]]; 25191cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 25201cbb95d3SBarry Smith *f = PETSC_FALSE; 25211cbb95d3SBarry Smith goto done; 25221cbb95d3SBarry Smith } else { 25231cbb95d3SBarry Smith aptr[i]++; 25241cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 25251cbb95d3SBarry Smith } 25261cbb95d3SBarry Smith } 25271cbb95d3SBarry Smith } 25281cbb95d3SBarry Smith done: 25291cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 25301cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 25311cbb95d3SBarry Smith PetscFunctionReturn(0); 25321cbb95d3SBarry Smith } 25331cbb95d3SBarry Smith 2534ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25359e29f15eSvictorle { 2536dfbe8321SBarry Smith PetscErrorCode ierr; 25376e111a19SKarl Rupp 25389e29f15eSvictorle PetscFunctionBegin; 25395485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25409e29f15eSvictorle PetscFunctionReturn(0); 25419e29f15eSvictorle } 25429e29f15eSvictorle 2543ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25441cbb95d3SBarry Smith { 25451cbb95d3SBarry Smith PetscErrorCode ierr; 25466e111a19SKarl Rupp 25471cbb95d3SBarry Smith PetscFunctionBegin; 25481cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25491cbb95d3SBarry Smith PetscFunctionReturn(0); 25501cbb95d3SBarry Smith } 25511cbb95d3SBarry Smith 2552dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 255317ab2063SBarry Smith { 2554416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2555fff8e43fSBarry Smith const PetscScalar *l,*r; 2556fff8e43fSBarry Smith PetscScalar x; 255754f21887SBarry Smith MatScalar *v; 2558dfbe8321SBarry Smith PetscErrorCode ierr; 2559fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2560fff8e43fSBarry Smith const PetscInt *jj; 256117ab2063SBarry Smith 25623a40ed3dSBarry Smith PetscFunctionBegin; 256317ab2063SBarry Smith if (ll) { 25643ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 25653ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2566e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2567e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2568fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 25692e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 257017ab2063SBarry Smith for (i=0; i<m; i++) { 257117ab2063SBarry Smith x = l[i]; 2572416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 25732205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 257417ab2063SBarry Smith } 2575fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2576efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 25772e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 257817ab2063SBarry Smith } 257917ab2063SBarry Smith if (rr) { 2580e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2581e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2582fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 25832e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 25842e5835c6SStefano Zampini jj = a->j; 25852205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 25862e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 2587fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2588efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 258917ab2063SBarry Smith } 2590acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 25918c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2592c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2593e2cf4d64SStefano Zampini #endif 25943a40ed3dSBarry Smith PetscFunctionReturn(0); 259517ab2063SBarry Smith } 259617ab2063SBarry Smith 25977dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 259817ab2063SBarry Smith { 2599db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 26006849ba73SBarry Smith PetscErrorCode ierr; 2601d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 260297f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 26035d0c19d7SBarry Smith const PetscInt *irow,*icol; 26042e5835c6SStefano Zampini const PetscScalar *aa; 26055d0c19d7SBarry Smith PetscInt nrows,ncols; 260697f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 260754f21887SBarry Smith MatScalar *a_new,*mat_a; 2608416022c9SBarry Smith Mat C; 2609cdc6f3adSToby Isaac PetscBool stride; 261017ab2063SBarry Smith 26113a40ed3dSBarry Smith PetscFunctionBegin; 261217ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2613b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2614b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 261517ab2063SBarry Smith 2616251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2617ff718158SBarry Smith if (stride) { 2618ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2619ff718158SBarry Smith } else { 2620ff718158SBarry Smith first = 0; 2621ff718158SBarry Smith step = 0; 2622ff718158SBarry Smith } 2623fee21e36SBarry Smith if (stride && step == 1) { 262402834360SBarry Smith /* special case of contiguous rows */ 2625dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 262602834360SBarry Smith /* loop over new rows determining lens and starting points */ 262702834360SBarry Smith for (i=0; i<nrows; i++) { 2628bfeeae90SHong Zhang kstart = ai[irow[i]]; 2629a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2630a91a9bebSLisandro Dalcin starts[i] = kstart; 263102834360SBarry Smith for (k=kstart; k<kend; k++) { 2632bfeeae90SHong Zhang if (aj[k] >= first) { 263302834360SBarry Smith starts[i] = k; 263402834360SBarry Smith break; 263502834360SBarry Smith } 263602834360SBarry Smith } 2637a2744918SBarry Smith sum = 0; 263802834360SBarry Smith while (k < kend) { 2639bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2640a2744918SBarry Smith sum++; 264102834360SBarry Smith } 2642a2744918SBarry Smith lens[i] = sum; 264302834360SBarry Smith } 264402834360SBarry Smith /* create submatrix */ 2645cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 264697f1f81fSBarry Smith PetscInt n_cols,n_rows; 264708480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2648e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2649d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 265008480c60SBarry Smith C = *B; 26513a40ed3dSBarry Smith } else { 26523bef6203SJed Brown PetscInt rbs,cbs; 2653ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2654f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 26553bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 26563bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 26573bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 26587adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2659ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 266008480c60SBarry Smith } 2661db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2662db02288aSLois Curfman McInnes 266302834360SBarry Smith /* loop over rows inserting into submatrix */ 2664db02288aSLois Curfman McInnes a_new = c->a; 2665db02288aSLois Curfman McInnes j_new = c->j; 2666db02288aSLois Curfman McInnes i_new = c->i; 26672e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 266802834360SBarry Smith for (i=0; i<nrows; i++) { 2669a2744918SBarry Smith ii = starts[i]; 2670a2744918SBarry Smith lensi = lens[i]; 2671a2744918SBarry Smith for (k=0; k<lensi; k++) { 2672a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 267302834360SBarry Smith } 26742e5835c6SStefano Zampini ierr = PetscArraycpy(a_new,aa + starts[i],lensi);CHKERRQ(ierr); 2675a2744918SBarry Smith a_new += lensi; 2676a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2677a2744918SBarry Smith c->ilen[i] = lensi; 267802834360SBarry Smith } 26792e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 26800e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 26813a40ed3dSBarry Smith } else { 268202834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 26831795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2684854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 26854dcab191SBarry Smith for (i=0; i<ncols; i++) { 2686d9ef940eSSatish 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); 26874dcab191SBarry Smith smap[icol[i]] = i+1; 26884dcab191SBarry Smith } 26894dcab191SBarry Smith 269002834360SBarry Smith /* determine lens of each row */ 269102834360SBarry Smith for (i=0; i<nrows; i++) { 2692bfeeae90SHong Zhang kstart = ai[irow[i]]; 269302834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 269402834360SBarry Smith lens[i] = 0; 269502834360SBarry Smith for (k=kstart; k<kend; k++) { 2696bfeeae90SHong Zhang if (smap[aj[k]]) { 269702834360SBarry Smith lens[i]++; 269802834360SBarry Smith } 269902834360SBarry Smith } 270002834360SBarry Smith } 270117ab2063SBarry Smith /* Create and fill new matrix */ 2702a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2703ace3abfcSBarry Smith PetscBool equal; 27040f5bd95cSBarry Smith 270599141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2706e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2707580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2708f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2709580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 271008480c60SBarry Smith C = *B; 27113a40ed3dSBarry Smith } else { 27123bef6203SJed Brown PetscInt rbs,cbs; 2713ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2714f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 27153bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 27163bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 27173bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 27187adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2719ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 272008480c60SBarry Smith } 27212e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 272299141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 272317ab2063SBarry Smith for (i=0; i<nrows; i++) { 272499141d43SSatish Balay row = irow[i]; 2725bfeeae90SHong Zhang kstart = ai[row]; 272699141d43SSatish Balay kend = kstart + a->ilen[row]; 2727bfeeae90SHong Zhang mat_i = c->i[i]; 272899141d43SSatish Balay mat_j = c->j + mat_i; 272999141d43SSatish Balay mat_a = c->a + mat_i; 273099141d43SSatish Balay mat_ilen = c->ilen + i; 273117ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2732bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2733ed480e8bSBarry Smith *mat_j++ = tcol - 1; 27342e5835c6SStefano Zampini *mat_a++ = aa[k]; 273599141d43SSatish Balay (*mat_ilen)++; 273699141d43SSatish Balay 273717ab2063SBarry Smith } 273817ab2063SBarry Smith } 273917ab2063SBarry Smith } 27402e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 274102834360SBarry Smith /* Free work space */ 274202834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2743606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2744606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2745cdc6f3adSToby Isaac /* sort */ 2746cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2747cdc6f3adSToby Isaac PetscInt ilen; 2748cdc6f3adSToby Isaac 2749cdc6f3adSToby Isaac mat_i = c->i[i]; 2750cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2751cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2752cdc6f3adSToby Isaac ilen = c->ilen[i]; 2753390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2754cdc6f3adSToby Isaac } 275502834360SBarry Smith } 27568c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2757b470e4b4SRichard Tran Mills ierr = MatBindToCPU(C,A->boundtocpu);CHKERRQ(ierr); 2758305c6ccfSStefano Zampini #endif 27596d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27606d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 276117ab2063SBarry Smith 276217ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2763416022c9SBarry Smith *B = C; 27643a40ed3dSBarry Smith PetscFunctionReturn(0); 276517ab2063SBarry Smith } 276617ab2063SBarry Smith 2767fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 276882d44351SHong Zhang { 276982d44351SHong Zhang PetscErrorCode ierr; 277082d44351SHong Zhang Mat B; 277182d44351SHong Zhang 277282d44351SHong Zhang PetscFunctionBegin; 2773c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 277482d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 277582d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 277633d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 277782d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 277882d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 277982d44351SHong Zhang *subMat = B; 2780c2d650bdSHong Zhang } else { 2781c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2782c2d650bdSHong Zhang } 278382d44351SHong Zhang PetscFunctionReturn(0); 278482d44351SHong Zhang } 278582d44351SHong Zhang 27869a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2787a871dcd8SBarry Smith { 278863b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2789dfbe8321SBarry Smith PetscErrorCode ierr; 279063b91edcSBarry Smith Mat outA; 2791ace3abfcSBarry Smith PetscBool row_identity,col_identity; 279263b91edcSBarry Smith 27933a40ed3dSBarry Smith PetscFunctionBegin; 2794e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 27951df811f5SHong Zhang 2796b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2797b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2798a871dcd8SBarry Smith 279963b91edcSBarry Smith outA = inA; 2800d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2801f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2802f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 28032205254eSKarl Rupp 2804c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 28056bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 28062205254eSKarl Rupp 2807c3122656SLisandro Dalcin a->row = row; 28082205254eSKarl Rupp 2809c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 28106bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 28112205254eSKarl Rupp 2812c3122656SLisandro Dalcin a->col = col; 281363b91edcSBarry Smith 281436db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 28156bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 28164c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 28173bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2818f0ec6fceSSatish Balay 281994a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2820854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 28213bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 282294a9d846SBarry Smith } 282363b91edcSBarry Smith 2824f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2825137fb511SHong Zhang if (row_identity && col_identity) { 2826ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2827137fb511SHong Zhang } else { 2828719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2829137fb511SHong Zhang } 28303a40ed3dSBarry Smith PetscFunctionReturn(0); 2831a871dcd8SBarry Smith } 2832a871dcd8SBarry Smith 2833f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2834f0b747eeSBarry Smith { 2835f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2836*dfa0f9e5SStefano Zampini PetscScalar *v; 2837efee365bSSatish Balay PetscErrorCode ierr; 2838c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 28393a40ed3dSBarry Smith 28403a40ed3dSBarry Smith PetscFunctionBegin; 2841*dfa0f9e5SStefano Zampini ierr = MatSeqAIJGetArray(inA,&v);CHKERRQ(ierr); 2842c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 2843*dfa0f9e5SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&alpha,v,&one)); 2844efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2845*dfa0f9e5SStefano Zampini ierr = MatSeqAIJRestoreArray(inA,&v);CHKERRQ(ierr); 2846acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 28473a40ed3dSBarry Smith PetscFunctionReturn(0); 2848f0b747eeSBarry Smith } 2849f0b747eeSBarry Smith 2850f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 285116b64355SHong Zhang { 285216b64355SHong Zhang PetscErrorCode ierr; 285316b64355SHong Zhang PetscInt i; 285416b64355SHong Zhang 285516b64355SHong Zhang PetscFunctionBegin; 285616b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 285716b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 285816b64355SHong Zhang 285916b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 286016b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 286116b64355SHong Zhang } 286216b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 286316b64355SHong Zhang 286416b64355SHong Zhang if (submatj->rbuf1) { 286516b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 286616b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 286716b64355SHong Zhang } 286816b64355SHong Zhang 286916b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 287016b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 287116b64355SHong Zhang } 287216b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 287316b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 287416b64355SHong Zhang } 287516b64355SHong Zhang 287616b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 287716b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 287816b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 287916b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 288016b64355SHong Zhang #else 288116b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 288216b64355SHong Zhang #endif 288316b64355SHong Zhang 288416b64355SHong Zhang if (!submatj->allcolumns) { 288516b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 288616b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 288716b64355SHong Zhang #else 288816b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 288916b64355SHong Zhang #endif 289016b64355SHong Zhang } 289116b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 289216b64355SHong Zhang 289316b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 289416b64355SHong Zhang PetscFunctionReturn(0); 289516b64355SHong Zhang } 289616b64355SHong Zhang 28970fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 289816b64355SHong Zhang { 289916b64355SHong Zhang PetscErrorCode ierr; 290016b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 29015c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 290216b64355SHong Zhang 290316b64355SHong Zhang PetscFunctionBegin; 290434136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2905f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 290616b64355SHong Zhang PetscFunctionReturn(0); 290716b64355SHong Zhang } 290816b64355SHong Zhang 29092d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 29102d033e1fSHong Zhang { 29112d033e1fSHong Zhang PetscErrorCode ierr; 29122d033e1fSHong Zhang PetscInt i; 29130fb991dcSHong Zhang Mat C; 29140fb991dcSHong Zhang Mat_SeqAIJ *c; 29150fb991dcSHong Zhang Mat_SubSppt *submatj; 29162d033e1fSHong Zhang 29172d033e1fSHong Zhang PetscFunctionBegin; 29182d033e1fSHong Zhang for (i=0; i<n; i++) { 29190fb991dcSHong Zhang C = (*mat)[i]; 29200fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 29210fb991dcSHong Zhang submatj = c->submatis1; 29222d033e1fSHong Zhang if (submatj) { 2923682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 292434136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2925f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 292634136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 29272d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 29282d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 29292d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2930682e4c99SStefano Zampini } 29312d033e1fSHong Zhang } else { 29322d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 29332d033e1fSHong Zhang } 29342d033e1fSHong Zhang } 293586e85357SHong Zhang 293663a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 293763a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 293863a75b2aSHong Zhang 29392d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 29402d033e1fSHong Zhang PetscFunctionReturn(0); 29412d033e1fSHong Zhang } 29422d033e1fSHong Zhang 29437dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2944cddf8d76SBarry Smith { 2945dfbe8321SBarry Smith PetscErrorCode ierr; 294697f1f81fSBarry Smith PetscInt i; 2947cddf8d76SBarry Smith 29483a40ed3dSBarry Smith PetscFunctionBegin; 2949cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2950df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2951cddf8d76SBarry Smith } 2952cddf8d76SBarry Smith 2953cddf8d76SBarry Smith for (i=0; i<n; i++) { 29547dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2955cddf8d76SBarry Smith } 29563a40ed3dSBarry Smith PetscFunctionReturn(0); 2957cddf8d76SBarry Smith } 2958cddf8d76SBarry Smith 295997f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 29604dcbc457SBarry Smith { 2961e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29626849ba73SBarry Smith PetscErrorCode ierr; 29635d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 29645d0c19d7SBarry Smith const PetscInt *idx; 296597f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2966f1af5d2fSBarry Smith PetscBT table; 2967bbd702dbSSatish Balay 29683a40ed3dSBarry Smith PetscFunctionBegin; 2969d0f46423SBarry Smith m = A->rmap->n; 2970e4d965acSSatish Balay ai = a->i; 2971bfeeae90SHong Zhang aj = a->j; 29728a047759SSatish Balay 2973e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 297406763907SSatish Balay 2975854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 297653b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 297706763907SSatish Balay 2978e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2979b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2980e4d965acSSatish Balay isz = 0; 29816831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2982e4d965acSSatish Balay 2983e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 29844dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2985b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2986e4d965acSSatish Balay 2987dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2988e4d965acSSatish Balay for (j=0; j<n; ++j) { 29892205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 29904dcbc457SBarry Smith } 299106763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 29926bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2993e4d965acSSatish Balay 299404a348a9SBarry Smith k = 0; 299504a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 299604a348a9SBarry Smith n = isz; 299706763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2998e4d965acSSatish Balay row = nidx[k]; 2999e4d965acSSatish Balay start = ai[row]; 3000e4d965acSSatish Balay end = ai[row+1]; 300104a348a9SBarry Smith for (l = start; l<end; l++) { 3002efb16452SHong Zhang val = aj[l]; 30032205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 3004e4d965acSSatish Balay } 3005e4d965acSSatish Balay } 3006e4d965acSSatish Balay } 300770b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 3008e4d965acSSatish Balay } 300994bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 3010606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 30113a40ed3dSBarry Smith PetscFunctionReturn(0); 30124dcbc457SBarry Smith } 301317ab2063SBarry Smith 30140513a670SBarry Smith /* -------------------------------------------------------------- */ 3015dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 30160513a670SBarry Smith { 30170513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 30186849ba73SBarry Smith PetscErrorCode ierr; 30193b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 30205d0c19d7SBarry Smith const PetscInt *row,*col; 30215d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 302256cd22aeSBarry Smith IS icolp,irowp; 30230298fd71SBarry Smith PetscInt *cwork = NULL; 30240298fd71SBarry Smith PetscScalar *vwork = NULL; 30250513a670SBarry Smith 30263a40ed3dSBarry Smith PetscFunctionBegin; 30274c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 302856cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 30294c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 303056cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 30310513a670SBarry Smith 30320513a670SBarry Smith /* determine lengths of permuted rows */ 3033854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 30342205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 3035ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 3036f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 303733d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 30387adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 3039ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 3040606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 30410513a670SBarry Smith 3042785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 30430513a670SBarry Smith for (i=0; i<m; i++) { 304432ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30452205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 3046cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 304732ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30480513a670SBarry Smith } 3049606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 30502205254eSKarl Rupp 30513c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 30522205254eSKarl Rupp 30538c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3054b470e4b4SRichard Tran Mills ierr = MatBindToCPU(*B,A->boundtocpu);CHKERRQ(ierr); 30559fe5e383SStefano Zampini #endif 30560513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30570513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 305856cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 305956cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 30606bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 30616bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 30626768869dSprj- if (rowp == colp) { 30636768869dSprj- if (A->symmetric) { 30646768869dSprj- ierr = MatSetOption(*B,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 30656768869dSprj- } 30666768869dSprj- if (A->hermitian) { 30676768869dSprj- ierr = MatSetOption(*B,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 30686768869dSprj- } 30696768869dSprj- } 30703a40ed3dSBarry Smith PetscFunctionReturn(0); 30710513a670SBarry Smith } 30720513a670SBarry Smith 3073dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 3074cb5b572fSBarry Smith { 3075dfbe8321SBarry Smith PetscErrorCode ierr; 3076cb5b572fSBarry Smith 3077cb5b572fSBarry Smith PetscFunctionBegin; 307833f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 307933f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 3080be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3081be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 30822e5835c6SStefano Zampini const PetscScalar *aa; 3083be6bf707SBarry Smith 30842e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 30854d805d7cSStefano 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]); 30862e5835c6SStefano Zampini ierr = PetscArraycpy(b->a,aa,a->i[A->rmap->n]);CHKERRQ(ierr); 3087cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 30882e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 3089cb5b572fSBarry Smith } else { 3090cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3091cb5b572fSBarry Smith } 3092cb5b572fSBarry Smith PetscFunctionReturn(0); 3093cb5b572fSBarry Smith } 3094cb5b572fSBarry Smith 30954994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 3096273d9f13SBarry Smith { 3097dfbe8321SBarry Smith PetscErrorCode ierr; 3098273d9f13SBarry Smith 3099273d9f13SBarry Smith PetscFunctionBegin; 3100f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 3101273d9f13SBarry Smith PetscFunctionReturn(0); 3102273d9f13SBarry Smith } 3103273d9f13SBarry Smith 3104f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 31056c0721eeSBarry Smith { 31066c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 31076e111a19SKarl Rupp 31086c0721eeSBarry Smith PetscFunctionBegin; 31096c0721eeSBarry Smith *array = a->a; 31106c0721eeSBarry Smith PetscFunctionReturn(0); 31116c0721eeSBarry Smith } 31126c0721eeSBarry Smith 3113f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 31146c0721eeSBarry Smith { 31156c0721eeSBarry Smith PetscFunctionBegin; 3116f38c1e66SStefano Zampini *array = NULL; 31176c0721eeSBarry Smith PetscFunctionReturn(0); 31186c0721eeSBarry Smith } 3119273d9f13SBarry Smith 31208229c054SShri Abhyankar /* 31218229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 31228229c054SShri Abhyankar have different nonzero structure. 31238229c054SShri Abhyankar */ 3124b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 3125ec7775f6SShri Abhyankar { 3126b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 3127ec7775f6SShri Abhyankar 3128ec7775f6SShri Abhyankar PetscFunctionBegin; 3129ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 3130ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 3131b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 3132b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 3133b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 31348af7cee1SJed Brown nnz[i] = 0; 31358af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 3136b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 3137b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 31388af7cee1SJed Brown nnz[i]++; 31398af7cee1SJed Brown } 31408af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 3141ec7775f6SShri Abhyankar } 3142ec7775f6SShri Abhyankar PetscFunctionReturn(0); 3143ec7775f6SShri Abhyankar } 3144ec7775f6SShri Abhyankar 3145b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 3146b264fe52SHong Zhang { 3147b264fe52SHong Zhang PetscInt m = Y->rmap->N; 3148b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 3149b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 3150b264fe52SHong Zhang PetscErrorCode ierr; 3151b264fe52SHong Zhang 3152b264fe52SHong Zhang PetscFunctionBegin; 3153b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 3154b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 3155b264fe52SHong Zhang PetscFunctionReturn(0); 3156b264fe52SHong Zhang } 3157b264fe52SHong Zhang 3158f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 3159ac90fabeSBarry Smith { 3160dfbe8321SBarry Smith PetscErrorCode ierr; 3161ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 3162ac90fabeSBarry Smith 3163ac90fabeSBarry Smith PetscFunctionBegin; 316441f5e1b1SStefano Zampini if (str == UNKNOWN_NONZERO_PATTERN && x->nz == y->nz) { 316581fa06acSBarry Smith PetscBool e; 316681fa06acSBarry Smith ierr = PetscArraycmp(x->i,y->i,Y->rmap->n+1,&e);CHKERRQ(ierr); 316781fa06acSBarry Smith if (e) { 316881fa06acSBarry Smith ierr = PetscArraycmp(x->j,y->j,y->nz,&e);CHKERRQ(ierr); 316981fa06acSBarry Smith if (e) { 317081fa06acSBarry Smith str = SAME_NONZERO_PATTERN; 317181fa06acSBarry Smith } 317281fa06acSBarry Smith } 317381fa06acSBarry Smith } 3174ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 31752e5835c6SStefano Zampini const PetscScalar *xa; 31762e5835c6SStefano Zampini PetscScalar *ya,alpha = a; 317781fa06acSBarry Smith PetscBLASInt one = 1,bnz; 317881fa06acSBarry Smith 317981fa06acSBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 31802e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(Y,&ya);CHKERRQ(ierr); 31812e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(X,&xa);CHKERRQ(ierr); 31822e5835c6SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,xa,&one,ya,&one)); 31832e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(X,&xa);CHKERRQ(ierr); 31842e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(Y,&ya);CHKERRQ(ierr); 318541f5e1b1SStefano Zampini ierr = PetscLogFlops(2.0*bnz);CHKERRQ(ierr); 3186acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 3187a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 318881fa06acSBarry Smith /* the MatAXPY_Basic* subroutines calls MatAssembly, so the matrix on the GPU will be updated */ 31898c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 319041f5e1b1SStefano Zampini if (Y->offloadmask != PETSC_OFFLOAD_UNALLOCATED) Y->offloadmask = PETSC_OFFLOAD_CPU; 3191e2cf4d64SStefano Zampini #endif 3192ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 3193ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 3194ac90fabeSBarry Smith } else { 31958229c054SShri Abhyankar Mat B; 31968229c054SShri Abhyankar PetscInt *nnz; 3197785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 3198ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 3199bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 320081fa06acSBarry Smith ierr = MatSetLayouts(B,Y->rmap,Y->cmap);CHKERRQ(ierr); 32012e5835c6SStefano Zampini ierr = MatSetType(B,((PetscObject)Y)->type_name);CHKERRQ(ierr); 32028229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 3203ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 3204ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 320528be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 32068229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 3207ac90fabeSBarry Smith } 3208ac90fabeSBarry Smith PetscFunctionReturn(0); 3209ac90fabeSBarry Smith } 3210ac90fabeSBarry Smith 32117087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3212354c94deSBarry Smith { 3213354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3214354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3215354c94deSBarry Smith PetscInt i,nz; 3216354c94deSBarry Smith PetscScalar *a; 3217354c94deSBarry Smith 3218354c94deSBarry Smith PetscFunctionBegin; 3219354c94deSBarry Smith nz = aij->nz; 3220354c94deSBarry Smith a = aij->a; 32212205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 32228c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3223c70f7ee4SJunchao Zhang if (mat->offloadmask != PETSC_OFFLOAD_UNALLOCATED) mat->offloadmask = PETSC_OFFLOAD_CPU; 3224e2cf4d64SStefano Zampini #endif 3225354c94deSBarry Smith #else 3226354c94deSBarry Smith PetscFunctionBegin; 3227354c94deSBarry Smith #endif 3228354c94deSBarry Smith PetscFunctionReturn(0); 3229354c94deSBarry Smith } 3230354c94deSBarry Smith 3231985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3232e34fafa9SBarry Smith { 3233e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3234e34fafa9SBarry Smith PetscErrorCode ierr; 3235d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3236e34fafa9SBarry Smith PetscReal atmp; 3237985db425SBarry Smith PetscScalar *x; 3238e34fafa9SBarry Smith MatScalar *aa; 3239e34fafa9SBarry Smith 3240e34fafa9SBarry Smith PetscFunctionBegin; 3241e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3242e34fafa9SBarry Smith aa = a->a; 3243e34fafa9SBarry Smith ai = a->i; 3244e34fafa9SBarry Smith aj = a->j; 3245e34fafa9SBarry Smith 3246985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3247475b8b61SHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3248e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3249e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3250e34fafa9SBarry Smith for (i=0; i<m; i++) { 3251e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 3252e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3253985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3254985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3255985db425SBarry Smith aa++; aj++; 3256985db425SBarry Smith } 3257985db425SBarry Smith } 3258475b8b61SHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3259985db425SBarry Smith PetscFunctionReturn(0); 3260985db425SBarry Smith } 3261985db425SBarry Smith 3262985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3263985db425SBarry Smith { 3264985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3265985db425SBarry Smith PetscErrorCode ierr; 3266d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3267985db425SBarry Smith PetscScalar *x; 3268985db425SBarry Smith MatScalar *aa; 3269985db425SBarry Smith 3270985db425SBarry Smith PetscFunctionBegin; 3271e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3272985db425SBarry Smith aa = a->a; 3273985db425SBarry Smith ai = a->i; 3274985db425SBarry Smith aj = a->j; 3275985db425SBarry Smith 3276985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3277fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3278985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3279e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3280985db425SBarry Smith for (i=0; i<m; i++) { 3281985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3282d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3283985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3284985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3285985db425SBarry Smith x[i] = 0.0; 3286985db425SBarry Smith if (idx) { 3287985db425SBarry Smith for (j=0; j<ncols; j++) { /* find first implicit 0.0 in the row */ 3288985db425SBarry Smith if (aj[j] > j) { 3289985db425SBarry Smith idx[i] = j; 3290985db425SBarry Smith break; 3291985db425SBarry Smith } 3292985db425SBarry Smith } 32931a254869SHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 32941a254869SHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3295985db425SBarry Smith } 3296985db425SBarry Smith } 3297985db425SBarry Smith for (j=0; j<ncols; j++) { 3298985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3299985db425SBarry Smith aa++; aj++; 3300985db425SBarry Smith } 3301985db425SBarry Smith } 3302fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3303985db425SBarry Smith PetscFunctionReturn(0); 3304985db425SBarry Smith } 3305985db425SBarry Smith 3306c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3307c87e5d42SMatthew Knepley { 3308c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3309c87e5d42SMatthew Knepley PetscErrorCode ierr; 3310c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 33114e879edeSHong Zhang PetscScalar *x,*aa; 3312c87e5d42SMatthew Knepley 3313c87e5d42SMatthew Knepley PetscFunctionBegin; 3314c87e5d42SMatthew Knepley aa = a->a; 3315c87e5d42SMatthew Knepley ai = a->i; 3316c87e5d42SMatthew Knepley aj = a->j; 3317c87e5d42SMatthew Knepley 3318c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3319f07e67edSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3320c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3321f07e67edSHong Zhang if (n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %D vs. %D rows", m, n); 3322c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3323c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3324f07e67edSHong Zhang if (ncols == A->cmap->n) { /* row is dense */ 3325f07e67edSHong Zhang x[i] = *aa; if (idx) idx[i] = 0; 3326f07e67edSHong Zhang } else { /* row is sparse so already KNOW minimum is 0.0 or higher */ 3327f07e67edSHong Zhang x[i] = 0.0; 3328f07e67edSHong Zhang if (idx) { /* find first implicit 0.0 in the row */ 3329289a08f5SMatthew Knepley for (j=0; j<ncols; j++) { 3330f07e67edSHong Zhang if (aj[j] > j) { 3331f07e67edSHong Zhang idx[i] = j; 33322205254eSKarl Rupp break; 33332205254eSKarl Rupp } 3334289a08f5SMatthew Knepley } 3335f07e67edSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3336f07e67edSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3337f07e67edSHong Zhang } 3338289a08f5SMatthew Knepley } 3339c87e5d42SMatthew Knepley for (j=0; j<ncols; j++) { 3340f07e67edSHong Zhang if (PetscAbsScalar(x[i]) > PetscAbsScalar(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3341c87e5d42SMatthew Knepley aa++; aj++; 3342c87e5d42SMatthew Knepley } 3343c87e5d42SMatthew Knepley } 3344f07e67edSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3345c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3346c87e5d42SMatthew Knepley } 3347c87e5d42SMatthew Knepley 3348985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3349985db425SBarry Smith { 3350985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3351985db425SBarry Smith PetscErrorCode ierr; 3352d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3353d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3354985db425SBarry Smith PetscScalar *x; 3355d9ca1df4SBarry Smith const MatScalar *aa; 3356985db425SBarry Smith 3357985db425SBarry Smith PetscFunctionBegin; 3358e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3359985db425SBarry Smith aa = a->a; 3360985db425SBarry Smith ai = a->i; 3361985db425SBarry Smith aj = a->j; 3362985db425SBarry Smith 3363985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3364fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3365985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3366f07e67edSHong Zhang if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3367985db425SBarry Smith for (i=0; i<m; i++) { 3368985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3369d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3370985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3371985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3372985db425SBarry Smith x[i] = 0.0; 3373985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3374985db425SBarry Smith for (j=0; j<ncols; j++) { 3375985db425SBarry Smith if (aj[j] > j) { 3376985db425SBarry Smith idx[i] = j; 3377985db425SBarry Smith break; 3378985db425SBarry Smith } 3379985db425SBarry Smith } 3380fa213d2fSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3381fa213d2fSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3382985db425SBarry Smith } 3383985db425SBarry Smith } 3384985db425SBarry Smith for (j=0; j<ncols; j++) { 3385985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3386985db425SBarry Smith aa++; aj++; 3387e34fafa9SBarry Smith } 3388e34fafa9SBarry Smith } 3389fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3390e34fafa9SBarry Smith PetscFunctionReturn(0); 3391e34fafa9SBarry Smith } 3392bbead8a2SBarry Smith 3393713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3394bbead8a2SBarry Smith { 3395bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3396bbead8a2SBarry Smith PetscErrorCode ierr; 339733d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3398bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 33990da83c2eSBarry Smith const PetscReal shift = 0.0; 34001a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3401bbead8a2SBarry Smith 3402bbead8a2SBarry Smith PetscFunctionBegin; 3403a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 34044a0d0026SBarry Smith if (a->ibdiagvalid) { 34054a0d0026SBarry Smith if (values) *values = a->ibdiag; 34064a0d0026SBarry Smith PetscFunctionReturn(0); 34074a0d0026SBarry Smith } 3408bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3409bbead8a2SBarry Smith if (!a->ibdiag) { 3410785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 34113bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3412bbead8a2SBarry Smith } 3413bbead8a2SBarry Smith diag = a->ibdiag; 3414bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3415bbead8a2SBarry Smith /* factor and invert each block */ 3416bbead8a2SBarry Smith switch (bs) { 3417bbead8a2SBarry Smith case 1: 3418bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3419bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3420ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3421ec1892c8SHong Zhang if (allowzeropivot) { 34227b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 34237b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 34247b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 34257b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 34267b6c816cSBarry 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); 3427ec1892c8SHong Zhang } 3428bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3429bbead8a2SBarry Smith } 3430bbead8a2SBarry Smith break; 3431bbead8a2SBarry Smith case 2: 3432bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3433bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3434bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3435a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34367b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 343796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3438bbead8a2SBarry Smith diag += 4; 3439bbead8a2SBarry Smith } 3440bbead8a2SBarry Smith break; 3441bbead8a2SBarry Smith case 3: 3442bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3443bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3444bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3445a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34467b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 344796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3448bbead8a2SBarry Smith diag += 9; 3449bbead8a2SBarry Smith } 3450bbead8a2SBarry Smith break; 3451bbead8a2SBarry Smith case 4: 3452bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3453bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3454bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3455a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34567b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 345796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3458bbead8a2SBarry Smith diag += 16; 3459bbead8a2SBarry Smith } 3460bbead8a2SBarry Smith break; 3461bbead8a2SBarry Smith case 5: 3462bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3463bbead8a2SBarry 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; 3464bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3465a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34667b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 346796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3468bbead8a2SBarry Smith diag += 25; 3469bbead8a2SBarry Smith } 3470bbead8a2SBarry Smith break; 3471bbead8a2SBarry Smith case 6: 3472bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3473bbead8a2SBarry 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; 3474bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3475a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34767b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 347796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3478bbead8a2SBarry Smith diag += 36; 3479bbead8a2SBarry Smith } 3480bbead8a2SBarry Smith break; 3481bbead8a2SBarry Smith case 7: 3482bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3483bbead8a2SBarry 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; 3484bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3485a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34867b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 348796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3488bbead8a2SBarry Smith diag += 49; 3489bbead8a2SBarry Smith } 3490bbead8a2SBarry Smith break; 3491bbead8a2SBarry Smith default: 3492dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3493bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3494bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3495bbead8a2SBarry Smith IJ[j] = bs*i + j; 3496bbead8a2SBarry Smith } 3497bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 34985f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34997b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 350096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3501bbead8a2SBarry Smith diag += bs2; 3502bbead8a2SBarry Smith } 3503bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3504bbead8a2SBarry Smith } 3505bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3506bbead8a2SBarry Smith PetscFunctionReturn(0); 3507bbead8a2SBarry Smith } 3508bbead8a2SBarry Smith 350973a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 351073a71a0fSBarry Smith { 351173a71a0fSBarry Smith PetscErrorCode ierr; 351273a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 351373a71a0fSBarry Smith PetscScalar a; 351473a71a0fSBarry Smith PetscInt m,n,i,j,col; 351573a71a0fSBarry Smith 351673a71a0fSBarry Smith PetscFunctionBegin; 351773a71a0fSBarry Smith if (!x->assembled) { 351873a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 351973a71a0fSBarry Smith for (i=0; i<m; i++) { 352073a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 352173a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 352273a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 352373a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 352473a71a0fSBarry Smith } 352573a71a0fSBarry Smith } 3526e2ce353bSJunchao Zhang } else { 3527e2ce353bSJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aij->a+i);CHKERRQ(ierr);} 3528e2ce353bSJunchao Zhang } 352973a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 353073a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 353173a71a0fSBarry Smith PetscFunctionReturn(0); 353273a71a0fSBarry Smith } 353373a71a0fSBarry Smith 3534679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3535679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3536679944adSJunchao Zhang { 3537679944adSJunchao Zhang PetscErrorCode ierr; 3538679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3539679944adSJunchao Zhang PetscScalar a; 3540679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3541679944adSJunchao Zhang 3542679944adSJunchao Zhang PetscFunctionBegin; 3543679944adSJunchao Zhang nskip = high - low; 3544679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3545679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3546679944adSJunchao Zhang for (i=0; i<m; i++) { 3547679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3548679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3549679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3550679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3551679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3552679944adSJunchao Zhang } 3553e2ce353bSJunchao Zhang } 3554679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3555679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3556679944adSJunchao Zhang PetscFunctionReturn(0); 3557679944adSJunchao Zhang } 3558679944adSJunchao Zhang 3559679944adSJunchao Zhang 3560682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 35610a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3562cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3563cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3564cb5b572fSBarry Smith MatMult_SeqAIJ, 356597304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 35667c922b88SBarry Smith MatMultTranspose_SeqAIJ, 35677c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3568f4259b30SLisandro Dalcin NULL, 3569f4259b30SLisandro Dalcin NULL, 3570f4259b30SLisandro Dalcin NULL, 3571f4259b30SLisandro Dalcin /* 10*/ NULL, 3572cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3573f4259b30SLisandro Dalcin NULL, 357441f059aeSBarry Smith MatSOR_SeqAIJ, 357591e9d3e2SHong Zhang MatTranspose_SeqAIJ, 357697304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3577cb5b572fSBarry Smith MatEqual_SeqAIJ, 3578cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3579cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3580cb5b572fSBarry Smith MatNorm_SeqAIJ, 3581f4259b30SLisandro Dalcin /* 20*/ NULL, 3582cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3583cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3584cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3585d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3586f4259b30SLisandro Dalcin NULL, 3587f4259b30SLisandro Dalcin NULL, 3588f4259b30SLisandro Dalcin NULL, 3589f4259b30SLisandro Dalcin NULL, 35904994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3591f4259b30SLisandro Dalcin NULL, 3592f4259b30SLisandro Dalcin NULL, 3593f4259b30SLisandro Dalcin NULL, 3594f4259b30SLisandro Dalcin NULL, 3595d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3596f4259b30SLisandro Dalcin NULL, 3597f4259b30SLisandro Dalcin NULL, 3598cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3599f4259b30SLisandro Dalcin NULL, 3600d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 36017dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3602cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3603cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3604cb5b572fSBarry Smith MatCopy_SeqAIJ, 3605d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3606cb5b572fSBarry Smith MatScale_SeqAIJ, 36077d68702bSBarry Smith MatShift_SeqAIJ, 360879299369SBarry Smith MatDiagonalSet_SeqAIJ, 36096e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 361073a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 36113b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 36123b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 36133b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3614a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 361593dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3616f4259b30SLisandro Dalcin NULL, 3617f4259b30SLisandro Dalcin NULL, 3618cda55fadSBarry Smith MatPermute_SeqAIJ, 3619f4259b30SLisandro Dalcin NULL, 3620f4259b30SLisandro Dalcin /* 59*/ NULL, 3621b9b97703SBarry Smith MatDestroy_SeqAIJ, 3622b9b97703SBarry Smith MatView_SeqAIJ, 3623f4259b30SLisandro Dalcin NULL, 3624f4259b30SLisandro Dalcin NULL, 3625f4259b30SLisandro Dalcin /* 64*/ NULL, 3626321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3627f4259b30SLisandro Dalcin NULL, 3628f4259b30SLisandro Dalcin NULL, 3629f4259b30SLisandro Dalcin NULL, 3630d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3631c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3632f4259b30SLisandro Dalcin NULL, 3633f4259b30SLisandro Dalcin NULL, 3634f4259b30SLisandro Dalcin NULL, 3635f4259b30SLisandro Dalcin /* 74*/ NULL, 36363acb8795SBarry Smith MatFDColoringApply_AIJ, 3637f4259b30SLisandro Dalcin NULL, 3638f4259b30SLisandro Dalcin NULL, 3639f4259b30SLisandro Dalcin NULL, 36406ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 3641f4259b30SLisandro Dalcin NULL, 3642f4259b30SLisandro Dalcin NULL, 3643f4259b30SLisandro Dalcin NULL, 3644bc011b1eSHong Zhang MatLoad_SeqAIJ, 3645d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 36461cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 3647f4259b30SLisandro Dalcin NULL, 3648f4259b30SLisandro Dalcin NULL, 3649f4259b30SLisandro Dalcin NULL, 3650f4259b30SLisandro Dalcin /* 89*/ NULL, 3651f4259b30SLisandro Dalcin NULL, 365226be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3653f4259b30SLisandro Dalcin NULL, 3654f4259b30SLisandro Dalcin NULL, 36558fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 3656f4259b30SLisandro Dalcin NULL, 3657f4259b30SLisandro Dalcin NULL, 36586fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 3659f4259b30SLisandro Dalcin NULL, 36604222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqAIJ, 3661f4259b30SLisandro Dalcin NULL, 3662f4259b30SLisandro Dalcin NULL, 366387d4246cSBarry Smith MatConjugate_SeqAIJ, 3664f4259b30SLisandro Dalcin NULL, 3665d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 366699cafbc1SBarry Smith MatRealPart_SeqAIJ, 3667f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3668f4259b30SLisandro Dalcin NULL, 3669f4259b30SLisandro Dalcin NULL, 3670cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3671f4259b30SLisandro Dalcin NULL, 36722af78befSBarry Smith MatGetRowMin_SeqAIJ, 3673f4259b30SLisandro Dalcin NULL, 3674599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3675f4259b30SLisandro Dalcin /*114*/ NULL, 3676f4259b30SLisandro Dalcin NULL, 3677f4259b30SLisandro Dalcin NULL, 3678f4259b30SLisandro Dalcin NULL, 3679f4259b30SLisandro Dalcin NULL, 3680f4259b30SLisandro Dalcin /*119*/ NULL, 3681f4259b30SLisandro Dalcin NULL, 3682f4259b30SLisandro Dalcin NULL, 3683f4259b30SLisandro Dalcin NULL, 3684b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 36850716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3686bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 368737868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 36880da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 3689f4259b30SLisandro Dalcin NULL, 3690f4259b30SLisandro Dalcin /*129*/ NULL, 3691f4259b30SLisandro Dalcin NULL, 3692f4259b30SLisandro Dalcin NULL, 369375648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3694b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3695b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 36962b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 3697f4259b30SLisandro Dalcin NULL, 3698f4259b30SLisandro Dalcin NULL, 36993964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 3700f4259b30SLisandro Dalcin /*139*/NULL, 3701f4259b30SLisandro Dalcin NULL, 3702f4259b30SLisandro Dalcin NULL, 37033a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 37049c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 37054222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 37064222ddf1SHong Zhang /*145*/MatDestroySubMatrices_SeqAIJ, 3707f4259b30SLisandro Dalcin NULL, 3708f4259b30SLisandro Dalcin NULL 37099e29f15eSvictorle }; 371017ab2063SBarry Smith 37117087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3712bef8e0ddSBarry Smith { 3713bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 371497f1f81fSBarry Smith PetscInt i,nz,n; 3715bef8e0ddSBarry Smith 3716bef8e0ddSBarry Smith PetscFunctionBegin; 3717bef8e0ddSBarry Smith nz = aij->maxnz; 3718d0f46423SBarry Smith n = mat->rmap->n; 3719bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3720bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3721bef8e0ddSBarry Smith } 3722bef8e0ddSBarry Smith aij->nz = nz; 3723bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3724bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3725bef8e0ddSBarry Smith } 3726bef8e0ddSBarry Smith PetscFunctionReturn(0); 3727bef8e0ddSBarry Smith } 3728bef8e0ddSBarry Smith 3729a3bb6f32SFande Kong /* 3730e8b528d9SFande Kong * When a sparse matrix has many zero columns, we should compact them out to save the space 3731a3bb6f32SFande Kong * This happens in MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3732a3bb6f32SFande Kong * */ 3733a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3734a3bb6f32SFande Kong { 3735a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3736a3bb6f32SFande Kong PetscTable gid1_lid1; 3737a3bb6f32SFande Kong PetscTablePosition tpos; 373825b670f0SStefano Zampini PetscInt gid,lid,i,ec,nz = aij->nz; 373925b670f0SStefano Zampini PetscInt *garray,*jj = aij->j; 3740a3bb6f32SFande Kong PetscErrorCode ierr; 3741a3bb6f32SFande Kong 3742a3bb6f32SFande Kong PetscFunctionBegin; 3743a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3744a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3745a3bb6f32SFande Kong /* use a table */ 3746a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3747a3bb6f32SFande Kong ec = 0; 374825b670f0SStefano Zampini for (i=0; i<nz; i++) { 374925b670f0SStefano Zampini PetscInt data,gid1 = jj[i] + 1; 3750a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3751a3bb6f32SFande Kong if (!data) { 3752a3bb6f32SFande Kong /* one based table */ 3753a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3754a3bb6f32SFande Kong } 3755a3bb6f32SFande Kong } 3756a3bb6f32SFande Kong /* form array of columns we need */ 3757a3bb6f32SFande Kong ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); 3758a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3759a3bb6f32SFande Kong while (tpos) { 3760a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3761a3bb6f32SFande Kong gid--; 3762a3bb6f32SFande Kong lid--; 3763a3bb6f32SFande Kong garray[lid] = gid; 3764a3bb6f32SFande Kong } 3765a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3766a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3767a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3768a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3769a3bb6f32SFande Kong } 3770a3bb6f32SFande Kong /* compact out the extra columns in B */ 377125b670f0SStefano Zampini for (i=0; i<nz; i++) { 377225b670f0SStefano Zampini PetscInt gid1 = jj[i] + 1; 3773a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3774a3bb6f32SFande Kong lid--; 377525b670f0SStefano Zampini jj[i] = lid; 3776a3bb6f32SFande Kong } 3777ca5434daSLawrence Mitchell ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 3778a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 377925b670f0SStefano Zampini ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr); 3780a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3781a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3782a3bb6f32SFande Kong PetscFunctionReturn(0); 3783a3bb6f32SFande Kong } 3784a3bb6f32SFande Kong 3785bef8e0ddSBarry Smith /*@ 3786bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3787bef8e0ddSBarry Smith in the matrix. 3788bef8e0ddSBarry Smith 3789bef8e0ddSBarry Smith Input Parameters: 3790bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3791bef8e0ddSBarry Smith - indices - the column indices 3792bef8e0ddSBarry Smith 379315091d37SBarry Smith Level: advanced 379415091d37SBarry Smith 3795bef8e0ddSBarry Smith Notes: 3796bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3797bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3798bef8e0ddSBarry Smith of the MatSetValues() operation. 3799bef8e0ddSBarry Smith 3800bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3801d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3802bef8e0ddSBarry Smith 3803bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3804bef8e0ddSBarry Smith 3805b9617806SBarry Smith The indices should start with zero, not one. 3806b9617806SBarry Smith 3807bef8e0ddSBarry Smith @*/ 38087087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3809bef8e0ddSBarry Smith { 38104ac538c5SBarry Smith PetscErrorCode ierr; 3811bef8e0ddSBarry Smith 3812bef8e0ddSBarry Smith PetscFunctionBegin; 38130700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 38144482741eSBarry Smith PetscValidPointer(indices,2); 38154ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3816bef8e0ddSBarry Smith PetscFunctionReturn(0); 3817bef8e0ddSBarry Smith } 3818bef8e0ddSBarry Smith 3819be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3820be6bf707SBarry Smith 38217087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3822be6bf707SBarry Smith { 3823be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 38246849ba73SBarry Smith PetscErrorCode ierr; 3825d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3826be6bf707SBarry Smith 3827be6bf707SBarry Smith PetscFunctionBegin; 3828169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3829be6bf707SBarry Smith 3830be6bf707SBarry Smith /* allocate space for values if not already there */ 3831be6bf707SBarry Smith if (!aij->saved_values) { 3832854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 38333bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3834be6bf707SBarry Smith } 3835be6bf707SBarry Smith 3836be6bf707SBarry Smith /* copy values over */ 3837580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3838be6bf707SBarry Smith PetscFunctionReturn(0); 3839be6bf707SBarry Smith } 3840be6bf707SBarry Smith 3841be6bf707SBarry Smith /*@ 3842be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3843be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3844be6bf707SBarry Smith nonlinear portion. 3845be6bf707SBarry Smith 3846be6bf707SBarry Smith Collect on Mat 3847be6bf707SBarry Smith 3848be6bf707SBarry Smith Input Parameters: 38490e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3850be6bf707SBarry Smith 385115091d37SBarry Smith Level: advanced 385215091d37SBarry Smith 3853be6bf707SBarry Smith Common Usage, with SNESSolve(): 3854be6bf707SBarry Smith $ Create Jacobian matrix 3855be6bf707SBarry Smith $ Set linear terms into matrix 3856be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3857be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3858be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3859512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3860be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3861be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3862be6bf707SBarry Smith $ In your Jacobian routine 3863be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3864be6bf707SBarry Smith $ Set nonlinear terms in matrix 3865be6bf707SBarry Smith 3866be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3867be6bf707SBarry Smith $ // build linear portion of Jacobian 3868512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3869be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3870be6bf707SBarry Smith $ loop over nonlinear iterations 3871be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3872be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3873be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3874be6bf707SBarry Smith $ Solve linear system with Jacobian 3875be6bf707SBarry Smith $ endloop 3876be6bf707SBarry Smith 3877be6bf707SBarry Smith Notes: 3878be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3879512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3880be6bf707SBarry Smith calling this routine. 3881be6bf707SBarry Smith 38820c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 38830c468ba9SBarry Smith and does not allocated additional space. 38840c468ba9SBarry Smith 3885be6bf707SBarry Smith .seealso: MatRetrieveValues() 3886be6bf707SBarry Smith 3887be6bf707SBarry Smith @*/ 38887087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3889be6bf707SBarry Smith { 38904ac538c5SBarry Smith PetscErrorCode ierr; 3891be6bf707SBarry Smith 3892be6bf707SBarry Smith PetscFunctionBegin; 38930700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3894e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3895e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 38964ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3897be6bf707SBarry Smith PetscFunctionReturn(0); 3898be6bf707SBarry Smith } 3899be6bf707SBarry Smith 39007087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3901be6bf707SBarry Smith { 3902be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 39036849ba73SBarry Smith PetscErrorCode ierr; 3904d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3905be6bf707SBarry Smith 3906be6bf707SBarry Smith PetscFunctionBegin; 3907169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3908f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3909be6bf707SBarry Smith /* copy values over */ 3910580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3911be6bf707SBarry Smith PetscFunctionReturn(0); 3912be6bf707SBarry Smith } 3913be6bf707SBarry Smith 3914be6bf707SBarry Smith /*@ 3915be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3916be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3917be6bf707SBarry Smith nonlinear portion. 3918be6bf707SBarry Smith 3919be6bf707SBarry Smith Collect on Mat 3920be6bf707SBarry Smith 3921be6bf707SBarry Smith Input Parameters: 3922386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3923be6bf707SBarry Smith 392415091d37SBarry Smith Level: advanced 392515091d37SBarry Smith 3926be6bf707SBarry Smith .seealso: MatStoreValues() 3927be6bf707SBarry Smith 3928be6bf707SBarry Smith @*/ 39297087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3930be6bf707SBarry Smith { 39314ac538c5SBarry Smith PetscErrorCode ierr; 3932be6bf707SBarry Smith 3933be6bf707SBarry Smith PetscFunctionBegin; 39340700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3935e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3936e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 39374ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3938be6bf707SBarry Smith PetscFunctionReturn(0); 3939be6bf707SBarry Smith } 3940be6bf707SBarry Smith 3941f83d6046SBarry Smith 3942be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 394317ab2063SBarry Smith /*@C 3944682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 39450d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 39466e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 394751c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 39482bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 394917ab2063SBarry Smith 3950d083f849SBarry Smith Collective 3951db81eaa0SLois Curfman McInnes 395217ab2063SBarry Smith Input Parameters: 3953db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 395417ab2063SBarry Smith . m - number of rows 395517ab2063SBarry Smith . n - number of columns 395617ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 395751c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39580298fd71SBarry Smith (possibly different for each row) or NULL 395917ab2063SBarry Smith 396017ab2063SBarry Smith Output Parameter: 3961416022c9SBarry Smith . A - the matrix 396217ab2063SBarry Smith 3963175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3964f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3965175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3966175b88e8SBarry Smith 3967b259b22eSLois Curfman McInnes Notes: 396849a6f317SBarry Smith If nnz is given then nz is ignored 396949a6f317SBarry Smith 397017ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 397117ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 39720002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 397344cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 397417ab2063SBarry Smith 397517ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39760298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 39773d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 39786da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 397917ab2063SBarry Smith 3980682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 39814fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3982682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 39836c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 39846c7ebb05SLois Curfman McInnes 39856c7ebb05SLois Curfman McInnes Options Database Keys: 3986698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 39879db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 398817ab2063SBarry Smith 3989027ccd11SLois Curfman McInnes Level: intermediate 3990027ccd11SLois Curfman McInnes 399169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 399236db0b34SBarry Smith 399317ab2063SBarry Smith @*/ 39947087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 399517ab2063SBarry Smith { 3996dfbe8321SBarry Smith PetscErrorCode ierr; 39976945ee14SBarry Smith 39983a40ed3dSBarry Smith PetscFunctionBegin; 3999f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 4000117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 4001c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 4002d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 4003273d9f13SBarry Smith PetscFunctionReturn(0); 4004273d9f13SBarry Smith } 4005273d9f13SBarry Smith 4006273d9f13SBarry Smith /*@C 4007273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 4008273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 4009273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 4010273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 4011273d9f13SBarry Smith 4012d083f849SBarry Smith Collective 4013273d9f13SBarry Smith 4014273d9f13SBarry Smith Input Parameters: 40151c4f3114SJed Brown + B - The matrix 4016273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 4017273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 40180298fd71SBarry Smith (possibly different for each row) or NULL 4019273d9f13SBarry Smith 4020273d9f13SBarry Smith Notes: 402149a6f317SBarry Smith If nnz is given then nz is ignored 402249a6f317SBarry Smith 4023273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 4024273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 4025273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 4026273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 4027273d9f13SBarry Smith 4028273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 40290298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 4030273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 4031273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 4032273d9f13SBarry Smith 4033aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 4034aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 4035aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 4036aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 4037aa95bbe8SBarry Smith 4038a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 4039a96a251dSBarry Smith entries or columns indices 4040a96a251dSBarry Smith 4041273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 4042273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 4043273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 4044273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 4045273d9f13SBarry Smith 4046273d9f13SBarry Smith Options Database Keys: 4047698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 404847b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 4049273d9f13SBarry Smith 4050273d9f13SBarry Smith Level: intermediate 4051273d9f13SBarry Smith 405219b08ed1SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo(), 405319b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation() 4054273d9f13SBarry Smith 4055273d9f13SBarry Smith @*/ 40567087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 4057273d9f13SBarry Smith { 40584ac538c5SBarry Smith PetscErrorCode ierr; 4059a23d5eceSKris Buschelman 4060a23d5eceSKris Buschelman PetscFunctionBegin; 40616ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 40626ba663aaSJed Brown PetscValidType(B,1); 40634ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 4064a23d5eceSKris Buschelman PetscFunctionReturn(0); 4065a23d5eceSKris Buschelman } 4066a23d5eceSKris Buschelman 40677087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 4068a23d5eceSKris Buschelman { 4069273d9f13SBarry Smith Mat_SeqAIJ *b; 40702576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 40716849ba73SBarry Smith PetscErrorCode ierr; 407297f1f81fSBarry Smith PetscInt i; 4073273d9f13SBarry Smith 4074273d9f13SBarry Smith PetscFunctionBegin; 40752576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 4076a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 4077c461c341SBarry Smith skipallocation = PETSC_TRUE; 4078c461c341SBarry Smith nz = 0; 4079c461c341SBarry Smith } 408026283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 408126283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4082899cda47SBarry Smith 4083435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 408460e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 4085cf9c20a2SJed Brown if (PetscUnlikelyDebug(nnz)) { 4086d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 408760e0710aSBarry 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]); 408860e0710aSBarry 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); 4089b73539f3SBarry Smith } 4090b73539f3SBarry Smith } 4091b73539f3SBarry Smith 4092273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 40932205254eSKarl Rupp 4094273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 4095273d9f13SBarry Smith 4096ab93d7beSBarry Smith if (!skipallocation) { 40972ee49352SLisandro Dalcin if (!b->imax) { 4098071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 4099071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4100071fcb05SBarry Smith } 4101071fcb05SBarry Smith if (!b->ilen) { 4102071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 4103071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 4104071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4105071fcb05SBarry Smith } else { 4106071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 41072ee49352SLisandro Dalcin } 4108846b4da1SFande Kong if (!b->ipre) { 4109846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 4110846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4111846b4da1SFande Kong } 4112273d9f13SBarry Smith if (!nnz) { 4113435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 4114c62bd62aSJed Brown else if (nz < 0) nz = 1; 41155d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 4116d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 4117d0f46423SBarry Smith nz = nz*B->rmap->n; 4118273d9f13SBarry Smith } else { 4119c73702f5SBarry Smith PetscInt64 nz64 = 0; 4120c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 4121c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 4122273d9f13SBarry Smith } 4123ab93d7beSBarry Smith 4124273d9f13SBarry Smith /* allocate the matrix space */ 412553dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 41262ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 4127396832f4SHong Zhang if (B->structure_only) { 41285848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 41295848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 4130396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 4131396832f4SHong Zhang } else { 4132dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 41333bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 4134396832f4SHong Zhang } 4135bfeeae90SHong Zhang b->i[0] = 0; 4136d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 41375da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 41385da197adSKris Buschelman } 4139396832f4SHong Zhang if (B->structure_only) { 4140396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 4141396832f4SHong Zhang b->free_a = PETSC_FALSE; 4142396832f4SHong Zhang } else { 4143273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 4144e6b907acSBarry Smith b->free_a = PETSC_TRUE; 4145396832f4SHong Zhang } 4146e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 4147c461c341SBarry Smith } else { 4148e6b907acSBarry Smith b->free_a = PETSC_FALSE; 4149e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 4150c461c341SBarry Smith } 4151273d9f13SBarry Smith 4152846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 4153846b4da1SFande Kong /* reserve user-requested sparsity */ 4154580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 4155846b4da1SFande Kong } 4156846b4da1SFande Kong 4157846b4da1SFande Kong 4158273d9f13SBarry Smith b->nz = 0; 4159273d9f13SBarry Smith b->maxnz = nz; 4160273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 41612205254eSKarl Rupp if (realalloc) { 41622205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 41632205254eSKarl Rupp } 4164cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 4165cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 4166273d9f13SBarry Smith PetscFunctionReturn(0); 4167273d9f13SBarry Smith } 4168273d9f13SBarry Smith 4169846b4da1SFande Kong 4170846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 4171846b4da1SFande Kong { 4172846b4da1SFande Kong Mat_SeqAIJ *a; 4173a5bbaf83SFande Kong PetscInt i; 4174846b4da1SFande Kong PetscErrorCode ierr; 4175846b4da1SFande Kong 4176846b4da1SFande Kong PetscFunctionBegin; 4177846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 417814d0e64fSAlex Lindsay 417914d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 418014d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 418114d0e64fSAlex Lindsay 4182846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 41832c814fdeSFande Kong /* if no saved info, we error out */ 4184fb4dc15dSAlex Lindsay if (!a->ipre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 41852c814fdeSFande Kong 4186fb4dc15dSAlex 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"); 41872c814fdeSFande Kong 4188580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 4189580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 4190846b4da1SFande Kong a->i[0] = 0; 4191846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 4192846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 4193846b4da1SFande Kong } 4194846b4da1SFande Kong A->preallocated = PETSC_TRUE; 4195846b4da1SFande Kong a->nz = 0; 4196846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 4197846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 4198846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 4199846b4da1SFande Kong A->assembled = PETSC_FALSE; 4200846b4da1SFande Kong PetscFunctionReturn(0); 4201846b4da1SFande Kong } 4202846b4da1SFande Kong 420358d36128SBarry Smith /*@ 4204a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 4205a1661176SMatthew Knepley 4206a1661176SMatthew Knepley Input Parameters: 4207a1661176SMatthew Knepley + B - the matrix 4208a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4209a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4210a1661176SMatthew Knepley - v - optional values in the matrix 4211a1661176SMatthew Knepley 4212a1661176SMatthew Knepley Level: developer 4213a1661176SMatthew Knepley 42146a9b8d82SBarry Smith Notes: 421558d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 421658d36128SBarry Smith 42176a9b8d82SBarry Smith This routine may be called multiple times with different nonzero patterns (or the same nonzero pattern). The nonzero 42186a9b8d82SBarry Smith structure will be the union of all the previous nonzero structures. 42196a9b8d82SBarry Smith 42206a9b8d82SBarry Smith Developer Notes: 42216a9b8d82SBarry 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 42226a9b8d82SBarry Smith then just copies the v values directly with PetscMemcpy(). 42236a9b8d82SBarry Smith 42246a9b8d82SBarry Smith This routine could also take a PetscCopyMode argument to allow sharing the values instead of always copying them. 42256a9b8d82SBarry Smith 42266a9b8d82SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ, MatResetPreallocation() 4227a1661176SMatthew Knepley @*/ 4228a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4229a1661176SMatthew Knepley { 4230a1661176SMatthew Knepley PetscErrorCode ierr; 4231a1661176SMatthew Knepley 4232a1661176SMatthew Knepley PetscFunctionBegin; 42330700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 42346ba663aaSJed Brown PetscValidType(B,1); 42354ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 4236a1661176SMatthew Knepley PetscFunctionReturn(0); 4237a1661176SMatthew Knepley } 4238a1661176SMatthew Knepley 42397087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4240a1661176SMatthew Knepley { 4241a1661176SMatthew Knepley PetscInt i; 4242a1661176SMatthew Knepley PetscInt m,n; 4243a1661176SMatthew Knepley PetscInt nz; 42446a9b8d82SBarry Smith PetscInt *nnz; 4245a1661176SMatthew Knepley PetscErrorCode ierr; 4246a1661176SMatthew Knepley 4247a1661176SMatthew Knepley PetscFunctionBegin; 424865e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4249779a8d59SSatish Balay 4250779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4251779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4252779a8d59SSatish Balay 4253779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4254854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 4255a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4256b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 425765e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4258a1661176SMatthew Knepley nnz[i] = nz; 4259a1661176SMatthew Knepley } 4260a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4261a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4262a1661176SMatthew Knepley 4263a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4264071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 4265a1661176SMatthew Knepley } 4266a1661176SMatthew Knepley 4267a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4268a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4269a1661176SMatthew Knepley 42707827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4271a1661176SMatthew Knepley PetscFunctionReturn(0); 4272a1661176SMatthew Knepley } 4273a1661176SMatthew Knepley 4274c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4275af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4276170fe5c8SBarry Smith 4277170fe5c8SBarry Smith /* 4278170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4279170fe5c8SBarry Smith 4280170fe5c8SBarry Smith n p p 42812da392ccSBarry Smith [ ] [ ] [ ] 42822da392ccSBarry Smith m [ A ] * n [ B ] = m [ C ] 42832da392ccSBarry Smith [ ] [ ] [ ] 4284170fe5c8SBarry Smith 4285170fe5c8SBarry Smith */ 4286170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4287170fe5c8SBarry Smith { 4288170fe5c8SBarry Smith PetscErrorCode ierr; 4289170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4290170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4291170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 429286214ceeSStefano Zampini PetscInt i,j,n,m,q,p; 4293170fe5c8SBarry Smith const PetscInt *ii,*idx; 4294170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4295170fe5c8SBarry Smith PetscScalar *c,*c_q; 429686214ceeSStefano Zampini PetscInt clda = sub_c->lda; 429786214ceeSStefano Zampini PetscInt alda = sub_a->lda; 4298170fe5c8SBarry Smith 4299170fe5c8SBarry Smith PetscFunctionBegin; 4300d0f46423SBarry Smith m = A->rmap->n; 4301d0f46423SBarry Smith n = A->cmap->n; 4302d0f46423SBarry Smith p = B->cmap->n; 4303170fe5c8SBarry Smith a = sub_a->v; 4304170fe5c8SBarry Smith b = sub_b->a; 4305170fe5c8SBarry Smith c = sub_c->v; 430686214ceeSStefano Zampini if (clda == m) { 4307580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 430886214ceeSStefano Zampini } else { 430986214ceeSStefano Zampini for (j=0;j<p;j++) 431086214ceeSStefano Zampini for (i=0;i<m;i++) 431186214ceeSStefano Zampini c[j*clda + i] = 0.0; 431286214ceeSStefano Zampini } 4313170fe5c8SBarry Smith ii = sub_b->i; 4314170fe5c8SBarry Smith idx = sub_b->j; 4315170fe5c8SBarry Smith for (i=0; i<n; i++) { 4316170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4317170fe5c8SBarry Smith while (q-->0) { 431886214ceeSStefano Zampini c_q = c + clda*(*idx); 431986214ceeSStefano Zampini a_q = a + alda*i; 4320854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4321170fe5c8SBarry Smith idx++; 4322170fe5c8SBarry Smith b++; 4323170fe5c8SBarry Smith } 4324170fe5c8SBarry Smith } 4325170fe5c8SBarry Smith PetscFunctionReturn(0); 4326170fe5c8SBarry Smith } 4327170fe5c8SBarry Smith 43284222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C) 4329170fe5c8SBarry Smith { 4330170fe5c8SBarry Smith PetscErrorCode ierr; 4331d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 433286214ceeSStefano Zampini PetscBool cisdense; 4333170fe5c8SBarry Smith 4334170fe5c8SBarry Smith PetscFunctionBegin; 433560e0710aSBarry 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); 43364222ddf1SHong Zhang ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr); 43374222ddf1SHong Zhang ierr = MatSetBlockSizesFromMats(C,A,B);CHKERRQ(ierr); 433886214ceeSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr); 433986214ceeSStefano Zampini if (!cisdense) { 434086214ceeSStefano Zampini ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); 434186214ceeSStefano Zampini } 434286214ceeSStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 4343d73949e8SHong Zhang 43444222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 4345170fe5c8SBarry Smith PetscFunctionReturn(0); 4346170fe5c8SBarry Smith } 4347170fe5c8SBarry Smith 4348170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 43490bad9183SKris Buschelman /*MC 4350fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 43510bad9183SKris Buschelman based on compressed sparse row format. 43520bad9183SKris Buschelman 43530bad9183SKris Buschelman Options Database Keys: 43540bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 43550bad9183SKris Buschelman 43560bad9183SKris Buschelman Level: beginner 43570bad9183SKris Buschelman 43580cd7f59aSBarry Smith Notes: 43590cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 43600cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 43610cd7f59aSBarry Smith in the matrix 43620cd7f59aSBarry Smith 43630cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 43640cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 43650cd7f59aSBarry Smith 43660cd7f59aSBarry Smith Developer Notes: 43670cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 43680cd7f59aSBarry Smith 4369f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 43700bad9183SKris Buschelman M*/ 43710bad9183SKris Buschelman 4372ccd284c7SBarry Smith /*MC 4373ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4374ccd284c7SBarry Smith 4375ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4376ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 43770cd7f59aSBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation() is supported 4378ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4379ccd284c7SBarry Smith the above preallocation routines for simplicity. 4380ccd284c7SBarry Smith 4381ccd284c7SBarry Smith Options Database Keys: 4382ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4383ccd284c7SBarry Smith 438495452b02SPatrick Sanan Developer Notes: 4385ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4386ccd284c7SBarry Smith enough exist. 4387ccd284c7SBarry Smith 4388ccd284c7SBarry Smith Level: beginner 4389ccd284c7SBarry Smith 4390ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4391ccd284c7SBarry Smith M*/ 4392ccd284c7SBarry Smith 4393ccd284c7SBarry Smith /*MC 4394ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4395ccd284c7SBarry Smith 4396ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4397ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4398ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4399ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4400ccd284c7SBarry Smith the above preallocation routines for simplicity. 4401ccd284c7SBarry Smith 4402ccd284c7SBarry Smith Options Database Keys: 4403ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4404ccd284c7SBarry Smith 4405ccd284c7SBarry Smith Level: beginner 4406ccd284c7SBarry Smith 4407ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4408ccd284c7SBarry Smith M*/ 4409ccd284c7SBarry Smith 44107906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 44117906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 44127906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 44137906f579SHong Zhang #endif 4414d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4415d24d4204SJose E. Roman PETSC_INTERN PetscErrorCode MatConvert_AIJ_ScaLAPACK(Mat,MatType,MatReuse,Mat*); 4416d24d4204SJose E. Roman #endif 44177906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 44187906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 44197906f579SHong Zhang #endif 44207906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 44217906f579SHong Zhang 4422d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4423c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 44244222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat); 44257906f579SHong Zhang 44268c778c55SBarry Smith /*@C 44278f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 44288c778c55SBarry Smith 44298c778c55SBarry Smith Not Collective 44308c778c55SBarry Smith 44318c778c55SBarry Smith Input Parameter: 4432579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 44338c778c55SBarry Smith 44348c778c55SBarry Smith Output Parameter: 44358c778c55SBarry Smith . array - pointer to the data 44368c778c55SBarry Smith 44378c778c55SBarry Smith Level: intermediate 44388c778c55SBarry Smith 4439774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 44408c778c55SBarry Smith @*/ 44418c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 44428c778c55SBarry Smith { 44438c778c55SBarry Smith PetscErrorCode ierr; 44448c778c55SBarry Smith 44458c778c55SBarry Smith PetscFunctionBegin; 44468c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 44472e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 44482e5835c6SStefano Zampini if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 44492e5835c6SStefano Zampini #endif 44508c778c55SBarry Smith PetscFunctionReturn(0); 44518c778c55SBarry Smith } 44528c778c55SBarry Smith 445321e72a00SBarry Smith /*@C 44548f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 44558f1ea47aSStefano Zampini 44568f1ea47aSStefano Zampini Not Collective 44578f1ea47aSStefano Zampini 44588f1ea47aSStefano Zampini Input Parameter: 44598f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44608f1ea47aSStefano Zampini 44618f1ea47aSStefano Zampini Output Parameter: 44628f1ea47aSStefano Zampini . array - pointer to the data 44638f1ea47aSStefano Zampini 44648f1ea47aSStefano Zampini Level: intermediate 44658f1ea47aSStefano Zampini 44668f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 44678f1ea47aSStefano Zampini @*/ 44688f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 44698f1ea47aSStefano Zampini { 44708c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4471c70f7ee4SJunchao Zhang PetscOffloadMask oval; 44728f1ea47aSStefano Zampini #endif 44738f1ea47aSStefano Zampini PetscErrorCode ierr; 44748f1ea47aSStefano Zampini 44758f1ea47aSStefano Zampini PetscFunctionBegin; 44768c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4477c70f7ee4SJunchao Zhang oval = A->offloadmask; 44788f1ea47aSStefano Zampini #endif 44798f1ea47aSStefano Zampini ierr = MatSeqAIJGetArray(A,(PetscScalar**)array);CHKERRQ(ierr); 44808c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4481c70f7ee4SJunchao Zhang if (oval == PETSC_OFFLOAD_GPU || oval == PETSC_OFFLOAD_BOTH) A->offloadmask = PETSC_OFFLOAD_BOTH; 44828f1ea47aSStefano Zampini #endif 44838f1ea47aSStefano Zampini PetscFunctionReturn(0); 44848f1ea47aSStefano Zampini } 44858f1ea47aSStefano Zampini 44868f1ea47aSStefano Zampini /*@C 44878f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 44888f1ea47aSStefano Zampini 44898f1ea47aSStefano Zampini Not Collective 44908f1ea47aSStefano Zampini 44918f1ea47aSStefano Zampini Input Parameter: 44928f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44938f1ea47aSStefano Zampini 44948f1ea47aSStefano Zampini Output Parameter: 44958f1ea47aSStefano Zampini . array - pointer to the data 44968f1ea47aSStefano Zampini 44978f1ea47aSStefano Zampini Level: intermediate 44988f1ea47aSStefano Zampini 44998f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 45008f1ea47aSStefano Zampini @*/ 45018f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 45028f1ea47aSStefano Zampini { 45038c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4504c70f7ee4SJunchao Zhang PetscOffloadMask oval; 45058f1ea47aSStefano Zampini #endif 45068f1ea47aSStefano Zampini PetscErrorCode ierr; 45078f1ea47aSStefano Zampini 45088f1ea47aSStefano Zampini PetscFunctionBegin; 45098c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4510c70f7ee4SJunchao Zhang oval = A->offloadmask; 45118f1ea47aSStefano Zampini #endif 45128f1ea47aSStefano Zampini ierr = MatSeqAIJRestoreArray(A,(PetscScalar**)array);CHKERRQ(ierr); 45138c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4514c70f7ee4SJunchao Zhang A->offloadmask = oval; 45158f1ea47aSStefano Zampini #endif 45168f1ea47aSStefano Zampini PetscFunctionReturn(0); 45178f1ea47aSStefano Zampini } 45188f1ea47aSStefano Zampini 45198f1ea47aSStefano Zampini /*@C 452021e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 452121e72a00SBarry Smith 452221e72a00SBarry Smith Not Collective 452321e72a00SBarry Smith 452421e72a00SBarry Smith Input Parameter: 4525579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 452621e72a00SBarry Smith 452721e72a00SBarry Smith Output Parameter: 452821e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 452921e72a00SBarry Smith 453021e72a00SBarry Smith Level: intermediate 453121e72a00SBarry Smith 453221e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 453321e72a00SBarry Smith @*/ 453421e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 453521e72a00SBarry Smith { 453621e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 453721e72a00SBarry Smith 453821e72a00SBarry Smith PetscFunctionBegin; 453921e72a00SBarry Smith *nz = aij->rmax; 454021e72a00SBarry Smith PetscFunctionReturn(0); 454121e72a00SBarry Smith } 454221e72a00SBarry Smith 45438c778c55SBarry Smith /*@C 4544579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 45458c778c55SBarry Smith 45468c778c55SBarry Smith Not Collective 45478c778c55SBarry Smith 45488c778c55SBarry Smith Input Parameters: 4549a2b725a8SWilliam Gropp + mat - a MATSEQAIJ matrix 4550a2b725a8SWilliam Gropp - array - pointer to the data 45518c778c55SBarry Smith 45528c778c55SBarry Smith Level: intermediate 45538c778c55SBarry Smith 4554774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 45558c778c55SBarry Smith @*/ 45568c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 45578c778c55SBarry Smith { 45588c778c55SBarry Smith PetscErrorCode ierr; 45598c778c55SBarry Smith 45608c778c55SBarry Smith PetscFunctionBegin; 45618c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 45628c778c55SBarry Smith PetscFunctionReturn(0); 45638c778c55SBarry Smith } 45648c778c55SBarry Smith 456534b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 45660ce8acdeSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat); 456702fe1965SBarry Smith #endif 45683d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 45693d0639e7SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJKokkos(Mat); 45703d0639e7SStefano Zampini #endif 457102fe1965SBarry Smith 45728cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4573273d9f13SBarry Smith { 4574273d9f13SBarry Smith Mat_SeqAIJ *b; 4575dfbe8321SBarry Smith PetscErrorCode ierr; 457638baddfdSBarry Smith PetscMPIInt size; 4577273d9f13SBarry Smith 4578273d9f13SBarry Smith PetscFunctionBegin; 4579ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr); 4580e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4581273d9f13SBarry Smith 4582b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 45832205254eSKarl Rupp 4584b0a32e0cSBarry Smith B->data = (void*)b; 45852205254eSKarl Rupp 4586549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4587071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 45882205254eSKarl Rupp 4589f4259b30SLisandro Dalcin b->row = NULL; 4590f4259b30SLisandro Dalcin b->col = NULL; 4591f4259b30SLisandro Dalcin b->icol = NULL; 4592b810aeb4SBarry Smith b->reallocs = 0; 459336db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4594f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4595416022c9SBarry Smith b->nonew = 0; 4596f4259b30SLisandro Dalcin b->diag = NULL; 4597f4259b30SLisandro Dalcin b->solve_work = NULL; 4598f4259b30SLisandro Dalcin B->spptr = NULL; 4599f4259b30SLisandro Dalcin b->saved_values = NULL; 4600f4259b30SLisandro Dalcin b->idiag = NULL; 4601f4259b30SLisandro Dalcin b->mdiag = NULL; 4602f4259b30SLisandro Dalcin b->ssor_work = NULL; 460371f1c65dSBarry Smith b->omega = 1.0; 460471f1c65dSBarry Smith b->fshift = 0.0; 460571f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4606bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4607a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 460817ab2063SBarry Smith 460935d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4610bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4611bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 46128c778c55SBarry Smith 4613b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4614bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4615bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4616b3866ffcSBarry Smith #endif 461717f1a0eaSHong Zhang 4618bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4619bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4620bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4621bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4622bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4623bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 46244dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 46259779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 46264a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4627191b95cbSRichard Tran Mills #endif 462834b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 462902fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 46304222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 4631fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 463202fe1965SBarry Smith #endif 46333d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 46343d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijkokkos_C",MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr); 46353d0639e7SStefano Zampini #endif 4636bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4637af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4638af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4639af8000cdSHong Zhang #endif 4640d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4641d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_scalapack_C",MatConvert_AIJ_ScaLAPACK);CHKERRQ(ierr); 4642d24d4204SJose E. Roman #endif 464363c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 464463c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 46454222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ);CHKERRQ(ierr); 464663c07aadSStefano Zampini #endif 4647b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4648d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4649c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4650bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4651bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4652bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4653846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4654bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4655bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 46564222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ);CHKERRQ(ierr); 46574222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ);CHKERRQ(ierr); 46584222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 46594108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 466017667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 46614099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 46623a40ed3dSBarry Smith PetscFunctionReturn(0); 466317ab2063SBarry Smith } 466417ab2063SBarry Smith 4665b24902e0SBarry Smith /* 4666b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4667b24902e0SBarry Smith */ 4668ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 466917ab2063SBarry Smith { 46702a350339SBarry Smith Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data,*a = (Mat_SeqAIJ*)A->data; 46716849ba73SBarry Smith PetscErrorCode ierr; 4672071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 467317ab2063SBarry Smith 46743a40ed3dSBarry Smith PetscFunctionBegin; 4675ca133879SJose E. Roman if (!A->assembled && cpvalues!=MAT_DO_NOT_COPY_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot duplicate unassembled matrix"); 4676273d9f13SBarry Smith 4677d5f3da31SBarry Smith C->factortype = A->factortype; 4678f4259b30SLisandro Dalcin c->row = NULL; 4679f4259b30SLisandro Dalcin c->col = NULL; 4680f4259b30SLisandro Dalcin c->icol = NULL; 46816ad4291fSHong Zhang c->reallocs = 0; 468217ab2063SBarry Smith 46836ad4291fSHong Zhang C->assembled = PETSC_TRUE; 468417ab2063SBarry Smith 4685aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4686aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4687eec197d1SBarry Smith 4688071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4689071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4690071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4691071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 46923bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 469317ab2063SBarry Smith 469417ab2063SBarry Smith /* allocate the matrix space */ 4695f77e22a1SHong Zhang if (mallocmatspace) { 4696dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 46973bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 46982205254eSKarl Rupp 4699f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 47002205254eSKarl Rupp 4701580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 470217ab2063SBarry Smith if (m > 0) { 4703580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4704be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 47052e5835c6SStefano Zampini const PetscScalar *aa; 47062e5835c6SStefano Zampini 47072e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 47082e5835c6SStefano Zampini ierr = PetscArraycpy(c->a,aa,a->i[m]);CHKERRQ(ierr); 47092e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 4710be6bf707SBarry Smith } else { 4711580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 471217ab2063SBarry Smith } 471308480c60SBarry Smith } 4714f77e22a1SHong Zhang } 471517ab2063SBarry Smith 47166ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4717416022c9SBarry Smith c->roworiented = a->roworiented; 4718416022c9SBarry Smith c->nonew = a->nonew; 4719416022c9SBarry Smith if (a->diag) { 4720854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4721071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 47223bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4723071fcb05SBarry Smith } else c->diag = NULL; 47242205254eSKarl Rupp 4725f4259b30SLisandro Dalcin c->solve_work = NULL; 4726f4259b30SLisandro Dalcin c->saved_values = NULL; 4727f4259b30SLisandro Dalcin c->idiag = NULL; 4728f4259b30SLisandro Dalcin c->ssor_work = NULL; 4729a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4730e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4731e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 47326ad4291fSHong Zhang 4733893ad86cSHong Zhang c->rmax = a->rmax; 4734416022c9SBarry Smith c->nz = a->nz; 47358ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4736273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4737754ec7b1SSatish Balay 47386ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 47396ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4740cd6b891eSBarry Smith if (a->compressedrow.use) { 47416ad4291fSHong Zhang i = a->compressedrow.nrows; 4742dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4743580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4744580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 474527ea64f8SHong Zhang } else { 474627ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 47470298fd71SBarry Smith c->compressedrow.i = NULL; 47480298fd71SBarry Smith c->compressedrow.rindex = NULL; 47496ad4291fSHong Zhang } 4750ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4751e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 47524846f1f5SKris Buschelman 47532205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4754140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 47553a40ed3dSBarry Smith PetscFunctionReturn(0); 475617ab2063SBarry Smith } 475717ab2063SBarry Smith 4758b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4759b24902e0SBarry Smith { 4760b24902e0SBarry Smith PetscErrorCode ierr; 4761b24902e0SBarry Smith 4762b24902e0SBarry Smith PetscFunctionBegin; 4763ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 47644b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4765cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 476633d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4767cfd3f464SBarry Smith } 4768a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4769f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4770b24902e0SBarry Smith PetscFunctionReturn(0); 4771b24902e0SBarry Smith } 4772b24902e0SBarry Smith 4773112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4774fbdbba38SShri Abhyankar { 477552f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 477652f91c60SVaclav Hapla PetscErrorCode ierr; 477752f91c60SVaclav Hapla 477852f91c60SVaclav Hapla PetscFunctionBegin; 477952f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 478052f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4781c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4782c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 478352f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 478452f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 478552f91c60SVaclav Hapla if (isbinary) { 478652f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 478752f91c60SVaclav Hapla } else if (ishdf5) { 478852f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 478952f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 479052f91c60SVaclav Hapla #else 479152f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 479252f91c60SVaclav Hapla #endif 479352f91c60SVaclav Hapla } else { 479452f91c60SVaclav 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); 479552f91c60SVaclav Hapla } 479652f91c60SVaclav Hapla PetscFunctionReturn(0); 479752f91c60SVaclav Hapla } 479852f91c60SVaclav Hapla 47993ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer) 480052f91c60SVaclav Hapla { 48013ea6fe3dSLisandro Dalcin Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 4802fbdbba38SShri Abhyankar PetscErrorCode ierr; 48033ea6fe3dSLisandro Dalcin PetscInt header[4],*rowlens,M,N,nz,sum,rows,cols,i; 4804fbdbba38SShri Abhyankar 4805fbdbba38SShri Abhyankar PetscFunctionBegin; 48063ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4807bbead8a2SBarry Smith 48083ea6fe3dSLisandro Dalcin /* read in matrix header */ 48093ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 48103ea6fe3dSLisandro Dalcin if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 4811fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 48123ea6fe3dSLisandro Dalcin if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M); 48133ea6fe3dSLisandro Dalcin if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N); 4814bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 4815fbdbba38SShri Abhyankar 48163ea6fe3dSLisandro Dalcin /* set block sizes from the viewer's .info file */ 48173ea6fe3dSLisandro Dalcin ierr = MatLoad_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 48183ea6fe3dSLisandro Dalcin /* set local and global sizes if not set already */ 48193ea6fe3dSLisandro Dalcin if (mat->rmap->n < 0) mat->rmap->n = M; 48203ea6fe3dSLisandro Dalcin if (mat->cmap->n < 0) mat->cmap->n = N; 48213ea6fe3dSLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 48223ea6fe3dSLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 48233ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 48243ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 48253ea6fe3dSLisandro Dalcin 48263ea6fe3dSLisandro Dalcin /* check if the matrix sizes are correct */ 48273ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 48283ea6fe3dSLisandro 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); 48293ea6fe3dSLisandro Dalcin 4830fbdbba38SShri Abhyankar /* read in row lengths */ 48313ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(M,&rowlens);CHKERRQ(ierr); 48323ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT);CHKERRQ(ierr); 48333ea6fe3dSLisandro Dalcin /* check if sum(rowlens) is same as nz */ 48343ea6fe3dSLisandro Dalcin sum = 0; for (i=0; i<M; i++) sum += rowlens[i]; 48353ea6fe3dSLisandro 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); 48363ea6fe3dSLisandro Dalcin /* preallocate and check sizes */ 48373ea6fe3dSLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens);CHKERRQ(ierr); 48383ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 483960e0710aSBarry 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); 48403ea6fe3dSLisandro Dalcin /* store row lengths */ 48413ea6fe3dSLisandro Dalcin ierr = PetscArraycpy(a->ilen,rowlens,M);CHKERRQ(ierr); 48423ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 4843fbdbba38SShri Abhyankar 48443ea6fe3dSLisandro Dalcin /* fill in "i" row pointers */ 48453ea6fe3dSLisandro Dalcin a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i]; 48463ea6fe3dSLisandro Dalcin /* read in "j" column indices */ 48473ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 48483ea6fe3dSLisandro Dalcin /* read in "a" nonzero values */ 48493ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4850fbdbba38SShri Abhyankar 48513ea6fe3dSLisandro Dalcin ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 48523ea6fe3dSLisandro Dalcin ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4853fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4854fbdbba38SShri Abhyankar } 4855fbdbba38SShri Abhyankar 4856ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 48577264ac53SSatish Balay { 48587264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4859dfbe8321SBarry Smith PetscErrorCode ierr; 4860eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4861eeffb40dSHong Zhang PetscInt k; 4862eeffb40dSHong Zhang #endif 48637264ac53SSatish Balay 48643a40ed3dSBarry Smith PetscFunctionBegin; 4865bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4866d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4867ca44d042SBarry Smith *flg = PETSC_FALSE; 4868ca44d042SBarry Smith PetscFunctionReturn(0); 4869bcd2baecSBarry Smith } 48707264ac53SSatish Balay 48717264ac53SSatish Balay /* if the a->i are the same */ 4872580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4873abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 48747264ac53SSatish Balay 48757264ac53SSatish Balay /* if a->j are the same */ 4876580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 4877abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4878bcd2baecSBarry Smith 4879bcd2baecSBarry Smith /* if a->a are the same */ 4880eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4881eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4882eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4883eeffb40dSHong Zhang *flg = PETSC_FALSE; 48843a40ed3dSBarry Smith PetscFunctionReturn(0); 4885eeffb40dSHong Zhang } 4886eeffb40dSHong Zhang } 4887eeffb40dSHong Zhang #else 4888580bdb30SBarry Smith ierr = PetscArraycmp(a->a,b->a,a->nz,flg);CHKERRQ(ierr); 4889eeffb40dSHong Zhang #endif 4890eeffb40dSHong Zhang PetscFunctionReturn(0); 48917264ac53SSatish Balay } 489236db0b34SBarry Smith 489305869f15SSatish Balay /*@ 489436db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 489536db0b34SBarry Smith provided by the user. 489636db0b34SBarry Smith 4897d083f849SBarry Smith Collective 489836db0b34SBarry Smith 489936db0b34SBarry Smith Input Parameters: 490036db0b34SBarry Smith + comm - must be an MPI communicator of size 1 490136db0b34SBarry Smith . m - number of rows 490236db0b34SBarry Smith . n - number of columns 4903483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 490436db0b34SBarry Smith . j - column indices 490536db0b34SBarry Smith - a - matrix values 490636db0b34SBarry Smith 490736db0b34SBarry Smith Output Parameter: 490836db0b34SBarry Smith . mat - the matrix 490936db0b34SBarry Smith 491036db0b34SBarry Smith Level: intermediate 491136db0b34SBarry Smith 491236db0b34SBarry Smith Notes: 49130551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4914292fb18eSBarry Smith once the matrix is destroyed and not before 491536db0b34SBarry Smith 491636db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 491736db0b34SBarry Smith 4918bfeeae90SHong Zhang The i and j indices are 0 based 491936db0b34SBarry Smith 4920a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4921a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 49228eef79e4SBarry Smith as shown 4923a4552177SSatish Balay 49248eef79e4SBarry Smith $ 1 0 0 49258eef79e4SBarry Smith $ 2 0 3 49268eef79e4SBarry Smith $ 4 5 6 49278eef79e4SBarry Smith $ 49288eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 49298eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 49308eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4931a4552177SSatish Balay 49329985e31cSBarry Smith 493369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 493436db0b34SBarry Smith 493536db0b34SBarry Smith @*/ 4936c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 493736db0b34SBarry Smith { 4938dfbe8321SBarry Smith PetscErrorCode ierr; 4939cbcfb4deSHong Zhang PetscInt ii; 494036db0b34SBarry Smith Mat_SeqAIJ *aij; 4941cbcfb4deSHong Zhang PetscInt jj; 494236db0b34SBarry Smith 494336db0b34SBarry Smith PetscFunctionBegin; 494441096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4945f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4946f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4947a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4948ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4949f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,NULL);CHKERRQ(ierr); 4950ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4951071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 4952071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 4953ab93d7beSBarry Smith 495436db0b34SBarry Smith aij->i = i; 495536db0b34SBarry Smith aij->j = j; 495636db0b34SBarry Smith aij->a = a; 495736db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 495836db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4959e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4960e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 496136db0b34SBarry Smith 496236db0b34SBarry Smith for (ii=0; ii<m; ii++) { 496336db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 496476bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 496560e0710aSBarry 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]); 49669985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4967a061629eSStefano 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); 4968a061629eSStefano 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); 49699985e31cSBarry Smith } 497036db0b34SBarry Smith } 497176bd3646SJed Brown } 497276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 497336db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 497460e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 497560e0710aSBarry 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]); 497636db0b34SBarry Smith } 497776bd3646SJed Brown } 497836db0b34SBarry Smith 4979b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4980b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 498136db0b34SBarry Smith PetscFunctionReturn(0); 498236db0b34SBarry Smith } 498380ef6e79SMatthew G Knepley /*@C 4984d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 49858a0b0e6bSVictor Minden provided by the user. 49868a0b0e6bSVictor Minden 4987d083f849SBarry Smith Collective 49888a0b0e6bSVictor Minden 49898a0b0e6bSVictor Minden Input Parameters: 49908a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 49918a0b0e6bSVictor Minden . m - number of rows 49928a0b0e6bSVictor Minden . n - number of columns 49938a0b0e6bSVictor Minden . i - row indices 49948a0b0e6bSVictor Minden . j - column indices 49951230e6d1SVictor Minden . a - matrix values 49961230e6d1SVictor Minden . nz - number of nonzeros 49971230e6d1SVictor Minden - idx - 0 or 1 based 49988a0b0e6bSVictor Minden 49998a0b0e6bSVictor Minden Output Parameter: 50008a0b0e6bSVictor Minden . mat - the matrix 50018a0b0e6bSVictor Minden 50028a0b0e6bSVictor Minden Level: intermediate 50038a0b0e6bSVictor Minden 50048a0b0e6bSVictor Minden Notes: 50058a0b0e6bSVictor Minden The i and j indices are 0 based 50068a0b0e6bSVictor Minden 50078a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 50088a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 50098a0b0e6bSVictor Minden as shown: 50108a0b0e6bSVictor Minden 50118a0b0e6bSVictor Minden 1 0 0 50128a0b0e6bSVictor Minden 2 0 3 50138a0b0e6bSVictor Minden 4 5 6 50148a0b0e6bSVictor Minden 50158a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 50168a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 50178a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 50188a0b0e6bSVictor Minden 50198a0b0e6bSVictor Minden 502069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 50218a0b0e6bSVictor Minden 50228a0b0e6bSVictor Minden @*/ 5023c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 50248a0b0e6bSVictor Minden { 50258a0b0e6bSVictor Minden PetscErrorCode ierr; 5026d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 50278a0b0e6bSVictor Minden 50288a0b0e6bSVictor Minden 50298a0b0e6bSVictor Minden PetscFunctionBegin; 50301795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 50311230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 5032c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 50331230e6d1SVictor Minden } 50348a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 50358a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 50368a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 50371230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 50381230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 50391230e6d1SVictor Minden if (idx) { 50401230e6d1SVictor Minden row = i[ii] - 1; 50411230e6d1SVictor Minden col = j[ii] - 1; 50421230e6d1SVictor Minden } else { 50431230e6d1SVictor Minden row = i[ii]; 50441230e6d1SVictor Minden col = j[ii]; 50458a0b0e6bSVictor Minden } 50461230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 50478a0b0e6bSVictor Minden } 50488a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 50498a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5050d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 50518a0b0e6bSVictor Minden PetscFunctionReturn(0); 50528a0b0e6bSVictor Minden } 505336db0b34SBarry Smith 5054acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 5055acf2f550SJed Brown { 5056acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 5057acf2f550SJed Brown PetscErrorCode ierr; 5058acf2f550SJed Brown 5059acf2f550SJed Brown PetscFunctionBegin; 5060acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 5061acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 50622205254eSKarl Rupp 5063acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 5064acf2f550SJed Brown PetscFunctionReturn(0); 5065acf2f550SJed Brown } 5066acf2f550SJed Brown 50679c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 50689c8f2541SHong Zhang { 50699c8f2541SHong Zhang PetscErrorCode ierr; 50708761c3d6SHong Zhang PetscMPIInt size; 50719c8f2541SHong Zhang 50729c8f2541SHong Zhang PetscFunctionBegin; 5073ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 50747bbdc51dSHong Zhang if (size == 1) { 50757bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 50767bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 50777bbdc51dSHong Zhang } else { 50788761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 50797bbdc51dSHong Zhang } 50808761c3d6SHong Zhang } else { 50819c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 50828761c3d6SHong Zhang } 50839c8f2541SHong Zhang PetscFunctionReturn(0); 50849c8f2541SHong Zhang } 50859c8f2541SHong Zhang 508681824310SBarry Smith /* 508753dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 508853dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 508953dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 509053dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 509153dd7562SDmitry Karpeev */ 509253dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 509353dd7562SDmitry Karpeev { 509453dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 509553dd7562SDmitry Karpeev PetscErrorCode ierr; 509653dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 509753dd7562SDmitry Karpeev PetscBool seqaij; 509853dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 509953dd7562SDmitry Karpeev PetscScalar v; 510053dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 510153dd7562SDmitry Karpeev 510253dd7562SDmitry Karpeev PetscFunctionBegin; 510353dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 510453dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 51054099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 510653dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 510753dd7562SDmitry Karpeev if (rowemb) { 510853dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 510953dd7562SDmitry 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); 511053dd7562SDmitry Karpeev } else { 51116c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 511253dd7562SDmitry Karpeev } 511353dd7562SDmitry Karpeev if (colemb) { 511453dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 511553dd7562SDmitry 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); 511653dd7562SDmitry Karpeev } else { 511753dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 511853dd7562SDmitry Karpeev } 511953dd7562SDmitry Karpeev 512053dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 512153dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 512253dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 512353dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 512453dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 512553dd7562SDmitry Karpeev } 512653dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 512753dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 512853dd7562SDmitry Karpeev } 512953dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 513053dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 513153dd7562SDmitry Karpeev } 513253dd7562SDmitry Karpeev count = 0; 513353dd7562SDmitry Karpeev rowindices = NULL; 513453dd7562SDmitry Karpeev colindices = NULL; 513553dd7562SDmitry Karpeev if (rowemb) { 513653dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 513753dd7562SDmitry Karpeev } 513853dd7562SDmitry Karpeev if (colemb) { 513953dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 514053dd7562SDmitry Karpeev } 514153dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 514253dd7562SDmitry Karpeev PetscInt row; 514353dd7562SDmitry Karpeev row = i; 514453dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 514553dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 514653dd7562SDmitry Karpeev PetscInt col; 514753dd7562SDmitry Karpeev col = Baij->j[count]; 514853dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 514953dd7562SDmitry Karpeev v = Baij->a[count]; 515053dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 515153dd7562SDmitry Karpeev ++count; 515253dd7562SDmitry Karpeev } 515353dd7562SDmitry Karpeev } 515453dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 515553dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 515653dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 515753dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 515853dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 515953dd7562SDmitry Karpeev PetscFunctionReturn(0); 516053dd7562SDmitry Karpeev } 516153dd7562SDmitry Karpeev 51624099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 51634099cc6bSBarry Smith 51644099cc6bSBarry Smith /*@C 51654099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 51664099cc6bSBarry Smith 51674099cc6bSBarry Smith Collective on Mat 51684099cc6bSBarry Smith 51694099cc6bSBarry Smith Input Parameters: 51704099cc6bSBarry Smith + mat - the matrix object 51714099cc6bSBarry Smith - matype - matrix type 51724099cc6bSBarry Smith 51734099cc6bSBarry Smith Options Database Key: 51744099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 51754099cc6bSBarry Smith 51764099cc6bSBarry Smith 51774099cc6bSBarry Smith Level: intermediate 51784099cc6bSBarry Smith 51794099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 51804099cc6bSBarry Smith @*/ 51814099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 51824099cc6bSBarry Smith { 5183fd9d3c67SJed Brown PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*); 51844099cc6bSBarry Smith PetscBool sametype; 51854099cc6bSBarry Smith 51864099cc6bSBarry Smith PetscFunctionBegin; 51874099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 51884099cc6bSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 51894099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 51904099cc6bSBarry Smith 51914099cc6bSBarry Smith ierr = PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr); 51924099cc6bSBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 51934099cc6bSBarry Smith ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 51944099cc6bSBarry Smith PetscFunctionReturn(0); 51954099cc6bSBarry Smith } 51964099cc6bSBarry Smith 51974099cc6bSBarry Smith 51984099cc6bSBarry Smith /*@C 51994099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 52004099cc6bSBarry Smith 52014099cc6bSBarry Smith Not Collective 52024099cc6bSBarry Smith 52034099cc6bSBarry Smith Input Parameters: 52044099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 52054099cc6bSBarry Smith - function - routine to convert to subtype 52064099cc6bSBarry Smith 52074099cc6bSBarry Smith Notes: 52084099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 52094099cc6bSBarry Smith 52104099cc6bSBarry Smith 52114099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 52124099cc6bSBarry Smith $ -mat_seqaij_type my_mat 52134099cc6bSBarry Smith 52144099cc6bSBarry Smith Level: advanced 52154099cc6bSBarry Smith 52164099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 52174099cc6bSBarry Smith 52184099cc6bSBarry Smith 52194099cc6bSBarry Smith Level: advanced 52204099cc6bSBarry Smith @*/ 5221388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 52224099cc6bSBarry Smith { 52234099cc6bSBarry Smith PetscErrorCode ierr; 52244099cc6bSBarry Smith 52254099cc6bSBarry Smith PetscFunctionBegin; 52269cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 52274099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 52284099cc6bSBarry Smith PetscFunctionReturn(0); 52294099cc6bSBarry Smith } 52304099cc6bSBarry Smith 52314099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 52324099cc6bSBarry Smith 52334099cc6bSBarry Smith /*@C 52344099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 52354099cc6bSBarry Smith 52364099cc6bSBarry Smith Not Collective 52374099cc6bSBarry Smith 52384099cc6bSBarry Smith Level: advanced 52394099cc6bSBarry Smith 5240f719121fSJed Brown Developers Note: CUSPARSE does not yet support the MatConvert_SeqAIJ..() paradigm and thus cannot be registered here 52414099cc6bSBarry Smith 52424099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 52434099cc6bSBarry Smith @*/ 52444099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 52454099cc6bSBarry Smith { 52464099cc6bSBarry Smith PetscErrorCode ierr; 52474099cc6bSBarry Smith 52484099cc6bSBarry Smith PetscFunctionBegin; 52494099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 52504099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 52514099cc6bSBarry Smith 52524099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 52534099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 52544dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 52559779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 52566b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 5257485f9817SRichard Tran Mills #endif 52584099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 52594099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 52604099cc6bSBarry Smith #endif 52614099cc6bSBarry Smith PetscFunctionReturn(0); 52624099cc6bSBarry Smith } 526353dd7562SDmitry Karpeev 526453dd7562SDmitry Karpeev /* 526581824310SBarry Smith Special version for direct calls from Fortran 526681824310SBarry Smith */ 5267af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 526881824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 526981824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 527081824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 527181824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 527281824310SBarry Smith #endif 527381824310SBarry Smith 527481824310SBarry Smith /* Change these macros so can be used in void function */ 527581824310SBarry Smith #undef CHKERRQ 5276ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 527781824310SBarry Smith #undef SETERRQ2 5278e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 52794994cf47SJed Brown #undef SETERRQ3 52804994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 528181824310SBarry Smith 528219caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 528381824310SBarry Smith { 528481824310SBarry Smith Mat A = *AA; 528581824310SBarry Smith PetscInt m = *mm, n = *nn; 528681824310SBarry Smith InsertMode is = *isis; 528781824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 528881824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 528981824310SBarry Smith PetscInt *imax,*ai,*ailen; 529081824310SBarry Smith PetscErrorCode ierr; 529181824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 529254f21887SBarry Smith MatScalar *ap,value,*aa; 5293ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5294ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 529581824310SBarry Smith 529681824310SBarry Smith PetscFunctionBegin; 52974994cf47SJed Brown MatCheckPreallocated(A,1); 529881824310SBarry Smith imax = a->imax; 529981824310SBarry Smith ai = a->i; 530081824310SBarry Smith ailen = a->ilen; 530181824310SBarry Smith aj = a->j; 530281824310SBarry Smith aa = a->a; 530381824310SBarry Smith 530481824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 530581824310SBarry Smith row = im[k]; 530681824310SBarry Smith if (row < 0) continue; 5307cf9c20a2SJed Brown if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 530881824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 530981824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 531081824310SBarry Smith low = 0; 531181824310SBarry Smith high = nrow; 531281824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 531381824310SBarry Smith if (in[l] < 0) continue; 5314cf9c20a2SJed Brown if (PetscUnlikelyDebug(in[l] >= A->cmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 531581824310SBarry Smith col = in[l]; 53162205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 53172205254eSKarl Rupp else value = v[k + l*m]; 53182205254eSKarl Rupp 531981824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 532081824310SBarry Smith 53212205254eSKarl Rupp if (col <= lastcol) low = 0; 53222205254eSKarl Rupp else high = nrow; 532381824310SBarry Smith lastcol = col; 532481824310SBarry Smith while (high-low > 5) { 532581824310SBarry Smith t = (low+high)/2; 532681824310SBarry Smith if (rp[t] > col) high = t; 532781824310SBarry Smith else low = t; 532881824310SBarry Smith } 532981824310SBarry Smith for (i=low; i<high; i++) { 533081824310SBarry Smith if (rp[i] > col) break; 533181824310SBarry Smith if (rp[i] == col) { 533281824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 533381824310SBarry Smith else ap[i] = value; 533481824310SBarry Smith goto noinsert; 533581824310SBarry Smith } 533681824310SBarry Smith } 533781824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 533881824310SBarry Smith if (nonew == 1) goto noinsert; 5339ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5340fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 534181824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 534281824310SBarry Smith /* shift up all the later entries in this row */ 534381824310SBarry Smith for (ii=N; ii>=i; ii--) { 534481824310SBarry Smith rp[ii+1] = rp[ii]; 534581824310SBarry Smith ap[ii+1] = ap[ii]; 534681824310SBarry Smith } 534781824310SBarry Smith rp[i] = col; 534881824310SBarry Smith ap[i] = value; 5349e56f5c9eSBarry Smith A->nonzerostate++; 535081824310SBarry Smith noinsert:; 535181824310SBarry Smith low = i + 1; 535281824310SBarry Smith } 535381824310SBarry Smith ailen[row] = nrow; 535481824310SBarry Smith } 535581824310SBarry Smith PetscFunctionReturnVoid(); 535681824310SBarry Smith } 5357