1d5d45c9bSBarry Smith /* 23369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 3d5d45c9bSBarry Smith matrix storage format. 4d5d45c9bSBarry Smith */ 53369ce9aSBarry Smith 6c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 7c6db04a5SJed Brown #include <petscblaslapack.h> 8c6db04a5SJed Brown #include <petscbt.h> 9af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h> 100716a85fSBarry Smith 114099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetTypeFromOptions(Mat A) 124099cc6bSBarry Smith { 134099cc6bSBarry Smith PetscErrorCode ierr; 144099cc6bSBarry Smith PetscBool flg; 154099cc6bSBarry Smith char type[256]; 164099cc6bSBarry Smith 174099cc6bSBarry Smith PetscFunctionBegin; 18*1e1ea65dSPierre Jolivet ierr = PetscObjectOptionsBegin((PetscObject)A);CHKERRQ(ierr); 194099cc6bSBarry Smith ierr = PetscOptionsFList("-mat_seqaij_type","Matrix SeqAIJ type","MatSeqAIJSetType",MatSeqAIJList,"seqaij",type,256,&flg);CHKERRQ(ierr); 204099cc6bSBarry Smith if (flg) { 214099cc6bSBarry Smith ierr = MatSeqAIJSetType(A,type);CHKERRQ(ierr); 224099cc6bSBarry Smith } 234099cc6bSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 244099cc6bSBarry Smith PetscFunctionReturn(0); 254099cc6bSBarry Smith } 264099cc6bSBarry Smith 270716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms) 280716a85fSBarry Smith { 290716a85fSBarry Smith PetscErrorCode ierr; 300716a85fSBarry Smith PetscInt i,m,n; 310716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 320716a85fSBarry Smith 330716a85fSBarry Smith PetscFunctionBegin; 340716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 35580bdb30SBarry Smith ierr = PetscArrayzero(norms,n);CHKERRQ(ierr); 360716a85fSBarry Smith if (type == NORM_2) { 370716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 380716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 390716a85fSBarry Smith } 400716a85fSBarry Smith } else if (type == NORM_1) { 410716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 420716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]); 430716a85fSBarry Smith } 440716a85fSBarry Smith } else if (type == NORM_INFINITY) { 450716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 460716a85fSBarry Smith norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]); 470716a85fSBarry Smith } 480716a85fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType"); 490716a85fSBarry Smith 500716a85fSBarry Smith if (type == NORM_2) { 518f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 520716a85fSBarry Smith } 530716a85fSBarry Smith PetscFunctionReturn(0); 540716a85fSBarry Smith } 550716a85fSBarry Smith 563a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 573a062f41SBarry Smith { 583a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 593a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 603a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 613a062f41SBarry Smith PetscInt *rows; 623a062f41SBarry Smith PetscErrorCode ierr; 633a062f41SBarry Smith 643a062f41SBarry Smith PetscFunctionBegin; 653a062f41SBarry Smith for (i=0; i<m; i++) { 663a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 673a062f41SBarry Smith cnt++; 683a062f41SBarry Smith } 693a062f41SBarry Smith } 703a062f41SBarry Smith ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 713a062f41SBarry Smith cnt = 0; 723a062f41SBarry Smith for (i=0; i<m; i++) { 733a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 743a062f41SBarry Smith rows[cnt] = i; 753a062f41SBarry Smith cnt++; 763a062f41SBarry Smith } 773a062f41SBarry Smith } 783a062f41SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr); 793a062f41SBarry Smith PetscFunctionReturn(0); 803a062f41SBarry Smith } 813a062f41SBarry Smith 82f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 836ce1633cSBarry Smith { 846ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 856ce1633cSBarry Smith const MatScalar *aa = a->a; 866ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 87b2db7409Sstefano_zampini const PetscInt *ii = a->i,*jj = a->j,*diag; 886ce1633cSBarry Smith PetscInt *rows; 896ce1633cSBarry Smith PetscErrorCode ierr; 906ce1633cSBarry Smith 916ce1633cSBarry Smith PetscFunctionBegin; 926ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 936ce1633cSBarry Smith diag = a->diag; 946ce1633cSBarry Smith for (i=0; i<m; i++) { 95b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 966ce1633cSBarry Smith cnt++; 976ce1633cSBarry Smith } 986ce1633cSBarry Smith } 99785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 1006ce1633cSBarry Smith cnt = 0; 1016ce1633cSBarry Smith for (i=0; i<m; i++) { 102b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1036ce1633cSBarry Smith rows[cnt++] = i; 1046ce1633cSBarry Smith } 1056ce1633cSBarry Smith } 106f1f41ecbSJed Brown *nrows = cnt; 107f1f41ecbSJed Brown *zrows = rows; 108f1f41ecbSJed Brown PetscFunctionReturn(0); 109f1f41ecbSJed Brown } 110f1f41ecbSJed Brown 111f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 112f1f41ecbSJed Brown { 113f1f41ecbSJed Brown PetscInt nrows,*rows; 114f1f41ecbSJed Brown PetscErrorCode ierr; 115f1f41ecbSJed Brown 116f1f41ecbSJed Brown PetscFunctionBegin; 1170298fd71SBarry Smith *zrows = NULL; 118f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 119ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1206ce1633cSBarry Smith PetscFunctionReturn(0); 1216ce1633cSBarry Smith } 1226ce1633cSBarry Smith 123b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 124b3a44c85SBarry Smith { 125b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 126b3a44c85SBarry Smith const MatScalar *aa; 127b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 128b3a44c85SBarry Smith const PetscInt *ii; 129b3a44c85SBarry Smith PetscInt n,i,j,*rows; 130b3a44c85SBarry Smith PetscErrorCode ierr; 131b3a44c85SBarry Smith 132b3a44c85SBarry Smith PetscFunctionBegin; 1332e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 134f4259b30SLisandro Dalcin *keptrows = NULL; 135b3a44c85SBarry Smith ii = a->i; 136b3a44c85SBarry Smith for (i=0; i<m; i++) { 137b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 138b3a44c85SBarry Smith if (!n) { 139b3a44c85SBarry Smith cnt++; 140b3a44c85SBarry Smith goto ok1; 141b3a44c85SBarry Smith } 1422e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 143b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 144b3a44c85SBarry Smith } 145b3a44c85SBarry Smith cnt++; 146b3a44c85SBarry Smith ok1:; 147b3a44c85SBarry Smith } 1482e5835c6SStefano Zampini if (!cnt) { 1492e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 1502e5835c6SStefano Zampini PetscFunctionReturn(0); 1512e5835c6SStefano Zampini } 152854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr); 153b3a44c85SBarry Smith cnt = 0; 154b3a44c85SBarry Smith for (i=0; i<m; i++) { 155b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 156b3a44c85SBarry Smith if (!n) continue; 1572e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 158b3a44c85SBarry Smith if (aa[j] != 0.0) { 159b3a44c85SBarry Smith rows[cnt++] = i; 160b3a44c85SBarry Smith break; 161b3a44c85SBarry Smith } 162b3a44c85SBarry Smith } 163b3a44c85SBarry Smith } 1642e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 165b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 166b3a44c85SBarry Smith PetscFunctionReturn(0); 167b3a44c85SBarry Smith } 168b3a44c85SBarry Smith 1697087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 17079299369SBarry Smith { 17179299369SBarry Smith PetscErrorCode ierr; 17279299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 17399e65526SBarry Smith PetscInt i,m = Y->rmap->n; 17499e65526SBarry Smith const PetscInt *diag; 1752e5835c6SStefano Zampini MatScalar *aa; 17699e65526SBarry Smith const PetscScalar *v; 177ace3abfcSBarry Smith PetscBool missing; 1788c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 179837a59e1SRichard Tran Mills PetscBool inserted = PETSC_FALSE; 180837a59e1SRichard Tran Mills #endif 18179299369SBarry Smith 18279299369SBarry Smith PetscFunctionBegin; 18309f38230SBarry Smith if (Y->assembled) { 1840298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 18509f38230SBarry Smith if (!missing) { 18679299369SBarry Smith diag = aij->diag; 18799e65526SBarry Smith ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr); 1882e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(Y,&aa);CHKERRQ(ierr); 18979299369SBarry Smith if (is == INSERT_VALUES) { 1908c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 191837a59e1SRichard Tran Mills inserted = PETSC_TRUE; 192837a59e1SRichard Tran Mills #endif 19379299369SBarry Smith for (i=0; i<m; i++) { 19479299369SBarry Smith aa[diag[i]] = v[i]; 19579299369SBarry Smith } 19679299369SBarry Smith } else { 19779299369SBarry Smith for (i=0; i<m; i++) { 1988c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 199837a59e1SRichard Tran Mills if (v[i] != 0.0) inserted = PETSC_TRUE; 200837a59e1SRichard Tran Mills #endif 20179299369SBarry Smith aa[diag[i]] += v[i]; 20279299369SBarry Smith } 20379299369SBarry Smith } 2042e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(Y,&aa);CHKERRQ(ierr); 2058c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 206837a59e1SRichard Tran Mills if (inserted) Y->offloadmask = PETSC_OFFLOAD_CPU; 207837a59e1SRichard Tran Mills #endif 20899e65526SBarry Smith ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr); 20979299369SBarry Smith PetscFunctionReturn(0); 21079299369SBarry Smith } 211acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 21209f38230SBarry Smith } 21309f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 21409f38230SBarry Smith PetscFunctionReturn(0); 21509f38230SBarry Smith } 21679299369SBarry Smith 2171a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 21817ab2063SBarry Smith { 219416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 220dfbe8321SBarry Smith PetscErrorCode ierr; 22197f1f81fSBarry Smith PetscInt i,ishift; 22217ab2063SBarry Smith 2233a40ed3dSBarry Smith PetscFunctionBegin; 224d0f46423SBarry Smith *m = A->rmap->n; 2253a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 226bfeeae90SHong Zhang ishift = 0; 22753e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 2282462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 229bfeeae90SHong Zhang } else if (oshift == 1) { 2301a83f524SJed Brown PetscInt *tia; 231d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2323b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 233854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr); 2341a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2351a83f524SJed Brown *ia = tia; 236ecc77c7aSBarry Smith if (ja) { 2371a83f524SJed Brown PetscInt *tja; 238854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr); 2391a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2401a83f524SJed Brown *ja = tja; 241ecc77c7aSBarry Smith } 2426945ee14SBarry Smith } else { 243ecc77c7aSBarry Smith *ia = a->i; 244ecc77c7aSBarry Smith if (ja) *ja = a->j; 245a2ce50c7SBarry Smith } 2463a40ed3dSBarry Smith PetscFunctionReturn(0); 247a2744918SBarry Smith } 248a2744918SBarry Smith 2491a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2506945ee14SBarry Smith { 251dfbe8321SBarry Smith PetscErrorCode ierr; 2526945ee14SBarry Smith 2533a40ed3dSBarry Smith PetscFunctionBegin; 2543a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 255bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 256606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 257ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 258bcd2baecSBarry Smith } 2593a40ed3dSBarry Smith PetscFunctionReturn(0); 26017ab2063SBarry Smith } 26117ab2063SBarry Smith 2621a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2633b2fbd54SBarry Smith { 2643b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 265dfbe8321SBarry Smith PetscErrorCode ierr; 266d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 26797f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2683b2fbd54SBarry Smith 2693a40ed3dSBarry Smith PetscFunctionBegin; 270899cda47SBarry Smith *nn = n; 2713a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2723b2fbd54SBarry Smith if (symmetric) { 2732462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2743b2fbd54SBarry Smith } else { 275b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 276854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 277b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 2783b2fbd54SBarry Smith jj = a->j; 2793b2fbd54SBarry Smith for (i=0; i<nz; i++) { 280bfeeae90SHong Zhang collengths[jj[i]]++; 2813b2fbd54SBarry Smith } 2823b2fbd54SBarry Smith cia[0] = oshift; 2833b2fbd54SBarry Smith for (i=0; i<n; i++) { 2843b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2853b2fbd54SBarry Smith } 286580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 2873b2fbd54SBarry Smith jj = a->j; 288a93ec695SBarry Smith for (row=0; row<m; row++) { 289a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 290a93ec695SBarry Smith for (i=0; i<mr; i++) { 291bfeeae90SHong Zhang col = *jj++; 2922205254eSKarl Rupp 2933b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2943b2fbd54SBarry Smith } 2953b2fbd54SBarry Smith } 296606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2973b2fbd54SBarry Smith *ia = cia; *ja = cja; 2983b2fbd54SBarry Smith } 2993a40ed3dSBarry Smith PetscFunctionReturn(0); 3003b2fbd54SBarry Smith } 3013b2fbd54SBarry Smith 3021a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 3033b2fbd54SBarry Smith { 304dfbe8321SBarry Smith PetscErrorCode ierr; 305606d414cSSatish Balay 3063a40ed3dSBarry Smith PetscFunctionBegin; 3073a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 3083b2fbd54SBarry Smith 309606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 310606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 3113a40ed3dSBarry Smith PetscFunctionReturn(0); 3123b2fbd54SBarry Smith } 3133b2fbd54SBarry Smith 3147cee066cSHong Zhang /* 3157cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 3167cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 317040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 3187cee066cSHong Zhang */ 3197cee066cSHong 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) 3207cee066cSHong Zhang { 3217cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3227cee066cSHong Zhang PetscErrorCode ierr; 3237cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 324071fcb05SBarry Smith PetscInt nz = a->i[m],row,mr,col,tmp; 3257cee066cSHong Zhang PetscInt *cspidx; 326071fcb05SBarry Smith const PetscInt *jj; 3277cee066cSHong Zhang 3287cee066cSHong Zhang PetscFunctionBegin; 3297cee066cSHong Zhang *nn = n; 3307cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 331625f6d37SHong Zhang 332b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 333854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 334b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 335b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cspidx);CHKERRQ(ierr); 3367cee066cSHong Zhang jj = a->j; 3377cee066cSHong Zhang for (i=0; i<nz; i++) { 3387cee066cSHong Zhang collengths[jj[i]]++; 3397cee066cSHong Zhang } 3407cee066cSHong Zhang cia[0] = oshift; 3417cee066cSHong Zhang for (i=0; i<n; i++) { 3427cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3437cee066cSHong Zhang } 344580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 3457cee066cSHong Zhang jj = a->j; 3467cee066cSHong Zhang for (row=0; row<m; row++) { 3477cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3487cee066cSHong Zhang for (i=0; i<mr; i++) { 3497cee066cSHong Zhang col = *jj++; 350071fcb05SBarry Smith tmp = cia[col] + collengths[col]++ - oshift; 351071fcb05SBarry Smith cspidx[tmp] = a->i[row] + i; /* index of a->j */ 352071fcb05SBarry Smith cja[tmp] = row + oshift; 3537cee066cSHong Zhang } 3547cee066cSHong Zhang } 3557cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 356071fcb05SBarry Smith *ia = cia; 357071fcb05SBarry Smith *ja = cja; 3587cee066cSHong Zhang *spidx = cspidx; 3597cee066cSHong Zhang PetscFunctionReturn(0); 3607cee066cSHong Zhang } 3617cee066cSHong Zhang 3627cee066cSHong 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) 3637cee066cSHong Zhang { 3647cee066cSHong Zhang PetscErrorCode ierr; 3657cee066cSHong Zhang 3667cee066cSHong Zhang PetscFunctionBegin; 3675243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3687cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3697cee066cSHong Zhang PetscFunctionReturn(0); 3707cee066cSHong Zhang } 3717cee066cSHong Zhang 37287d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 37387d4246cSBarry Smith { 37487d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 37587d4246cSBarry Smith PetscInt *ai = a->i; 37687d4246cSBarry Smith PetscErrorCode ierr; 37787d4246cSBarry Smith 37887d4246cSBarry Smith PetscFunctionBegin; 379580bdb30SBarry Smith ierr = PetscArraycpy(a->a+ai[row],v,ai[row+1]-ai[row]);CHKERRQ(ierr); 3808c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 381c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && ai[row+1]-ai[row]) A->offloadmask = PETSC_OFFLOAD_CPU; 382e2cf4d64SStefano Zampini #endif 38387d4246cSBarry Smith PetscFunctionReturn(0); 38487d4246cSBarry Smith } 38587d4246cSBarry Smith 386bd04181cSBarry Smith /* 387bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 388bd04181cSBarry Smith 389bd04181cSBarry Smith - a single row of values is set with each call 390bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 391bd04181cSBarry Smith - the values are always added to the matrix, not set 392bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 393bd04181cSBarry Smith 3941f763a69SBarry Smith This does NOT assume the global column indices are sorted 395bd04181cSBarry Smith 3961f763a69SBarry Smith */ 397bd04181cSBarry Smith 398af0996ceSBarry Smith #include <petsc/private/isimpl.h> 399189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 400189e4007SBarry Smith { 401189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4021f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 4031f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 4041f763a69SBarry Smith PetscInt lastcol = -1; 405189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 406189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 407189e4007SBarry Smith 408f38dd0b8SBarry Smith row = ridx[im[0]]; 4091f763a69SBarry Smith rp = aj + ai[row]; 4101f763a69SBarry Smith ap = aa + ai[row]; 4111f763a69SBarry Smith nrow = ailen[row]; 412189e4007SBarry Smith low = 0; 413189e4007SBarry Smith high = nrow; 414189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 415189e4007SBarry Smith col = cidx[in[l]]; 416f38dd0b8SBarry Smith value = v[l]; 417189e4007SBarry Smith 418189e4007SBarry Smith if (col <= lastcol) low = 0; 419189e4007SBarry Smith else high = nrow; 420189e4007SBarry Smith lastcol = col; 421189e4007SBarry Smith while (high-low > 5) { 422189e4007SBarry Smith t = (low+high)/2; 423189e4007SBarry Smith if (rp[t] > col) high = t; 424189e4007SBarry Smith else low = t; 425189e4007SBarry Smith } 426189e4007SBarry Smith for (i=low; i<high; i++) { 427189e4007SBarry Smith if (rp[i] == col) { 4281f763a69SBarry Smith ap[i] += value; 429189e4007SBarry Smith low = i + 1; 4301f763a69SBarry Smith break; 431189e4007SBarry Smith } 432189e4007SBarry Smith } 433189e4007SBarry Smith } 4348c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 435c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 436e2cf4d64SStefano Zampini #endif 437f38dd0b8SBarry Smith return 0; 438189e4007SBarry Smith } 439189e4007SBarry Smith 44097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 44117ab2063SBarry Smith { 442416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 443e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 44497f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 4456849ba73SBarry Smith PetscErrorCode ierr; 446e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 447ce496241SStefano Zampini MatScalar *ap=NULL,value=0.0,*aa; 448ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 449ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 4508c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 451e2cf4d64SStefano Zampini PetscBool inserted = PETSC_FALSE; 452e2cf4d64SStefano Zampini #endif 45317ab2063SBarry Smith 4543a40ed3dSBarry Smith PetscFunctionBegin; 455ce496241SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 456ce496241SStefano Zampini if (A->offloadmask == PETSC_OFFLOAD_GPU) { 457ce496241SStefano Zampini const PetscScalar *dummy; 458ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&dummy);CHKERRQ(ierr); 459ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&dummy);CHKERRQ(ierr); 460ce496241SStefano Zampini } 461ce496241SStefano Zampini #endif 462ce496241SStefano Zampini aa = a->a; 46317ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 464416022c9SBarry Smith row = im[k]; 4655ef9f2a5SBarry Smith if (row < 0) continue; 466cf9c20a2SJed 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); 467720833daSHong Zhang rp = aj + ai[row]; 468876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 46917ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 470416022c9SBarry Smith low = 0; 471c71e6ed7SBarry Smith high = nrow; 47217ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4735ef9f2a5SBarry Smith if (in[l] < 0) continue; 474cf9c20a2SJed 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); 475bfeeae90SHong Zhang col = in[l]; 476071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 477071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 47836db0b34SBarry Smith 4792205254eSKarl Rupp if (col <= lastcol) low = 0; 4802205254eSKarl Rupp else high = nrow; 481e2ee6c50SBarry Smith lastcol = col; 482416022c9SBarry Smith while (high-low > 5) { 483416022c9SBarry Smith t = (low+high)/2; 484416022c9SBarry Smith if (rp[t] > col) high = t; 485416022c9SBarry Smith else low = t; 48617ab2063SBarry Smith } 487416022c9SBarry Smith for (i=low; i<high; i++) { 48817ab2063SBarry Smith if (rp[i] > col) break; 48917ab2063SBarry Smith if (rp[i] == col) { 490876c6284SHong Zhang if (!A->structure_only) { 4910c0d7e18SFande Kong if (is == ADD_VALUES) { 4920c0d7e18SFande Kong ap[i] += value; 4930c0d7e18SFande Kong (void)PetscLogFlops(1.0); 4940c0d7e18SFande Kong } 49517ab2063SBarry Smith else ap[i] = value; 4968c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 497e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 498e2cf4d64SStefano Zampini #endif 499720833daSHong Zhang } 500e44c0bd4SBarry Smith low = i + 1; 50117ab2063SBarry Smith goto noinsert; 50217ab2063SBarry Smith } 50317ab2063SBarry Smith } 504dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 505c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 506e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 507720833daSHong Zhang if (A->structure_only) { 508876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 509720833daSHong Zhang } else { 510fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 511720833daSHong Zhang } 512c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 513416022c9SBarry Smith /* shift up all the later entries in this row */ 514580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 51517ab2063SBarry Smith rp[i] = col; 516580bdb30SBarry Smith if (!A->structure_only) { 517580bdb30SBarry Smith ierr = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr); 518580bdb30SBarry Smith ap[i] = value; 519580bdb30SBarry Smith } 520416022c9SBarry Smith low = i + 1; 521e56f5c9eSBarry Smith A->nonzerostate++; 5228c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 523e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 524e2cf4d64SStefano Zampini #endif 525e44c0bd4SBarry Smith noinsert:; 52617ab2063SBarry Smith } 52717ab2063SBarry Smith ailen[row] = nrow; 52817ab2063SBarry Smith } 5298c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 530c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && inserted) A->offloadmask = PETSC_OFFLOAD_CPU; 531e2cf4d64SStefano Zampini #endif 5323a40ed3dSBarry Smith PetscFunctionReturn(0); 53317ab2063SBarry Smith } 53417ab2063SBarry Smith 53519b08ed1SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFullNoPreallocation(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 53619b08ed1SBarry Smith { 53719b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 53819b08ed1SBarry Smith PetscInt *rp,k,row; 53919b08ed1SBarry Smith PetscInt *ai = a->i; 54019b08ed1SBarry Smith PetscErrorCode ierr; 54119b08ed1SBarry Smith PetscInt *aj = a->j; 54219b08ed1SBarry Smith MatScalar *aa = a->a,*ap; 54319b08ed1SBarry Smith 54419b08ed1SBarry Smith PetscFunctionBegin; 54519b08ed1SBarry Smith if (A->was_assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call on assembled matrix."); 54619b08ed1SBarry 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); 54719b08ed1SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 54819b08ed1SBarry Smith row = im[k]; 54919b08ed1SBarry Smith rp = aj + ai[row]; 55019b08ed1SBarry Smith ap = aa + ai[row]; 55119b08ed1SBarry Smith 55219b08ed1SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 55319b08ed1SBarry Smith if (!A->structure_only) { 55419b08ed1SBarry Smith if (v) { 55519b08ed1SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 55619b08ed1SBarry Smith v += n; 55719b08ed1SBarry Smith } else { 55819b08ed1SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 55919b08ed1SBarry Smith } 56019b08ed1SBarry Smith } 56119b08ed1SBarry Smith a->ilen[row] = n; 56219b08ed1SBarry Smith a->imax[row] = n; 56319b08ed1SBarry Smith a->i[row+1] = a->i[row]+n; 56419b08ed1SBarry Smith a->nz += n; 56519b08ed1SBarry Smith } 5668c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 56719b08ed1SBarry Smith if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 56819b08ed1SBarry Smith #endif 56919b08ed1SBarry Smith PetscFunctionReturn(0); 57019b08ed1SBarry Smith } 57119b08ed1SBarry Smith 57219b08ed1SBarry Smith /*@ 57319b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation - Sets an upper bound on the total number of expected nonzeros in the matrix. 57419b08ed1SBarry Smith 57519b08ed1SBarry Smith Input Parameters: 57619b08ed1SBarry Smith + A - the SeqAIJ matrix 57719b08ed1SBarry Smith - nztotal - bound on the number of nonzeros 57819b08ed1SBarry Smith 57919b08ed1SBarry Smith Level: advanced 58019b08ed1SBarry Smith 58119b08ed1SBarry Smith Notes: 58219b08ed1SBarry 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. 58319b08ed1SBarry Smith Simply call MatSetValues() after this call to provide the matrix entries in the usual manner. This matrix may be used 58419b08ed1SBarry Smith as always with multiple matrix assemblies. 58519b08ed1SBarry Smith 58619b08ed1SBarry Smith .seealso: MatSetOption(), MAT_SORTED_FULL, MatSetValues(), MatSeqAIJSetPreallocation() 58719b08ed1SBarry Smith @*/ 58819b08ed1SBarry Smith 58919b08ed1SBarry Smith PetscErrorCode MatSeqAIJSetTotalPreallocation(Mat A,PetscInt nztotal) 59019b08ed1SBarry Smith { 59119b08ed1SBarry Smith PetscErrorCode ierr; 59219b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 59319b08ed1SBarry Smith 59419b08ed1SBarry Smith PetscFunctionBegin; 59519b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 59619b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 59719b08ed1SBarry Smith a->maxnz = nztotal; 59819b08ed1SBarry Smith if (!a->imax) { 59919b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->imax);CHKERRQ(ierr); 60019b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 60119b08ed1SBarry Smith } 60219b08ed1SBarry Smith if (!a->ilen) { 60319b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->ilen);CHKERRQ(ierr); 60419b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 60519b08ed1SBarry Smith } else { 60619b08ed1SBarry Smith ierr = PetscMemzero(a->ilen,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 60719b08ed1SBarry Smith } 60819b08ed1SBarry Smith 60919b08ed1SBarry Smith /* allocate the matrix space */ 61019b08ed1SBarry Smith if (A->structure_only) { 61119b08ed1SBarry Smith ierr = PetscMalloc1(nztotal,&a->j);CHKERRQ(ierr); 61219b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&a->i);CHKERRQ(ierr); 61319b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*sizeof(PetscInt));CHKERRQ(ierr); 61419b08ed1SBarry Smith } else { 61519b08ed1SBarry Smith ierr = PetscMalloc3(nztotal,&a->a,nztotal,&a->j,A->rmap->n+1,&a->i);CHKERRQ(ierr); 61619b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 61719b08ed1SBarry Smith } 61819b08ed1SBarry Smith a->i[0] = 0; 61919b08ed1SBarry Smith if (A->structure_only) { 62019b08ed1SBarry Smith a->singlemalloc = PETSC_FALSE; 62119b08ed1SBarry Smith a->free_a = PETSC_FALSE; 62219b08ed1SBarry Smith } else { 62319b08ed1SBarry Smith a->singlemalloc = PETSC_TRUE; 62419b08ed1SBarry Smith a->free_a = PETSC_TRUE; 62519b08ed1SBarry Smith } 62619b08ed1SBarry Smith a->free_ij = PETSC_TRUE; 62719b08ed1SBarry Smith A->ops->setvalues = MatSetValues_SeqAIJ_SortedFullNoPreallocation; 62819b08ed1SBarry Smith A->preallocated = PETSC_TRUE; 62919b08ed1SBarry Smith PetscFunctionReturn(0); 63019b08ed1SBarry Smith } 63119b08ed1SBarry Smith 632071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 633071fcb05SBarry Smith { 634071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 635071fcb05SBarry Smith PetscInt *rp,k,row; 636071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 637071fcb05SBarry Smith PetscErrorCode ierr; 638071fcb05SBarry Smith PetscInt *aj = a->j; 639071fcb05SBarry Smith MatScalar *aa = a->a,*ap; 640071fcb05SBarry Smith 641071fcb05SBarry Smith PetscFunctionBegin; 642071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 643071fcb05SBarry Smith row = im[k]; 64419b08ed1SBarry 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); 645071fcb05SBarry Smith rp = aj + ai[row]; 646071fcb05SBarry Smith ap = aa + ai[row]; 647071fcb05SBarry Smith if (!A->was_assembled) { 648071fcb05SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 649071fcb05SBarry Smith } 650071fcb05SBarry Smith if (!A->structure_only) { 651071fcb05SBarry Smith if (v) { 652071fcb05SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 653071fcb05SBarry Smith v += n; 654071fcb05SBarry Smith } else { 655071fcb05SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 656071fcb05SBarry Smith } 657071fcb05SBarry Smith } 658071fcb05SBarry Smith ailen[row] = n; 659071fcb05SBarry Smith a->nz += n; 660071fcb05SBarry Smith } 6618c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 662c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 663e2cf4d64SStefano Zampini #endif 664071fcb05SBarry Smith PetscFunctionReturn(0); 665071fcb05SBarry Smith } 666071fcb05SBarry Smith 667a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 6687eb43aa7SLois Curfman McInnes { 6697eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 67097f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 67197f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 67254f21887SBarry Smith MatScalar *ap,*aa = a->a; 6737eb43aa7SLois Curfman McInnes 6743a40ed3dSBarry Smith PetscFunctionBegin; 6757eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 6767eb43aa7SLois Curfman McInnes row = im[k]; 677e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 678e32f2f54SBarry 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); 679bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 6807eb43aa7SLois Curfman McInnes nrow = ailen[row]; 6817eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 682e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 683e32f2f54SBarry 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); 684bfeeae90SHong Zhang col = in[l]; 6857eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 6867eb43aa7SLois Curfman McInnes while (high-low > 5) { 6877eb43aa7SLois Curfman McInnes t = (low+high)/2; 6887eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 6897eb43aa7SLois Curfman McInnes else low = t; 6907eb43aa7SLois Curfman McInnes } 6917eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 6927eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 6937eb43aa7SLois Curfman McInnes if (rp[i] == col) { 694b49de8d1SLois Curfman McInnes *v++ = ap[i]; 6957eb43aa7SLois Curfman McInnes goto finished; 6967eb43aa7SLois Curfman McInnes } 6977eb43aa7SLois Curfman McInnes } 69897e567efSBarry Smith *v++ = 0.0; 6997eb43aa7SLois Curfman McInnes finished:; 7007eb43aa7SLois Curfman McInnes } 7017eb43aa7SLois Curfman McInnes } 7023a40ed3dSBarry Smith PetscFunctionReturn(0); 7037eb43aa7SLois Curfman McInnes } 7047eb43aa7SLois Curfman McInnes 7053ea6fe3dSLisandro Dalcin PetscErrorCode MatView_SeqAIJ_Binary(Mat mat,PetscViewer viewer) 70617ab2063SBarry Smith { 7073ea6fe3dSLisandro Dalcin Mat_SeqAIJ *A = (Mat_SeqAIJ*)mat->data; 708c898d852SStefano Zampini const PetscScalar *av; 7093ea6fe3dSLisandro Dalcin PetscInt header[4],M,N,m,nz,i; 7103ea6fe3dSLisandro Dalcin PetscInt *rowlens; 7116849ba73SBarry Smith PetscErrorCode ierr; 71217ab2063SBarry Smith 7133a40ed3dSBarry Smith PetscFunctionBegin; 7143ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 7152205254eSKarl Rupp 7163ea6fe3dSLisandro Dalcin M = mat->rmap->N; 7173ea6fe3dSLisandro Dalcin N = mat->cmap->N; 7183ea6fe3dSLisandro Dalcin m = mat->rmap->n; 7193ea6fe3dSLisandro Dalcin nz = A->nz; 720416022c9SBarry Smith 7213ea6fe3dSLisandro Dalcin /* write matrix header */ 7223ea6fe3dSLisandro Dalcin header[0] = MAT_FILE_CLASSID; 7233ea6fe3dSLisandro Dalcin header[1] = M; header[2] = N; header[3] = nz; 7243ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr); 725416022c9SBarry Smith 7263ea6fe3dSLisandro Dalcin /* fill in and store row lengths */ 7273ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(m,&rowlens);CHKERRQ(ierr); 7283ea6fe3dSLisandro Dalcin for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i]; 7293ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT);CHKERRQ(ierr); 7303ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 7313ea6fe3dSLisandro Dalcin /* store column indices */ 7323ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT);CHKERRQ(ierr); 733416022c9SBarry Smith /* store nonzero values */ 734c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(mat,&av);CHKERRQ(ierr); 735c898d852SStefano Zampini ierr = PetscViewerBinaryWrite(viewer,av,nz,PETSC_SCALAR);CHKERRQ(ierr); 736c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(mat,&av);CHKERRQ(ierr); 737b37d52dbSMark F. Adams 7383ea6fe3dSLisandro Dalcin /* write block size option to the viewer's .info file */ 7393ea6fe3dSLisandro Dalcin ierr = MatView_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 7403a40ed3dSBarry Smith PetscFunctionReturn(0); 74117ab2063SBarry Smith } 742416022c9SBarry Smith 7437dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 7447dc0baabSHong Zhang { 7457dc0baabSHong Zhang PetscErrorCode ierr; 7467dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7477dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 7487dc0baabSHong Zhang 7497dc0baabSHong Zhang PetscFunctionBegin; 7507dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7517dc0baabSHong Zhang for (i=0; i<m; i++) { 7527dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 7537dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 7547dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 7557dc0baabSHong Zhang } 7567dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 7577dc0baabSHong Zhang } 7587dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7597dc0baabSHong Zhang PetscFunctionReturn(0); 7607dc0baabSHong Zhang } 7617dc0baabSHong Zhang 76209573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 763cd155464SBarry Smith 764dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 765416022c9SBarry Smith { 766416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 767c898d852SStefano Zampini const PetscScalar *av; 768dfbe8321SBarry Smith PetscErrorCode ierr; 76960e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 770e060cb09SBarry Smith const char *name; 771f3ef73ceSBarry Smith PetscViewerFormat format; 77217ab2063SBarry Smith 7733a40ed3dSBarry Smith PetscFunctionBegin; 7747dc0baabSHong Zhang if (A->structure_only) { 7757dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 7767dc0baabSHong Zhang PetscFunctionReturn(0); 7777dc0baabSHong Zhang } 77843e49210SHong Zhang 779b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 7802e5835c6SStefano Zampini if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 7812e5835c6SStefano Zampini 782c898d852SStefano Zampini /* trigger copy to CPU if needed */ 783c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 784c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 78571c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 78697f1f81fSBarry Smith PetscInt nofinalvalue = 0; 78760e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 788c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 789d00d2cf4SBarry Smith nofinalvalue = 1; 790d00d2cf4SBarry Smith } 791d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 792d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 79377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 794fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 795fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 796fbfe6fa7SJed Brown #else 79777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 798fbfe6fa7SJed Brown #endif 799b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 80017ab2063SBarry Smith 80117ab2063SBarry Smith for (i=0; i<m; i++) { 80260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 803aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 804a9bf72d8SJed 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); 80517ab2063SBarry Smith #else 80660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 80717ab2063SBarry Smith #endif 80817ab2063SBarry Smith } 80917ab2063SBarry Smith } 810d00d2cf4SBarry Smith if (nofinalvalue) { 811c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 812c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 813c337ccceSJed Brown #else 814d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 815c337ccceSJed Brown #endif 816d00d2cf4SBarry Smith } 817317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 818fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 819d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 820fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 821d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 82244cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 82377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 82460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 825aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 82636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 82760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 82836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 82960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 83036db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 83160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 8326831982aSBarry Smith } 83344cd7ae7SLois Curfman McInnes #else 83460e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 83544cd7ae7SLois Curfman McInnes #endif 83644cd7ae7SLois Curfman McInnes } 837b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 83844cd7ae7SLois Curfman McInnes } 839d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 840fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 84197f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 842d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 843854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 844496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 845496be53dSLois Curfman McInnes sptr[i] = nzd+1; 84660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 847496be53dSLois Curfman McInnes if (a->j[j] >= i) { 848aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 84936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 850496be53dSLois Curfman McInnes #else 851496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 852496be53dSLois Curfman McInnes #endif 853496be53dSLois Curfman McInnes } 854496be53dSLois Curfman McInnes } 855496be53dSLois Curfman McInnes } 8562e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 85777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 8582e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 8592205254eSKarl Rupp if (i+4<m) { 8602205254eSKarl 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); 8612205254eSKarl Rupp } else if (i+3<m) { 8622205254eSKarl 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); 8632205254eSKarl Rupp } else if (i+2<m) { 8642205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 8652205254eSKarl Rupp } else if (i+1<m) { 8662205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 8672205254eSKarl Rupp } else if (i<m) { 8682205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 8692205254eSKarl Rupp } else { 8702205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 8712205254eSKarl Rupp } 872496be53dSLois Curfman McInnes } 873b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 874606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 875496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 87660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 87777431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 878496be53dSLois Curfman McInnes } 879b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 880496be53dSLois Curfman McInnes } 881b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 882496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 88360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 884496be53dSLois Curfman McInnes if (a->j[j] >= i) { 885aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 88636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 88760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8886831982aSBarry Smith } 889496be53dSLois Curfman McInnes #else 89060e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 891496be53dSLois Curfman McInnes #endif 892496be53dSLois Curfman McInnes } 893496be53dSLois Curfman McInnes } 894b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 895496be53dSLois Curfman McInnes } 896d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 897fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 89897f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 89987828ca2SBarry Smith PetscScalar value; 90068f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 90168f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 90268f1ed48SBarry Smith 90368f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 90468f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 90568f1ed48SBarry Smith realonly = PETSC_FALSE; 90668f1ed48SBarry Smith break; 90768f1ed48SBarry Smith } 90868f1ed48SBarry Smith } 90968f1ed48SBarry Smith #endif 91002594712SBarry Smith 911d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 91202594712SBarry Smith for (i=0; i<m; i++) { 91302594712SBarry Smith jcnt = 0; 914d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 915e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 91602594712SBarry Smith value = a->a[cnt++]; 917e24b481bSBarry Smith jcnt++; 91802594712SBarry Smith } else { 91902594712SBarry Smith value = 0.0; 92002594712SBarry Smith } 921aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 92268f1ed48SBarry Smith if (realonly) { 92360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 92468f1ed48SBarry Smith } else { 92560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 92668f1ed48SBarry Smith } 92702594712SBarry Smith #else 92860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 92902594712SBarry Smith #endif 93002594712SBarry Smith } 931b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 93202594712SBarry Smith } 933d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9343c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 935150b93efSMatthew G. Knepley PetscInt fshift=1; 936d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 9373c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 93819303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 9393c215bfdSMatthew Knepley #else 94019303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 9413c215bfdSMatthew Knepley #endif 942d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 9433c215bfdSMatthew Knepley for (i=0; i<m; i++) { 94460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 9453c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 946a9a0e077SKarl 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); 9473c215bfdSMatthew Knepley #else 948150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 9493c215bfdSMatthew Knepley #endif 9503c215bfdSMatthew Knepley } 9513c215bfdSMatthew Knepley } 952d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9533a40ed3dSBarry Smith } else { 954d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 955d5f3da31SBarry Smith if (A->factortype) { 95616cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 95716cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 95816cd7e1dSShri Abhyankar /* L part */ 95960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 96016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 96116cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 96260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 96316cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9646712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 96516cd7e1dSShri Abhyankar } else { 96660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 96716cd7e1dSShri Abhyankar } 96816cd7e1dSShri Abhyankar #else 96960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 97016cd7e1dSShri Abhyankar #endif 97116cd7e1dSShri Abhyankar } 97216cd7e1dSShri Abhyankar /* diagonal */ 97316cd7e1dSShri Abhyankar j = a->diag[i]; 97416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 97516cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 97660e0710aSBarry 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); 97716cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9786712e2f1SBarry 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); 97916cd7e1dSShri Abhyankar } else { 98060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 98116cd7e1dSShri Abhyankar } 98216cd7e1dSShri Abhyankar #else 98360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 98416cd7e1dSShri Abhyankar #endif 98516cd7e1dSShri Abhyankar 98616cd7e1dSShri Abhyankar /* U part */ 98760e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 98816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 98916cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 99060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 99116cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 99222ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 99316cd7e1dSShri Abhyankar } else { 99460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 99516cd7e1dSShri Abhyankar } 99616cd7e1dSShri Abhyankar #else 99760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 99816cd7e1dSShri Abhyankar #endif 99916cd7e1dSShri Abhyankar } 100016cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 100116cd7e1dSShri Abhyankar } 100216cd7e1dSShri Abhyankar } else { 100317ab2063SBarry Smith for (i=0; i<m; i++) { 100477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 100560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 1006aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 100736db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 100860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 100936db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 101060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 10113a40ed3dSBarry Smith } else { 101260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 101317ab2063SBarry Smith } 101417ab2063SBarry Smith #else 101560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 101617ab2063SBarry Smith #endif 101717ab2063SBarry Smith } 1018b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 101917ab2063SBarry Smith } 102016cd7e1dSShri Abhyankar } 1021d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 102217ab2063SBarry Smith } 1023b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 10243a40ed3dSBarry Smith PetscFunctionReturn(0); 1025416022c9SBarry Smith } 1026416022c9SBarry Smith 10279804daf3SBarry Smith #include <petscdraw.h> 1028dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 1029416022c9SBarry Smith { 1030480ef9eaSBarry Smith Mat A = (Mat) Aa; 1031416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1032dfbe8321SBarry Smith PetscErrorCode ierr; 1033383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 1034383922c3SLisandro Dalcin int color; 1035b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1036b0a32e0cSBarry Smith PetscViewer viewer; 1037f3ef73ceSBarry Smith PetscViewerFormat format; 1038cddf8d76SBarry Smith 10393a40ed3dSBarry Smith PetscFunctionBegin; 1040480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 1041b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1042b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1043383922c3SLisandro Dalcin 1044416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 10450513a670SBarry Smith 1046fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1047383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10480513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 1049b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1050416022c9SBarry Smith for (i=0; i<m; i++) { 1051cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1052bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1053bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 105436db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 1055b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1056cddf8d76SBarry Smith } 1057cddf8d76SBarry Smith } 1058b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 1059cddf8d76SBarry Smith for (i=0; i<m; i++) { 1060cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1061bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1062bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1063cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 1064b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1065cddf8d76SBarry Smith } 1066cddf8d76SBarry Smith } 1067b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1068cddf8d76SBarry Smith for (i=0; i<m; i++) { 1069cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1070bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1071bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 107236db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 1073b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1074416022c9SBarry Smith } 1075416022c9SBarry Smith } 1076383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10770513a670SBarry Smith } else { 10780513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 10790513a670SBarry Smith /* first determine max of all nonzero values */ 1080b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1081383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 1082b0a32e0cSBarry Smith PetscDraw popup; 10830513a670SBarry Smith 10840513a670SBarry Smith for (i=0; i<nz; i++) { 10850513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 10860513a670SBarry Smith } 1087383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 1088b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 108945f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 1090383922c3SLisandro Dalcin 1091383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10920513a670SBarry Smith for (i=0; i<m; i++) { 1093383922c3SLisandro Dalcin y_l = m - i - 1.0; 1094383922c3SLisandro Dalcin y_r = y_l + 1.0; 1095bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1096383922c3SLisandro Dalcin x_l = a->j[j]; 1097383922c3SLisandro Dalcin x_r = x_l + 1.0; 1098b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 1099b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 11000513a670SBarry Smith count++; 11010513a670SBarry Smith } 11020513a670SBarry Smith } 1103383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 11040513a670SBarry Smith } 1105480ef9eaSBarry Smith PetscFunctionReturn(0); 1106480ef9eaSBarry Smith } 1107cddf8d76SBarry Smith 11089804daf3SBarry Smith #include <petscdraw.h> 1109dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 1110480ef9eaSBarry Smith { 1111dfbe8321SBarry Smith PetscErrorCode ierr; 1112b0a32e0cSBarry Smith PetscDraw draw; 111336db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1114ace3abfcSBarry Smith PetscBool isnull; 1115480ef9eaSBarry Smith 1116480ef9eaSBarry Smith PetscFunctionBegin; 1117b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1118b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1119480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1120480ef9eaSBarry Smith 1121d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1122480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1123b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1124832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1125b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 11260298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1127832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 11283a40ed3dSBarry Smith PetscFunctionReturn(0); 1129416022c9SBarry Smith } 1130416022c9SBarry Smith 1131dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1132416022c9SBarry Smith { 1133dfbe8321SBarry Smith PetscErrorCode ierr; 1134ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1135416022c9SBarry Smith 11363a40ed3dSBarry Smith PetscFunctionBegin; 1137251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1138251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1139251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1140c45a1595SBarry Smith if (iascii) { 11413a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 11420f5bd95cSBarry Smith } else if (isbinary) { 11433a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 11440f5bd95cSBarry Smith } else if (isdraw) { 11453a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 114611aeaf0aSBarry Smith } 11474108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 11483a40ed3dSBarry Smith PetscFunctionReturn(0); 114917ab2063SBarry Smith } 115019bcc07fSBarry Smith 1151dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 115217ab2063SBarry Smith { 1153416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11546849ba73SBarry Smith PetscErrorCode ierr; 1155580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1156d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 115754f21887SBarry Smith MatScalar *aa = a->a,*ap; 11583447b6efSHong Zhang PetscReal ratio = 0.6; 115917ab2063SBarry Smith 11603a40ed3dSBarry Smith PetscFunctionBegin; 11613a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1162071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1163b215bc84SStefano Zampini if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) { 1164b215bc84SStefano Zampini /* we need to respect users asking to use or not the inodes routine in between matrix assemblies */ 1165b215bc84SStefano Zampini ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 1166b215bc84SStefano Zampini PetscFunctionReturn(0); 1167b215bc84SStefano Zampini } 116817ab2063SBarry Smith 116943ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 117017ab2063SBarry Smith for (i=1; i<m; i++) { 1171416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 117217ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 117394a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 117417ab2063SBarry Smith if (fshift) { 1175bfeeae90SHong Zhang ip = aj + ai[i]; 1176bfeeae90SHong Zhang ap = aa + ai[i]; 117717ab2063SBarry Smith N = ailen[i]; 1178580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1179580bdb30SBarry Smith if (!A->structure_only) { 1180580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 118117ab2063SBarry Smith } 118217ab2063SBarry Smith } 118317ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 118417ab2063SBarry Smith } 118517ab2063SBarry Smith if (m) { 118617ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 118717ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 118817ab2063SBarry Smith } 11897b083b7cSBarry Smith 119017ab2063SBarry Smith /* reset ilen and imax for each row */ 11917b083b7cSBarry Smith a->nonzerorowcnt = 0; 1192396832f4SHong Zhang if (A->structure_only) { 1193071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1194071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1195396832f4SHong Zhang } else { /* !A->structure_only */ 119617ab2063SBarry Smith for (i=0; i<m; i++) { 119717ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 11987b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 119917ab2063SBarry Smith } 1200396832f4SHong Zhang } 1201bfeeae90SHong Zhang a->nz = ai[m]; 120265e19b50SBarry 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); 120317ab2063SBarry Smith 120409f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1205d0f46423SBarry 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); 1206ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1207ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 12082205254eSKarl Rupp 12098e58a170SBarry Smith A->info.mallocs += a->reallocs; 1210dd5f02e7SSatish Balay a->reallocs = 0; 12116712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 121236db0b34SBarry Smith a->rmax = rmax; 12134e220ebcSLois Curfman McInnes 1214396832f4SHong Zhang if (!A->structure_only) { 121511e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1216396832f4SHong Zhang } 12174108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 12183a40ed3dSBarry Smith PetscFunctionReturn(0); 121917ab2063SBarry Smith } 122017ab2063SBarry Smith 122199cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 122299cafbc1SBarry Smith { 122399cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 122499cafbc1SBarry Smith PetscInt i,nz = a->nz; 12252e5835c6SStefano Zampini MatScalar *aa; 1226acf2f550SJed Brown PetscErrorCode ierr; 122799cafbc1SBarry Smith 122899cafbc1SBarry Smith PetscFunctionBegin; 12292e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 123099cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 12312e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1232acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12338c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1234c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1235e2cf4d64SStefano Zampini #endif 123699cafbc1SBarry Smith PetscFunctionReturn(0); 123799cafbc1SBarry Smith } 123899cafbc1SBarry Smith 123999cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 124099cafbc1SBarry Smith { 124199cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 124299cafbc1SBarry Smith PetscInt i,nz = a->nz; 12432e5835c6SStefano Zampini MatScalar *aa; 1244acf2f550SJed Brown PetscErrorCode ierr; 124599cafbc1SBarry Smith 124699cafbc1SBarry Smith PetscFunctionBegin; 12472e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 124899cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 12492e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1250acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12518c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1252c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1253e2cf4d64SStefano Zampini #endif 125499cafbc1SBarry Smith PetscFunctionReturn(0); 125599cafbc1SBarry Smith } 125699cafbc1SBarry Smith 1257dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 125817ab2063SBarry Smith { 1259416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1260dfbe8321SBarry Smith PetscErrorCode ierr; 12613a40ed3dSBarry Smith 12623a40ed3dSBarry Smith PetscFunctionBegin; 1263580bdb30SBarry Smith ierr = PetscArrayzero(a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 1264acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12658c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1266c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1267e2cf4d64SStefano Zampini #endif 12683a40ed3dSBarry Smith PetscFunctionReturn(0); 126917ab2063SBarry Smith } 1270416022c9SBarry Smith 1271dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 127217ab2063SBarry Smith { 1273416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1274dfbe8321SBarry Smith PetscErrorCode ierr; 1275d5d45c9bSBarry Smith 12763a40ed3dSBarry Smith PetscFunctionBegin; 1277aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1278d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 127917ab2063SBarry Smith #endif 1280e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 12816bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 12826bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 128305b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1284d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1285071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1286071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1287846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 128871f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 128905b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 12906bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 129105b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 1292cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 1293a30b2313SHong Zhang 12944108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1295bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1296901853e0SKris Buschelman 12976718818eSStefano Zampini /* MatMatMultNumeric_SeqAIJ_SeqAIJ_Sorted may allocate this. 12986718818eSStefano Zampini That function is so heavily used (sometimes in an hidden way through multnumeric function pointers) 12996718818eSStefano Zampini that is hard to properly add this data to the MatProduct data. We free it here to avoid 13006718818eSStefano Zampini users reusing the matrix object with different data to incur in obscure segmentation faults 13016718818eSStefano Zampini due to different matrix sizes */ 13026718818eSStefano Zampini ierr = PetscObjectCompose((PetscObject)A,"__PETSc__ab_dense",NULL);CHKERRQ(ierr); 13036718818eSStefano Zampini 1304f4259b30SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)A,NULL);CHKERRQ(ierr); 1305bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1306bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1307bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1308bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1309bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1310bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 13114222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA) 13124222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 1313e6e9a74fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",NULL);CHKERRQ(ierr); 1314fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 13154222ddf1SHong Zhang #endif 13163d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 13173d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijkokkos_C",NULL);CHKERRQ(ierr); 13183d0639e7SStefano Zampini #endif 13194222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL);CHKERRQ(ierr); 1320af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1321af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1322af8000cdSHong Zhang #endif 1323d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 1324d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_scalapack_C",NULL);CHKERRQ(ierr); 1325d24d4204SJose E. Roman #endif 132663c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 132763c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 13284222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 132963c07aadSStefano Zampini #endif 1330b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1331c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1332c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1333bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1334bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1335846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1336bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1337bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 13384222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL);CHKERRQ(ierr); 13394222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 13404222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 13413a40ed3dSBarry Smith PetscFunctionReturn(0); 134217ab2063SBarry Smith } 134317ab2063SBarry Smith 1344ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 134517ab2063SBarry Smith { 1346416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13474846f1f5SKris Buschelman PetscErrorCode ierr; 13483a40ed3dSBarry Smith 13493a40ed3dSBarry Smith PetscFunctionBegin; 1350a65d3064SKris Buschelman switch (op) { 1351a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 13524e0d8c25SBarry Smith a->roworiented = flg; 1353a65d3064SKris Buschelman break; 1354a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1355a9817697SBarry Smith a->keepnonzeropattern = flg; 1356a65d3064SKris Buschelman break; 1357512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1358512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1359a65d3064SKris Buschelman break; 1360a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 13614e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1362a65d3064SKris Buschelman break; 1363a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 13644e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1365a65d3064SKris Buschelman break; 136628b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 136728b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 136828b2fa4aSMatthew Knepley break; 1369a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 13704e0d8c25SBarry Smith a->ignorezeroentries = flg; 13710df259c2SBarry Smith break; 13723d472b54SHong Zhang case MAT_SPD: 1373b1646e73SJed Brown case MAT_SYMMETRIC: 1374b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1375b1646e73SJed Brown case MAT_HERMITIAN: 1376b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1377957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 13785021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 13795021d80fSJed Brown break; 13808c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 1381a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1382a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1383290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1384a65d3064SKris Buschelman break; 1385b87ac2d8SJed Brown case MAT_USE_INODES: 1386b215bc84SStefano Zampini ierr = MatSetOption_SeqAIJ_Inode(A,MAT_USE_INODES,flg);CHKERRQ(ierr); 1387b87ac2d8SJed Brown break; 1388c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1389c10200c1SHong Zhang A->submat_singleis = flg; 1390c10200c1SHong Zhang break; 1391071fcb05SBarry Smith case MAT_SORTED_FULL: 1392071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1393071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1394071fcb05SBarry Smith break; 13951a2c6b5cSJunchao Zhang case MAT_FORM_EXPLICIT_TRANSPOSE: 13961a2c6b5cSJunchao Zhang A->form_explicit_transpose = flg; 13971a2c6b5cSJunchao Zhang break; 1398a65d3064SKris Buschelman default: 1399e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1400a65d3064SKris Buschelman } 14013a40ed3dSBarry Smith PetscFunctionReturn(0); 140217ab2063SBarry Smith } 140317ab2063SBarry Smith 1404dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 140517ab2063SBarry Smith { 1406416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14076849ba73SBarry Smith PetscErrorCode ierr; 1408fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1409c898d852SStefano Zampini PetscScalar *x; 1410c898d852SStefano Zampini const PetscScalar *aa; 141117ab2063SBarry Smith 14123a40ed3dSBarry Smith PetscFunctionBegin; 1413d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1414e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1415c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 1416d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1417d3e70bfaSHong Zhang PetscInt *diag=a->diag; 1418fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 14192c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 1420fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1421c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 142235e7444dSHong Zhang PetscFunctionReturn(0); 142335e7444dSHong Zhang } 142435e7444dSHong Zhang 1425fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 142635e7444dSHong Zhang for (i=0; i<n; i++) { 1427fdc842d1SBarry Smith x[i] = 0.0; 142835e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 142935e7444dSHong Zhang if (aj[j] == i) { 143035e7444dSHong Zhang x[i] = aa[j]; 143117ab2063SBarry Smith break; 143217ab2063SBarry Smith } 143317ab2063SBarry Smith } 143417ab2063SBarry Smith } 1435fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1436c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 14373a40ed3dSBarry Smith PetscFunctionReturn(0); 143817ab2063SBarry Smith } 143917ab2063SBarry Smith 1440c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1441dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 144217ab2063SBarry Smith { 1443416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1444d9ca1df4SBarry Smith PetscScalar *y; 1445d9ca1df4SBarry Smith const PetscScalar *x; 1446dfbe8321SBarry Smith PetscErrorCode ierr; 1447d0f46423SBarry Smith PetscInt m = A->rmap->n; 14485c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1449d9ca1df4SBarry Smith const MatScalar *v; 1450a77337e4SBarry Smith PetscScalar alpha; 1451d9ca1df4SBarry Smith PetscInt n,i,j; 1452d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 14533447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1454ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 14555c897100SBarry Smith #endif 145617ab2063SBarry Smith 14573a40ed3dSBarry Smith PetscFunctionBegin; 14582e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1459d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14601ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 14615c897100SBarry Smith 14625c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1463bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 14645c897100SBarry Smith #else 14653447b6efSHong Zhang if (usecprow) { 14663447b6efSHong Zhang m = cprow.nrows; 14673447b6efSHong Zhang ii = cprow.i; 14687b2bb3b9SHong Zhang ridx = cprow.rindex; 14693447b6efSHong Zhang } else { 14703447b6efSHong Zhang ii = a->i; 14713447b6efSHong Zhang } 147217ab2063SBarry Smith for (i=0; i<m; i++) { 14733447b6efSHong Zhang idx = a->j + ii[i]; 14743447b6efSHong Zhang v = a->a + ii[i]; 14753447b6efSHong Zhang n = ii[i+1] - ii[i]; 14763447b6efSHong Zhang if (usecprow) { 14777b2bb3b9SHong Zhang alpha = x[ridx[i]]; 14783447b6efSHong Zhang } else { 147917ab2063SBarry Smith alpha = x[i]; 14803447b6efSHong Zhang } 148104fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 148217ab2063SBarry Smith } 14835c897100SBarry Smith #endif 1484dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1485d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14861ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14873a40ed3dSBarry Smith PetscFunctionReturn(0); 148817ab2063SBarry Smith } 148917ab2063SBarry Smith 1490dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 14915c897100SBarry Smith { 1492dfbe8321SBarry Smith PetscErrorCode ierr; 14935c897100SBarry Smith 14945c897100SBarry Smith PetscFunctionBegin; 1495170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 14965c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 14975c897100SBarry Smith PetscFunctionReturn(0); 14985c897100SBarry Smith } 14995c897100SBarry Smith 1500c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 150178b84d54SShri Abhyankar 1502dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 150317ab2063SBarry Smith { 1504416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1505d9fead3dSBarry Smith PetscScalar *y; 150654f21887SBarry Smith const PetscScalar *x; 150754f21887SBarry Smith const MatScalar *aa; 1508dfbe8321SBarry Smith PetscErrorCode ierr; 1509003131ecSBarry Smith PetscInt m=A->rmap->n; 15100298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 15117b083b7cSBarry Smith PetscInt n,i; 1512362ced78SSatish Balay PetscScalar sum; 1513ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 151417ab2063SBarry Smith 1515b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 151697952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1517fee21e36SBarry Smith #endif 1518fee21e36SBarry Smith 15193a40ed3dSBarry Smith PetscFunctionBegin; 1520b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1521b215bc84SStefano Zampini ierr = MatMult_SeqAIJ_Inode(A,xx,yy);CHKERRQ(ierr); 1522b215bc84SStefano Zampini PetscFunctionReturn(0); 1523b215bc84SStefano Zampini } 15243649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 15251ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1526416022c9SBarry Smith ii = a->i; 15274eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1528580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 152997952fefSHong Zhang m = a->compressedrow.nrows; 153097952fefSHong Zhang ii = a->compressedrow.i; 153197952fefSHong Zhang ridx = a->compressedrow.rindex; 153297952fefSHong Zhang for (i=0; i<m; i++) { 153397952fefSHong Zhang n = ii[i+1] - ii[i]; 153497952fefSHong Zhang aj = a->j + ii[i]; 153597952fefSHong Zhang aa = a->a + ii[i]; 153697952fefSHong Zhang sum = 0.0; 1537003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1538003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 153997952fefSHong Zhang y[*ridx++] = sum; 154097952fefSHong Zhang } 154197952fefSHong Zhang } else { /* do not use compressed row format */ 1542b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 15433d3eaba7SBarry Smith aj = a->j; 15443d3eaba7SBarry Smith aa = a->a; 1545b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1546b05257ddSBarry Smith #else 154717ab2063SBarry Smith for (i=0; i<m; i++) { 1548003131ecSBarry Smith n = ii[i+1] - ii[i]; 1549003131ecSBarry Smith aj = a->j + ii[i]; 1550003131ecSBarry Smith aa = a->a + ii[i]; 155117ab2063SBarry Smith sum = 0.0; 1552003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 155317ab2063SBarry Smith y[i] = sum; 155417ab2063SBarry Smith } 15558d195f9aSBarry Smith #endif 1556b05257ddSBarry Smith } 15577b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 15583649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15591ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15603a40ed3dSBarry Smith PetscFunctionReturn(0); 156117ab2063SBarry Smith } 156217ab2063SBarry Smith 1563b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1564b434eb95SMatthew G. Knepley { 1565b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1566b434eb95SMatthew G. Knepley PetscScalar *y; 1567b434eb95SMatthew G. Knepley const PetscScalar *x; 1568b434eb95SMatthew G. Knepley const MatScalar *aa; 1569b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1570b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1571b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1572b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1573b434eb95SMatthew G. Knepley PetscScalar sum; 1574b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1575b434eb95SMatthew G. Knepley 1576b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1577b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1578b434eb95SMatthew G. Knepley #endif 1579b434eb95SMatthew G. Knepley 1580b434eb95SMatthew G. Knepley PetscFunctionBegin; 1581b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1582b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1583b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1584b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1585b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1586b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1587b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1588b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1589b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1590b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1591b434eb95SMatthew G. Knepley sum = 0.0; 1592b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1593b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1594b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1595b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1596b434eb95SMatthew G. Knepley } 1597b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 15983d3eaba7SBarry Smith ii = a->i; 1599b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1600b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1601b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1602b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1603b434eb95SMatthew G. Knepley sum = 0.0; 1604b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1605b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1606b434eb95SMatthew G. Knepley y[i] = sum; 1607b434eb95SMatthew G. Knepley } 1608b434eb95SMatthew G. Knepley } 1609b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1610b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1611b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1612b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1613b434eb95SMatthew G. Knepley } 1614b434eb95SMatthew G. Knepley 1615b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1616b434eb95SMatthew G. Knepley { 1617b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1618b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1619b434eb95SMatthew G. Knepley const PetscScalar *x; 1620b434eb95SMatthew G. Knepley const MatScalar *aa; 1621b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1622b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1623b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1624b434eb95SMatthew G. Knepley PetscScalar sum; 1625b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1626b434eb95SMatthew G. Knepley 1627b434eb95SMatthew G. Knepley PetscFunctionBegin; 1628b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1629d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1630b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1631b434eb95SMatthew G. Knepley if (zz != yy) { 1632580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1633b434eb95SMatthew G. Knepley } 1634b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1635b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1636b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1637b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1638b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1639b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1640b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1641b434eb95SMatthew G. Knepley sum = y[*ridx]; 1642b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1643b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1644b434eb95SMatthew G. Knepley } 1645b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16463d3eaba7SBarry Smith ii = a->i; 1647b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1648b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1649b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1650b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1651b434eb95SMatthew G. Knepley sum = y[i]; 1652b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1653b434eb95SMatthew G. Knepley z[i] = sum; 1654b434eb95SMatthew G. Knepley } 1655b434eb95SMatthew G. Knepley } 1656b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1657b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1658d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1659b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1660b434eb95SMatthew G. Knepley } 1661b434eb95SMatthew G. Knepley 1662c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1663dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 166417ab2063SBarry Smith { 1665416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1666f15663dcSBarry Smith PetscScalar *y,*z; 1667f15663dcSBarry Smith const PetscScalar *x; 166854f21887SBarry Smith const MatScalar *aa; 1669dfbe8321SBarry Smith PetscErrorCode ierr; 1670d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1671d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1672362ced78SSatish Balay PetscScalar sum; 1673ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 16749ea0dfa2SSatish Balay 16753a40ed3dSBarry Smith PetscFunctionBegin; 1676b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1677b215bc84SStefano Zampini ierr = MatMultAdd_SeqAIJ_Inode(A,xx,yy,zz);CHKERRQ(ierr); 1678b215bc84SStefano Zampini PetscFunctionReturn(0); 1679b215bc84SStefano Zampini } 1680f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1681d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 16824eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 16834eb6d288SHong Zhang if (zz != yy) { 1684580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 16854eb6d288SHong Zhang } 168697952fefSHong Zhang m = a->compressedrow.nrows; 168797952fefSHong Zhang ii = a->compressedrow.i; 168897952fefSHong Zhang ridx = a->compressedrow.rindex; 168997952fefSHong Zhang for (i=0; i<m; i++) { 169097952fefSHong Zhang n = ii[i+1] - ii[i]; 169197952fefSHong Zhang aj = a->j + ii[i]; 169297952fefSHong Zhang aa = a->a + ii[i]; 169397952fefSHong Zhang sum = y[*ridx]; 1694f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 169597952fefSHong Zhang z[*ridx++] = sum; 169697952fefSHong Zhang } 169797952fefSHong Zhang } else { /* do not use compressed row format */ 16983d3eaba7SBarry Smith ii = a->i; 1699f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 17003d3eaba7SBarry Smith aj = a->j; 17013d3eaba7SBarry Smith aa = a->a; 1702f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1703f15663dcSBarry Smith #else 170417ab2063SBarry Smith for (i=0; i<m; i++) { 1705f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1706f15663dcSBarry Smith aj = a->j + ii[i]; 1707f15663dcSBarry Smith aa = a->a + ii[i]; 170817ab2063SBarry Smith sum = y[i]; 1709f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 171017ab2063SBarry Smith z[i] = sum; 171117ab2063SBarry Smith } 171202ab625aSSatish Balay #endif 1713f15663dcSBarry Smith } 1714dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1715f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1716d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 17173a40ed3dSBarry Smith PetscFunctionReturn(0); 171817ab2063SBarry Smith } 171917ab2063SBarry Smith 172017ab2063SBarry Smith /* 172117ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 172217ab2063SBarry Smith */ 1723dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 172417ab2063SBarry Smith { 1725416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17266849ba73SBarry Smith PetscErrorCode ierr; 1727d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 172817ab2063SBarry Smith 17293a40ed3dSBarry Smith PetscFunctionBegin; 173009f38230SBarry Smith if (!a->diag) { 1731785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 17323bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 173309f38230SBarry Smith } 1734d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 173509f38230SBarry Smith a->diag[i] = a->i[i+1]; 1736bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1737bfeeae90SHong Zhang if (a->j[j] == i) { 173809f38230SBarry Smith a->diag[i] = j; 173917ab2063SBarry Smith break; 174017ab2063SBarry Smith } 174117ab2063SBarry Smith } 174217ab2063SBarry Smith } 17433a40ed3dSBarry Smith PetscFunctionReturn(0); 174417ab2063SBarry Smith } 174517ab2063SBarry Smith 174661ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 174761ecd0c6SBarry Smith { 174861ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 174961ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 175061ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 175161ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 175261ecd0c6SBarry Smith PetscErrorCode ierr; 175361ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 175461ecd0c6SBarry Smith 175561ecd0c6SBarry Smith PetscFunctionBegin; 175661ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 175761ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 175861ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 175961ecd0c6SBarry Smith PetscFunctionReturn(0); 176061ecd0c6SBarry Smith } 176161ecd0c6SBarry Smith 176261ecd0c6SBarry Smith if (a->diagonaldense) { 176361ecd0c6SBarry Smith cnt = 0; 176461ecd0c6SBarry Smith } else { 176561ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 176661ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 176761ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 176861ecd0c6SBarry Smith cnt++; 176961ecd0c6SBarry Smith mdiag[i] = 1; 177061ecd0c6SBarry Smith } 177161ecd0c6SBarry Smith } 177261ecd0c6SBarry Smith } 177361ecd0c6SBarry Smith if (!cnt) { 177461ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 177561ecd0c6SBarry Smith } else { 1776b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1777b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 177861ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 177961ecd0c6SBarry Smith 178061ecd0c6SBarry Smith a->a = NULL; 178161ecd0c6SBarry Smith a->j = NULL; 178261ecd0c6SBarry Smith a->i = NULL; 178361ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 178461ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 178561ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1786447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 178761ecd0c6SBarry Smith } 178861ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 178961ecd0c6SBarry Smith 179061ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 179161ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 179261ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1793447d62f5SStefano Zampini if (i < A->cmap->n) { 179461ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 179561ecd0c6SBarry Smith } 1796447d62f5SStefano Zampini } 179761ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179861ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179961ecd0c6SBarry Smith if (singlemalloc) { 180061ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 180161ecd0c6SBarry Smith } else { 180261ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 180361ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 180461ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 180561ecd0c6SBarry Smith } 180661ecd0c6SBarry Smith } 180761ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 180861ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 180961ecd0c6SBarry Smith PetscFunctionReturn(0); 181061ecd0c6SBarry Smith } 181161ecd0c6SBarry Smith 1812be5855fcSBarry Smith /* 1813be5855fcSBarry Smith Checks for missing diagonals 1814be5855fcSBarry Smith */ 1815ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1816be5855fcSBarry Smith { 1817be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18187734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1819994fe344SLisandro Dalcin PetscErrorCode ierr; 1820be5855fcSBarry Smith 1821be5855fcSBarry Smith PetscFunctionBegin; 182209f38230SBarry Smith *missing = PETSC_FALSE; 18237734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 182409f38230SBarry Smith *missing = PETSC_TRUE; 182509f38230SBarry Smith if (d) *d = 0; 1826994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 182709f38230SBarry Smith } else { 182801445905SHong Zhang PetscInt n; 182901445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1830f1e2ffcdSBarry Smith diag = a->diag; 183101445905SHong Zhang for (i=0; i<n; i++) { 18327734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 183309f38230SBarry Smith *missing = PETSC_TRUE; 183409f38230SBarry Smith if (d) *d = i; 1835994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1836358d2f5dSShri Abhyankar break; 183709f38230SBarry Smith } 1838be5855fcSBarry Smith } 1839be5855fcSBarry Smith } 1840be5855fcSBarry Smith PetscFunctionReturn(0); 1841be5855fcSBarry Smith } 1842be5855fcSBarry Smith 18430da83c2eSBarry Smith #include <petscblaslapack.h> 18440da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 18450da83c2eSBarry Smith 18460da83c2eSBarry Smith /* 18470da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 18480da83c2eSBarry Smith */ 18490da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 18500da83c2eSBarry Smith { 18510da83c2eSBarry Smith PetscErrorCode ierr; 18520da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 18530da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 18540da83c2eSBarry Smith const PetscReal shift = 0.0; 18550da83c2eSBarry Smith PetscInt ipvt[5]; 18560da83c2eSBarry Smith PetscScalar work[25],*v_work; 18570da83c2eSBarry Smith 18580da83c2eSBarry Smith PetscFunctionBegin; 18590da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 18600da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 18610da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 18620da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18630da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 18640da83c2eSBarry Smith } 18650da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 18660da83c2eSBarry Smith if (bsizemax > 7) { 18670da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 18680da83c2eSBarry Smith } 18690da83c2eSBarry Smith ncnt = 0; 18700da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18710da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 18720da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 18730da83c2eSBarry Smith switch (bsizes[i]) { 18740da83c2eSBarry Smith case 1: 18750da83c2eSBarry Smith *diag = 1.0/(*diag); 18760da83c2eSBarry Smith break; 18770da83c2eSBarry Smith case 2: 18780da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18790da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18800da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 18810da83c2eSBarry Smith break; 18820da83c2eSBarry Smith case 3: 18830da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18840da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18850da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 18860da83c2eSBarry Smith break; 18870da83c2eSBarry Smith case 4: 18880da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18890da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18900da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 18910da83c2eSBarry Smith break; 18920da83c2eSBarry Smith case 5: 18930da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18940da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18950da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 18960da83c2eSBarry Smith break; 18970da83c2eSBarry Smith case 6: 18980da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18990da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19000da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 19010da83c2eSBarry Smith break; 19020da83c2eSBarry Smith case 7: 19030da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19040da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19050da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 19060da83c2eSBarry Smith break; 19070da83c2eSBarry Smith default: 19080da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19090da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19100da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 19110da83c2eSBarry Smith } 19120da83c2eSBarry Smith ncnt += bsizes[i]; 19130da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 19140da83c2eSBarry Smith } 19150da83c2eSBarry Smith if (bsizemax > 7) { 19160da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 19170da83c2eSBarry Smith } 19180da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 19190da83c2eSBarry Smith PetscFunctionReturn(0); 19200da83c2eSBarry Smith } 19210da83c2eSBarry Smith 1922422a814eSBarry Smith /* 1923422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1924422a814eSBarry Smith */ 19257087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 192671f1c65dSBarry Smith { 192771f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 192871f1c65dSBarry Smith PetscErrorCode ierr; 1929d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 19302e5835c6SStefano Zampini const MatScalar *v; 193154f21887SBarry Smith PetscScalar *idiag,*mdiag; 193271f1c65dSBarry Smith 193371f1c65dSBarry Smith PetscFunctionBegin; 193471f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 193571f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 193671f1c65dSBarry Smith diag = a->diag; 193771f1c65dSBarry Smith if (!a->idiag) { 1938dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 19393bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,3*m*sizeof(PetscScalar));CHKERRQ(ierr); 194071f1c65dSBarry Smith } 19412e5835c6SStefano Zampini 194271f1c65dSBarry Smith mdiag = a->mdiag; 194371f1c65dSBarry Smith idiag = a->idiag; 19442e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 1945422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 194671f1c65dSBarry Smith for (i=0; i<m; i++) { 194771f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1948899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1949899639b0SHong Zhang if (PetscRealPart(fshift)) { 1950899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 19517b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19527b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 19537b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1954a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1955899639b0SHong Zhang } 195671f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 195771f1c65dSBarry Smith } 195871f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 195971f1c65dSBarry Smith } else { 196071f1c65dSBarry Smith for (i=0; i<m; i++) { 196171f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 196271f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 196371f1c65dSBarry Smith } 1964dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 196571f1c65dSBarry Smith } 196671f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 19672e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 196871f1c65dSBarry Smith PetscFunctionReturn(0); 196971f1c65dSBarry Smith } 197071f1c65dSBarry Smith 1971c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 197241f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 197317ab2063SBarry Smith { 1974416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1975e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 19762e5835c6SStefano Zampini const MatScalar *v,*idiag=NULL,*mdiag,*aa; 197754f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1978dfbe8321SBarry Smith PetscErrorCode ierr; 19793d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 198097f1f81fSBarry Smith const PetscInt *idx,*diag; 198117ab2063SBarry Smith 19823a40ed3dSBarry Smith PetscFunctionBegin; 1983b215bc84SStefano Zampini if (a->inode.use && a->inode.checked && omega == 1.0 && fshift == 0.0) { 1984b215bc84SStefano Zampini ierr = MatSOR_SeqAIJ_Inode(A,bb,omega,flag,fshift,its,lits,xx);CHKERRQ(ierr); 1985b215bc84SStefano Zampini PetscFunctionReturn(0); 1986b215bc84SStefano Zampini } 1987b965ef7fSBarry Smith its = its*lits; 198891723122SBarry Smith 198971f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 199071f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 199171f1c65dSBarry Smith a->fshift = fshift; 199271f1c65dSBarry Smith a->omega = omega; 1993ed480e8bSBarry Smith 199471f1c65dSBarry Smith diag = a->diag; 199571f1c65dSBarry Smith t = a->ssor_work; 1996ed480e8bSBarry Smith idiag = a->idiag; 199771f1c65dSBarry Smith mdiag = a->mdiag; 1998ed480e8bSBarry Smith 19992e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 20001ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 20013649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 2002ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 200317ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 200417ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 2005ed480e8bSBarry Smith bs = b; 200617ab2063SBarry Smith for (i=0; i<m; i++) { 200771f1c65dSBarry Smith d = fshift + mdiag[i]; 2008416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2009ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20102e5835c6SStefano Zampini v = aa + diag[i] + 1; 201117ab2063SBarry Smith sum = b[i]*d/omega; 2012003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 201317ab2063SBarry Smith x[i] = sum; 201417ab2063SBarry Smith } 20151ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20163649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20172e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 2018efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20193a40ed3dSBarry Smith PetscFunctionReturn(0); 202017ab2063SBarry Smith } 2021c783ea89SBarry Smith 20222205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 20232205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 20244c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 2025887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 202617ab2063SBarry Smith 202717ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 202817ab2063SBarry Smith 2029887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 203017ab2063SBarry Smith */ 203117ab2063SBarry Smith scale = (2.0/omega) - 1.0; 203217ab2063SBarry Smith 203317ab2063SBarry Smith /* x = (E + U)^{-1} b */ 203417ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2035416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2036ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20372e5835c6SStefano Zampini v = aa + diag[i] + 1; 203817ab2063SBarry Smith sum = b[i]; 2039e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2040ed480e8bSBarry Smith x[i] = sum*idiag[i]; 204117ab2063SBarry Smith } 204217ab2063SBarry Smith 204317ab2063SBarry Smith /* t = b - (2*E - D)x */ 20442e5835c6SStefano Zampini v = aa; 20452205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 204617ab2063SBarry Smith 204717ab2063SBarry Smith /* t = (E + L)^{-1}t */ 2048ed480e8bSBarry Smith ts = t; 2049416022c9SBarry Smith diag = a->diag; 205017ab2063SBarry Smith for (i=0; i<m; i++) { 2051416022c9SBarry Smith n = diag[i] - a->i[i]; 2052ed480e8bSBarry Smith idx = a->j + a->i[i]; 20532e5835c6SStefano Zampini v = aa + a->i[i]; 205417ab2063SBarry Smith sum = t[i]; 2055003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 2056ed480e8bSBarry Smith t[i] = sum*idiag[i]; 2057733d66baSBarry Smith /* x = x + t */ 2058733d66baSBarry Smith x[i] += t[i]; 205917ab2063SBarry Smith } 206017ab2063SBarry Smith 2061dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 20621ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20633649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20643a40ed3dSBarry Smith PetscFunctionReturn(0); 206517ab2063SBarry Smith } 206617ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 206717ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 206817ab2063SBarry Smith for (i=0; i<m; i++) { 2069416022c9SBarry Smith n = diag[i] - a->i[i]; 2070ed480e8bSBarry Smith idx = a->j + a->i[i]; 20712e5835c6SStefano Zampini v = aa + a->i[i]; 207217ab2063SBarry Smith sum = b[i]; 2073e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20745c99c7daSBarry Smith t[i] = sum; 2075ed480e8bSBarry Smith x[i] = sum*idiag[i]; 207617ab2063SBarry Smith } 20775c99c7daSBarry Smith xb = t; 2078efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20793a40ed3dSBarry Smith } else xb = b; 208017ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 208117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2082416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2083ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20842e5835c6SStefano Zampini v = aa + diag[i] + 1; 208517ab2063SBarry Smith sum = xb[i]; 2086e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20875c99c7daSBarry Smith if (xb == b) { 2088ed480e8bSBarry Smith x[i] = sum*idiag[i]; 20895c99c7daSBarry Smith } else { 2090b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 209117ab2063SBarry Smith } 20925c99c7daSBarry Smith } 2093b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 209417ab2063SBarry Smith } 209517ab2063SBarry Smith its--; 209617ab2063SBarry Smith } 209717ab2063SBarry Smith while (its--) { 209817ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 209917ab2063SBarry Smith for (i=0; i<m; i++) { 2100b19a5dc2SMark Adams /* lower */ 2101b19a5dc2SMark Adams n = diag[i] - a->i[i]; 2102ed480e8bSBarry Smith idx = a->j + a->i[i]; 21032e5835c6SStefano Zampini v = aa + a->i[i]; 210417ab2063SBarry Smith sum = b[i]; 2105e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2106b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 2107b19a5dc2SMark Adams /* upper */ 2108b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2109b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21102e5835c6SStefano Zampini v = aa + diag[i] + 1; 2111b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2112b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 211317ab2063SBarry Smith } 2114b19a5dc2SMark Adams xb = t; 21159f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2116b19a5dc2SMark Adams } else xb = b; 211717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 211817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2119b19a5dc2SMark Adams sum = xb[i]; 2120b19a5dc2SMark Adams if (xb == b) { 2121b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 2122416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 2123ed480e8bSBarry Smith idx = a->j + a->i[i]; 21242e5835c6SStefano Zampini v = aa + a->i[i]; 2125e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2126ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 2127b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 2128b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2129b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21302e5835c6SStefano Zampini v = aa + diag[i] + 1; 2131b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2132b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 213317ab2063SBarry Smith } 2134b19a5dc2SMark Adams } 2135b19a5dc2SMark Adams if (xb == b) { 21369f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2137b19a5dc2SMark Adams } else { 2138b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 2139b19a5dc2SMark Adams } 214017ab2063SBarry Smith } 214117ab2063SBarry Smith } 21422e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 21431ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 21443649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 2145365a8a9eSBarry Smith PetscFunctionReturn(0); 214617ab2063SBarry Smith } 214717ab2063SBarry Smith 2148dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 214917ab2063SBarry Smith { 2150416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21514e220ebcSLois Curfman McInnes 21523a40ed3dSBarry Smith PetscFunctionBegin; 21534e220ebcSLois Curfman McInnes info->block_size = 1.0; 21543966268fSBarry Smith info->nz_allocated = a->maxnz; 21553966268fSBarry Smith info->nz_used = a->nz; 21563966268fSBarry Smith info->nz_unneeded = (a->maxnz - a->nz); 21573966268fSBarry Smith info->assemblies = A->num_ass; 21583966268fSBarry Smith info->mallocs = A->info.mallocs; 21597adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2160d5f3da31SBarry Smith if (A->factortype) { 21614e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 21624e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 21634e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 21644e220ebcSLois Curfman McInnes } else { 21654e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 21664e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 21674e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 21684e220ebcSLois Curfman McInnes } 21693a40ed3dSBarry Smith PetscFunctionReturn(0); 217017ab2063SBarry Smith } 217117ab2063SBarry Smith 21722b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 217317ab2063SBarry Smith { 2174416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2175c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 21766849ba73SBarry Smith PetscErrorCode ierr; 217797b48c8fSBarry Smith const PetscScalar *xx; 21782e5835c6SStefano Zampini PetscScalar *bb,*aa; 2179c7da8527SEric Chamberland PetscInt d = 0; 218017ab2063SBarry Smith 21813a40ed3dSBarry Smith PetscFunctionBegin; 218297b48c8fSBarry Smith if (x && b) { 218397b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 218497b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 218597b48c8fSBarry Smith for (i=0; i<N; i++) { 218697b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2187447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 218897b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 218997b48c8fSBarry Smith } 219097b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 219197b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 219297b48c8fSBarry Smith } 219397b48c8fSBarry Smith 21942e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 2195a9817697SBarry Smith if (a->keepnonzeropattern) { 2196f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2197e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 21982e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2199f1e2ffcdSBarry Smith } 2200f4df32b1SMatthew Knepley if (diag != 0.0) { 2201c7da8527SEric Chamberland for (i=0; i<N; i++) { 2202c7da8527SEric Chamberland d = rows[i]; 2203447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2204c7da8527SEric 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); 2205c7da8527SEric Chamberland } 2206f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2207447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 22082e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 2209f1e2ffcdSBarry Smith } 2210f1e2ffcdSBarry Smith } 2211f1e2ffcdSBarry Smith } else { 2212f4df32b1SMatthew Knepley if (diag != 0.0) { 221317ab2063SBarry Smith for (i=0; i<N; i++) { 2214e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22157ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2216447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2217447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2218447d62f5SStefano Zampini } else { 2219416022c9SBarry Smith a->ilen[rows[i]] = 1; 22202e5835c6SStefano Zampini aa[a->i[rows[i]]] = diag; 2221bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2222447d62f5SStefano Zampini } 2223447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2224f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 222517ab2063SBarry Smith } 222617ab2063SBarry Smith } 22273a40ed3dSBarry Smith } else { 222817ab2063SBarry Smith for (i=0; i<N; i++) { 2229e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2230416022c9SBarry Smith a->ilen[rows[i]] = 0; 223117ab2063SBarry Smith } 223217ab2063SBarry Smith } 2233e56f5c9eSBarry Smith A->nonzerostate++; 2234f1e2ffcdSBarry Smith } 22352e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 22368c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2237c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2238e2cf4d64SStefano Zampini #endif 22394099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22403a40ed3dSBarry Smith PetscFunctionReturn(0); 224117ab2063SBarry Smith } 224217ab2063SBarry Smith 22436e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 22446e169961SBarry Smith { 22456e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22466e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 22476e169961SBarry Smith PetscErrorCode ierr; 22482b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 22496e169961SBarry Smith const PetscScalar *xx; 22502e5835c6SStefano Zampini PetscScalar *bb,*aa; 22516e169961SBarry Smith 22526e169961SBarry Smith PetscFunctionBegin; 22532e5835c6SStefano Zampini if (!N) PetscFunctionReturn(0); 22542e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 22556e169961SBarry Smith if (x && b) { 22566e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 22576e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 22582b40b63fSBarry Smith vecs = PETSC_TRUE; 22596e169961SBarry Smith } 22601795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 22616e169961SBarry Smith for (i=0; i<N; i++) { 22626e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22632e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 22642205254eSKarl Rupp 22656e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 22666e169961SBarry Smith } 22676e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 22686e169961SBarry Smith if (!zeroed[i]) { 22696e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 22704cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 22712e5835c6SStefano Zampini if (vecs) bb[i] -= aa[j]*xx[a->j[j]]; 22722e5835c6SStefano Zampini aa[j] = 0.0; 22736e169961SBarry Smith } 22746e169961SBarry Smith } 22754cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 22766e169961SBarry Smith } 22776e169961SBarry Smith if (x && b) { 22786e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 22796e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 22806e169961SBarry Smith } 22816e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 22826e169961SBarry Smith if (diag != 0.0) { 22836e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 22841d5a398dSstefano_zampini if (missing) { 22851d5a398dSstefano_zampini for (i=0; i<N; i++) { 22864cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 22874cf107fdSStefano 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]); 22881d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 22891d5a398dSstefano_zampini } 22901d5a398dSstefano_zampini } else { 22916e169961SBarry Smith for (i=0; i<N; i++) { 22922e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 22936e169961SBarry Smith } 22946e169961SBarry Smith } 22951d5a398dSstefano_zampini } 22962e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 22978c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2298c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2299e2cf4d64SStefano Zampini #endif 23004099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23016e169961SBarry Smith PetscFunctionReturn(0); 23026e169961SBarry Smith } 23036e169961SBarry Smith 2304a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 230517ab2063SBarry Smith { 2306416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23072e5835c6SStefano Zampini const PetscScalar *aa = a->a; 230897f1f81fSBarry Smith PetscInt *itmp; 23092e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23102e5835c6SStefano Zampini PetscErrorCode ierr; 23112e5835c6SStefano Zampini PetscBool rest = PETSC_FALSE; 23122e5835c6SStefano Zampini #endif 231317ab2063SBarry Smith 23143a40ed3dSBarry Smith PetscFunctionBegin; 23152e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23162e5835c6SStefano Zampini if (v && A->offloadmask == PETSC_OFFLOAD_GPU) { 23172e5835c6SStefano Zampini /* triggers copy to CPU */ 23182e5835c6SStefano Zampini rest = PETSC_TRUE; 23192e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 23202e5835c6SStefano Zampini } else aa = a->a; 23212e5835c6SStefano Zampini #endif 2322416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 23232e5835c6SStefano Zampini if (v) *v = (PetscScalar*)(aa + a->i[row]); 232417ab2063SBarry Smith if (idx) { 2325bfeeae90SHong Zhang itmp = a->j + a->i[row]; 232626fbe8dcSKarl Rupp if (*nz) *idx = itmp; 2327f4259b30SLisandro Dalcin else *idx = NULL; 232817ab2063SBarry Smith } 23292e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23302e5835c6SStefano Zampini if (rest) { 23312e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 23322e5835c6SStefano Zampini } 23332e5835c6SStefano Zampini #endif 23343a40ed3dSBarry Smith PetscFunctionReturn(0); 233517ab2063SBarry Smith } 233617ab2063SBarry Smith 2337a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 233817ab2063SBarry Smith { 23393a40ed3dSBarry Smith PetscFunctionBegin; 2340cb4a9cd9SHong Zhang if (nz) *nz = 0; 23412e5835c6SStefano Zampini if (idx) *idx = NULL; 23422e5835c6SStefano Zampini if (v) *v = NULL; 23433a40ed3dSBarry Smith PetscFunctionReturn(0); 234417ab2063SBarry Smith } 234517ab2063SBarry Smith 2346dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 234717ab2063SBarry Smith { 2348416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23492e5835c6SStefano Zampini const MatScalar *v; 235036db0b34SBarry Smith PetscReal sum = 0.0; 23516849ba73SBarry Smith PetscErrorCode ierr; 235297f1f81fSBarry Smith PetscInt i,j; 235317ab2063SBarry Smith 23543a40ed3dSBarry Smith PetscFunctionBegin; 23552e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 235617ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2357570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2358570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 235973cf7048SBarry Smith PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&nz,v,&one)); 2360570b7f6dSBarry Smith #else 2361416022c9SBarry Smith for (i=0; i<a->nz; i++) { 236236db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 236317ab2063SBarry Smith } 23648f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2365570b7f6dSBarry Smith #endif 2366ca0c957dSBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 23673a40ed3dSBarry Smith } else if (type == NORM_1) { 236836db0b34SBarry Smith PetscReal *tmp; 236997f1f81fSBarry Smith PetscInt *jj = a->j; 23701795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2371064f8208SBarry Smith *nrm = 0.0; 2372416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2373bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 237417ab2063SBarry Smith } 2375d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2376064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 237717ab2063SBarry Smith } 2378606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 237951f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 23803a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2381064f8208SBarry Smith *nrm = 0.0; 2382d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 23832e5835c6SStefano Zampini const PetscScalar *v2 = v + a->i[j]; 238417ab2063SBarry Smith sum = 0.0; 2385416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 23862e5835c6SStefano Zampini sum += PetscAbsScalar(*v2); v2++; 238717ab2063SBarry Smith } 2388064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 238917ab2063SBarry Smith } 239051f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2391f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 23922e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 23933a40ed3dSBarry Smith PetscFunctionReturn(0); 239417ab2063SBarry Smith } 239517ab2063SBarry Smith 23964e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 23974e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 23984e938277SHong Zhang { 23994e938277SHong Zhang PetscErrorCode ierr; 24004e938277SHong Zhang PetscInt i,j,anzj; 24014e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 24024e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 24034e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 24044e938277SHong Zhang 24054e938277SHong Zhang PetscFunctionBegin; 24064e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2407854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2408785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2409785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 24104e938277SHong Zhang 24114e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 24124e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 241326fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 24144e938277SHong Zhang /* Form ati for csr format of A^T. */ 241526fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 24164e938277SHong Zhang 24174e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2418580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 24194e938277SHong Zhang 24204e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 24214e938277SHong Zhang for (i=0;i<am;i++) { 24224e938277SHong Zhang anzj = ai[i+1] - ai[i]; 24234e938277SHong Zhang for (j=0;j<anzj;j++) { 24244e938277SHong Zhang atj[atfill[*aj]] = i; 24254e938277SHong Zhang atfill[*aj++] += 1; 24264e938277SHong Zhang } 24274e938277SHong Zhang } 24284e938277SHong Zhang 24294e938277SHong Zhang /* Clean up temporary space and complete requests. */ 24304e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2431ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 243233d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2433b5bb3eecSMark Adams ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2434a2f3521dSMark F. Adams 24354e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 24364e938277SHong Zhang b->free_a = PETSC_FALSE; 24374e938277SHong Zhang b->free_ij = PETSC_TRUE; 24384e938277SHong Zhang b->nonew = 0; 24394e938277SHong Zhang PetscFunctionReturn(0); 24404e938277SHong Zhang } 24414e938277SHong Zhang 24427087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2443cd0d46ebSvictorle { 24443d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 244554f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 24462e5835c6SStefano Zampini const MatScalar *va,*vb; 24476849ba73SBarry Smith PetscErrorCode ierr; 244897f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2449cd0d46ebSvictorle 2450cd0d46ebSvictorle PetscFunctionBegin; 2451cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2452cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24535485867bSBarry Smith if (ma!=nb || na!=mb) { 24545485867bSBarry Smith *f = PETSC_FALSE; 24555485867bSBarry Smith PetscFunctionReturn(0); 24565485867bSBarry Smith } 24572e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&va);CHKERRQ(ierr); 24582e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(B,&vb);CHKERRQ(ierr); 2459cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2460cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2461785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2462785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2463cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2464cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2465cd0d46ebSvictorle 2466cd0d46ebSvictorle *f = PETSC_TRUE; 2467cd0d46ebSvictorle for (i=0; i<ma; i++) { 2468cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 246997f1f81fSBarry Smith PetscInt idc,idr; 24705485867bSBarry Smith PetscScalar vc,vr; 2471cd0d46ebSvictorle /* column/row index/value */ 24725485867bSBarry Smith idc = adx[aptr[i]]; 24735485867bSBarry Smith idr = bdx[bptr[idc]]; 24745485867bSBarry Smith vc = va[aptr[i]]; 24755485867bSBarry Smith vr = vb[bptr[idc]]; 24765485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 24775485867bSBarry Smith *f = PETSC_FALSE; 24785485867bSBarry Smith goto done; 2479cd0d46ebSvictorle } else { 24805485867bSBarry Smith aptr[i]++; 24815485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2482cd0d46ebSvictorle } 2483cd0d46ebSvictorle } 2484cd0d46ebSvictorle } 2485cd0d46ebSvictorle done: 2486cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 24873aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 24882e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&va);CHKERRQ(ierr); 24892e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(B,&vb);CHKERRQ(ierr); 2490cd0d46ebSvictorle PetscFunctionReturn(0); 2491cd0d46ebSvictorle } 2492cd0d46ebSvictorle 24937087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 24941cbb95d3SBarry Smith { 24953d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 249654f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 249754f21887SBarry Smith MatScalar *va,*vb; 24981cbb95d3SBarry Smith PetscErrorCode ierr; 24991cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 25001cbb95d3SBarry Smith 25011cbb95d3SBarry Smith PetscFunctionBegin; 25021cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 25031cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 25041cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 25051cbb95d3SBarry Smith *f = PETSC_FALSE; 25061cbb95d3SBarry Smith PetscFunctionReturn(0); 25071cbb95d3SBarry Smith } 25081cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 25091cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 25101cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2511785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2512785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 25131cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 25141cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 25151cbb95d3SBarry Smith 25161cbb95d3SBarry Smith *f = PETSC_TRUE; 25171cbb95d3SBarry Smith for (i=0; i<ma; i++) { 25181cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 25191cbb95d3SBarry Smith PetscInt idc,idr; 25201cbb95d3SBarry Smith PetscScalar vc,vr; 25211cbb95d3SBarry Smith /* column/row index/value */ 25221cbb95d3SBarry Smith idc = adx[aptr[i]]; 25231cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 25241cbb95d3SBarry Smith vc = va[aptr[i]]; 25251cbb95d3SBarry Smith vr = vb[bptr[idc]]; 25261cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 25271cbb95d3SBarry Smith *f = PETSC_FALSE; 25281cbb95d3SBarry Smith goto done; 25291cbb95d3SBarry Smith } else { 25301cbb95d3SBarry Smith aptr[i]++; 25311cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 25321cbb95d3SBarry Smith } 25331cbb95d3SBarry Smith } 25341cbb95d3SBarry Smith } 25351cbb95d3SBarry Smith done: 25361cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 25371cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 25381cbb95d3SBarry Smith PetscFunctionReturn(0); 25391cbb95d3SBarry Smith } 25401cbb95d3SBarry Smith 2541ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25429e29f15eSvictorle { 2543dfbe8321SBarry Smith PetscErrorCode ierr; 25446e111a19SKarl Rupp 25459e29f15eSvictorle PetscFunctionBegin; 25465485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25479e29f15eSvictorle PetscFunctionReturn(0); 25489e29f15eSvictorle } 25499e29f15eSvictorle 2550ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25511cbb95d3SBarry Smith { 25521cbb95d3SBarry Smith PetscErrorCode ierr; 25536e111a19SKarl Rupp 25541cbb95d3SBarry Smith PetscFunctionBegin; 25551cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25561cbb95d3SBarry Smith PetscFunctionReturn(0); 25571cbb95d3SBarry Smith } 25581cbb95d3SBarry Smith 2559dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 256017ab2063SBarry Smith { 2561416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2562fff8e43fSBarry Smith const PetscScalar *l,*r; 2563fff8e43fSBarry Smith PetscScalar x; 256454f21887SBarry Smith MatScalar *v; 2565dfbe8321SBarry Smith PetscErrorCode ierr; 2566fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2567fff8e43fSBarry Smith const PetscInt *jj; 256817ab2063SBarry Smith 25693a40ed3dSBarry Smith PetscFunctionBegin; 257017ab2063SBarry Smith if (ll) { 25713ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 25723ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2573e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2574e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2575fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 25762e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 257717ab2063SBarry Smith for (i=0; i<m; i++) { 257817ab2063SBarry Smith x = l[i]; 2579416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 25802205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 258117ab2063SBarry Smith } 2582fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2583efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 25842e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 258517ab2063SBarry Smith } 258617ab2063SBarry Smith if (rr) { 2587e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2588e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2589fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 25902e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 25912e5835c6SStefano Zampini jj = a->j; 25922205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 25932e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 2594fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2595efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 259617ab2063SBarry Smith } 2597acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 25988c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2599c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2600e2cf4d64SStefano Zampini #endif 26013a40ed3dSBarry Smith PetscFunctionReturn(0); 260217ab2063SBarry Smith } 260317ab2063SBarry Smith 26047dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 260517ab2063SBarry Smith { 2606db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 26076849ba73SBarry Smith PetscErrorCode ierr; 2608d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 260997f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 26105d0c19d7SBarry Smith const PetscInt *irow,*icol; 26112e5835c6SStefano Zampini const PetscScalar *aa; 26125d0c19d7SBarry Smith PetscInt nrows,ncols; 261397f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 261454f21887SBarry Smith MatScalar *a_new,*mat_a; 2615416022c9SBarry Smith Mat C; 2616cdc6f3adSToby Isaac PetscBool stride; 261717ab2063SBarry Smith 26183a40ed3dSBarry Smith PetscFunctionBegin; 261917ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2620b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2621b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 262217ab2063SBarry Smith 2623251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2624ff718158SBarry Smith if (stride) { 2625ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2626ff718158SBarry Smith } else { 2627ff718158SBarry Smith first = 0; 2628ff718158SBarry Smith step = 0; 2629ff718158SBarry Smith } 2630fee21e36SBarry Smith if (stride && step == 1) { 263102834360SBarry Smith /* special case of contiguous rows */ 2632dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 263302834360SBarry Smith /* loop over new rows determining lens and starting points */ 263402834360SBarry Smith for (i=0; i<nrows; i++) { 2635bfeeae90SHong Zhang kstart = ai[irow[i]]; 2636a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2637a91a9bebSLisandro Dalcin starts[i] = kstart; 263802834360SBarry Smith for (k=kstart; k<kend; k++) { 2639bfeeae90SHong Zhang if (aj[k] >= first) { 264002834360SBarry Smith starts[i] = k; 264102834360SBarry Smith break; 264202834360SBarry Smith } 264302834360SBarry Smith } 2644a2744918SBarry Smith sum = 0; 264502834360SBarry Smith while (k < kend) { 2646bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2647a2744918SBarry Smith sum++; 264802834360SBarry Smith } 2649a2744918SBarry Smith lens[i] = sum; 265002834360SBarry Smith } 265102834360SBarry Smith /* create submatrix */ 2652cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 265397f1f81fSBarry Smith PetscInt n_cols,n_rows; 265408480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2655e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2656d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 265708480c60SBarry Smith C = *B; 26583a40ed3dSBarry Smith } else { 26593bef6203SJed Brown PetscInt rbs,cbs; 2660ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2661f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 26623bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 26633bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 26643bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 26657adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2666ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 266708480c60SBarry Smith } 2668db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2669db02288aSLois Curfman McInnes 267002834360SBarry Smith /* loop over rows inserting into submatrix */ 2671db02288aSLois Curfman McInnes a_new = c->a; 2672db02288aSLois Curfman McInnes j_new = c->j; 2673db02288aSLois Curfman McInnes i_new = c->i; 26742e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 267502834360SBarry Smith for (i=0; i<nrows; i++) { 2676a2744918SBarry Smith ii = starts[i]; 2677a2744918SBarry Smith lensi = lens[i]; 2678a2744918SBarry Smith for (k=0; k<lensi; k++) { 2679a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 268002834360SBarry Smith } 26812e5835c6SStefano Zampini ierr = PetscArraycpy(a_new,aa + starts[i],lensi);CHKERRQ(ierr); 2682a2744918SBarry Smith a_new += lensi; 2683a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2684a2744918SBarry Smith c->ilen[i] = lensi; 268502834360SBarry Smith } 26862e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 26870e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 26883a40ed3dSBarry Smith } else { 268902834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 26901795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2691854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 26924dcab191SBarry Smith for (i=0; i<ncols; i++) { 2693d9ef940eSSatish 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); 26944dcab191SBarry Smith smap[icol[i]] = i+1; 26954dcab191SBarry Smith } 26964dcab191SBarry Smith 269702834360SBarry Smith /* determine lens of each row */ 269802834360SBarry Smith for (i=0; i<nrows; i++) { 2699bfeeae90SHong Zhang kstart = ai[irow[i]]; 270002834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 270102834360SBarry Smith lens[i] = 0; 270202834360SBarry Smith for (k=kstart; k<kend; k++) { 2703bfeeae90SHong Zhang if (smap[aj[k]]) { 270402834360SBarry Smith lens[i]++; 270502834360SBarry Smith } 270602834360SBarry Smith } 270702834360SBarry Smith } 270817ab2063SBarry Smith /* Create and fill new matrix */ 2709a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2710ace3abfcSBarry Smith PetscBool equal; 27110f5bd95cSBarry Smith 271299141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2713e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2714580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2715f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2716580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 271708480c60SBarry Smith C = *B; 27183a40ed3dSBarry Smith } else { 27193bef6203SJed Brown PetscInt rbs,cbs; 2720ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2721f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 27223bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 27233bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 27243bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 27257adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2726ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 272708480c60SBarry Smith } 27282e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 272999141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 273017ab2063SBarry Smith for (i=0; i<nrows; i++) { 273199141d43SSatish Balay row = irow[i]; 2732bfeeae90SHong Zhang kstart = ai[row]; 273399141d43SSatish Balay kend = kstart + a->ilen[row]; 2734bfeeae90SHong Zhang mat_i = c->i[i]; 273599141d43SSatish Balay mat_j = c->j + mat_i; 273699141d43SSatish Balay mat_a = c->a + mat_i; 273799141d43SSatish Balay mat_ilen = c->ilen + i; 273817ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2739bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2740ed480e8bSBarry Smith *mat_j++ = tcol - 1; 27412e5835c6SStefano Zampini *mat_a++ = aa[k]; 274299141d43SSatish Balay (*mat_ilen)++; 274399141d43SSatish Balay 274417ab2063SBarry Smith } 274517ab2063SBarry Smith } 274617ab2063SBarry Smith } 27472e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 274802834360SBarry Smith /* Free work space */ 274902834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2750606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2751606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2752cdc6f3adSToby Isaac /* sort */ 2753cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2754cdc6f3adSToby Isaac PetscInt ilen; 2755cdc6f3adSToby Isaac 2756cdc6f3adSToby Isaac mat_i = c->i[i]; 2757cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2758cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2759cdc6f3adSToby Isaac ilen = c->ilen[i]; 2760390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2761cdc6f3adSToby Isaac } 276202834360SBarry Smith } 27638c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2764b470e4b4SRichard Tran Mills ierr = MatBindToCPU(C,A->boundtocpu);CHKERRQ(ierr); 2765305c6ccfSStefano Zampini #endif 27666d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27676d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 276817ab2063SBarry Smith 276917ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2770416022c9SBarry Smith *B = C; 27713a40ed3dSBarry Smith PetscFunctionReturn(0); 277217ab2063SBarry Smith } 277317ab2063SBarry Smith 2774fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 277582d44351SHong Zhang { 277682d44351SHong Zhang PetscErrorCode ierr; 277782d44351SHong Zhang Mat B; 277882d44351SHong Zhang 277982d44351SHong Zhang PetscFunctionBegin; 2780c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 278182d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 278282d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 278333d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 278482d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 278582d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 278682d44351SHong Zhang *subMat = B; 2787c2d650bdSHong Zhang } else { 2788c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2789c2d650bdSHong Zhang } 279082d44351SHong Zhang PetscFunctionReturn(0); 279182d44351SHong Zhang } 279282d44351SHong Zhang 27939a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2794a871dcd8SBarry Smith { 279563b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2796dfbe8321SBarry Smith PetscErrorCode ierr; 279763b91edcSBarry Smith Mat outA; 2798ace3abfcSBarry Smith PetscBool row_identity,col_identity; 279963b91edcSBarry Smith 28003a40ed3dSBarry Smith PetscFunctionBegin; 2801e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 28021df811f5SHong Zhang 2803b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2804b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2805a871dcd8SBarry Smith 280663b91edcSBarry Smith outA = inA; 2807d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2808f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2809f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 28102205254eSKarl Rupp 2811c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 28126bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 28132205254eSKarl Rupp 2814c3122656SLisandro Dalcin a->row = row; 28152205254eSKarl Rupp 2816c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 28176bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 28182205254eSKarl Rupp 2819c3122656SLisandro Dalcin a->col = col; 282063b91edcSBarry Smith 282136db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 28226bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 28234c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 28243bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2825f0ec6fceSSatish Balay 282694a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2827854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 28283bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 282994a9d846SBarry Smith } 283063b91edcSBarry Smith 2831f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2832137fb511SHong Zhang if (row_identity && col_identity) { 2833ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2834137fb511SHong Zhang } else { 2835719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2836137fb511SHong Zhang } 28373a40ed3dSBarry Smith PetscFunctionReturn(0); 2838a871dcd8SBarry Smith } 2839a871dcd8SBarry Smith 2840f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2841f0b747eeSBarry Smith { 2842f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2843dfa0f9e5SStefano Zampini PetscScalar *v; 2844efee365bSSatish Balay PetscErrorCode ierr; 2845c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 28463a40ed3dSBarry Smith 28473a40ed3dSBarry Smith PetscFunctionBegin; 2848dfa0f9e5SStefano Zampini ierr = MatSeqAIJGetArray(inA,&v);CHKERRQ(ierr); 2849c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 2850dfa0f9e5SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&alpha,v,&one)); 2851efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2852dfa0f9e5SStefano Zampini ierr = MatSeqAIJRestoreArray(inA,&v);CHKERRQ(ierr); 2853acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 28543a40ed3dSBarry Smith PetscFunctionReturn(0); 2855f0b747eeSBarry Smith } 2856f0b747eeSBarry Smith 2857f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 285816b64355SHong Zhang { 285916b64355SHong Zhang PetscErrorCode ierr; 286016b64355SHong Zhang PetscInt i; 286116b64355SHong Zhang 286216b64355SHong Zhang PetscFunctionBegin; 286316b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 286416b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 286516b64355SHong Zhang 286616b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 286716b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 286816b64355SHong Zhang } 286916b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 287016b64355SHong Zhang 287116b64355SHong Zhang if (submatj->rbuf1) { 287216b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 287316b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 287416b64355SHong Zhang } 287516b64355SHong Zhang 287616b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 287716b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 287816b64355SHong Zhang } 287916b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 288016b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 288116b64355SHong Zhang } 288216b64355SHong Zhang 288316b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 288416b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 288516b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 288616b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 288716b64355SHong Zhang #else 288816b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 288916b64355SHong Zhang #endif 289016b64355SHong Zhang 289116b64355SHong Zhang if (!submatj->allcolumns) { 289216b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 289316b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 289416b64355SHong Zhang #else 289516b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 289616b64355SHong Zhang #endif 289716b64355SHong Zhang } 289816b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 289916b64355SHong Zhang 290016b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 290116b64355SHong Zhang PetscFunctionReturn(0); 290216b64355SHong Zhang } 290316b64355SHong Zhang 29040fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 290516b64355SHong Zhang { 290616b64355SHong Zhang PetscErrorCode ierr; 290716b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 29085c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 290916b64355SHong Zhang 291016b64355SHong Zhang PetscFunctionBegin; 291134136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2912f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 291316b64355SHong Zhang PetscFunctionReturn(0); 291416b64355SHong Zhang } 291516b64355SHong Zhang 29162d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 29172d033e1fSHong Zhang { 29182d033e1fSHong Zhang PetscErrorCode ierr; 29192d033e1fSHong Zhang PetscInt i; 29200fb991dcSHong Zhang Mat C; 29210fb991dcSHong Zhang Mat_SeqAIJ *c; 29220fb991dcSHong Zhang Mat_SubSppt *submatj; 29232d033e1fSHong Zhang 29242d033e1fSHong Zhang PetscFunctionBegin; 29252d033e1fSHong Zhang for (i=0; i<n; i++) { 29260fb991dcSHong Zhang C = (*mat)[i]; 29270fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 29280fb991dcSHong Zhang submatj = c->submatis1; 29292d033e1fSHong Zhang if (submatj) { 2930682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 293134136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2932f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 293334136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 29342d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 29352d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 29362d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2937682e4c99SStefano Zampini } 29382d033e1fSHong Zhang } else { 29392d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 29402d033e1fSHong Zhang } 29412d033e1fSHong Zhang } 294286e85357SHong Zhang 294363a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 294463a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 294563a75b2aSHong Zhang 29462d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 29472d033e1fSHong Zhang PetscFunctionReturn(0); 29482d033e1fSHong Zhang } 29492d033e1fSHong Zhang 29507dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2951cddf8d76SBarry Smith { 2952dfbe8321SBarry Smith PetscErrorCode ierr; 295397f1f81fSBarry Smith PetscInt i; 2954cddf8d76SBarry Smith 29553a40ed3dSBarry Smith PetscFunctionBegin; 2956cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2957df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2958cddf8d76SBarry Smith } 2959cddf8d76SBarry Smith 2960cddf8d76SBarry Smith for (i=0; i<n; i++) { 29617dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2962cddf8d76SBarry Smith } 29633a40ed3dSBarry Smith PetscFunctionReturn(0); 2964cddf8d76SBarry Smith } 2965cddf8d76SBarry Smith 296697f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 29674dcbc457SBarry Smith { 2968e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29696849ba73SBarry Smith PetscErrorCode ierr; 29705d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 29715d0c19d7SBarry Smith const PetscInt *idx; 297297f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2973f1af5d2fSBarry Smith PetscBT table; 2974bbd702dbSSatish Balay 29753a40ed3dSBarry Smith PetscFunctionBegin; 2976d0f46423SBarry Smith m = A->rmap->n; 2977e4d965acSSatish Balay ai = a->i; 2978bfeeae90SHong Zhang aj = a->j; 29798a047759SSatish Balay 2980e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 298106763907SSatish Balay 2982854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 298353b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 298406763907SSatish Balay 2985e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2986b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2987e4d965acSSatish Balay isz = 0; 29886831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2989e4d965acSSatish Balay 2990e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 29914dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2992b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2993e4d965acSSatish Balay 2994dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2995e4d965acSSatish Balay for (j=0; j<n; ++j) { 29962205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 29974dcbc457SBarry Smith } 299806763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 29996bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 3000e4d965acSSatish Balay 300104a348a9SBarry Smith k = 0; 300204a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 300304a348a9SBarry Smith n = isz; 300406763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 3005e4d965acSSatish Balay row = nidx[k]; 3006e4d965acSSatish Balay start = ai[row]; 3007e4d965acSSatish Balay end = ai[row+1]; 300804a348a9SBarry Smith for (l = start; l<end; l++) { 3009efb16452SHong Zhang val = aj[l]; 30102205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 3011e4d965acSSatish Balay } 3012e4d965acSSatish Balay } 3013e4d965acSSatish Balay } 301470b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 3015e4d965acSSatish Balay } 301694bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 3017606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 30183a40ed3dSBarry Smith PetscFunctionReturn(0); 30194dcbc457SBarry Smith } 302017ab2063SBarry Smith 30210513a670SBarry Smith /* -------------------------------------------------------------- */ 3022dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 30230513a670SBarry Smith { 30240513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 30256849ba73SBarry Smith PetscErrorCode ierr; 30263b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 30275d0c19d7SBarry Smith const PetscInt *row,*col; 30285d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 302956cd22aeSBarry Smith IS icolp,irowp; 30300298fd71SBarry Smith PetscInt *cwork = NULL; 30310298fd71SBarry Smith PetscScalar *vwork = NULL; 30320513a670SBarry Smith 30333a40ed3dSBarry Smith PetscFunctionBegin; 30344c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 303556cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 30364c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 303756cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 30380513a670SBarry Smith 30390513a670SBarry Smith /* determine lengths of permuted rows */ 3040854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 30412205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 3042ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 3043f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 304433d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 30457adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 3046ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 3047606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 30480513a670SBarry Smith 3049785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 30500513a670SBarry Smith for (i=0; i<m; i++) { 305132ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30522205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 3053cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 305432ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30550513a670SBarry Smith } 3056606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 30572205254eSKarl Rupp 30583c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 30592205254eSKarl Rupp 30608c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3061b470e4b4SRichard Tran Mills ierr = MatBindToCPU(*B,A->boundtocpu);CHKERRQ(ierr); 30629fe5e383SStefano Zampini #endif 30630513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30640513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 306556cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 306656cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 30676bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 30686bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 30696768869dSprj- if (rowp == colp) { 3070dc29a518SPierre Jolivet ierr = MatPropagateSymmetryOptions(A,*B);CHKERRQ(ierr); 30716768869dSprj- } 30723a40ed3dSBarry Smith PetscFunctionReturn(0); 30730513a670SBarry Smith } 30740513a670SBarry Smith 3075dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 3076cb5b572fSBarry Smith { 3077dfbe8321SBarry Smith PetscErrorCode ierr; 3078cb5b572fSBarry Smith 3079cb5b572fSBarry Smith PetscFunctionBegin; 308033f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 308133f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 3082be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3083be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 30842e5835c6SStefano Zampini const PetscScalar *aa; 3085be6bf707SBarry Smith 30862e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 30874d805d7cSStefano 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]); 30882e5835c6SStefano Zampini ierr = PetscArraycpy(b->a,aa,a->i[A->rmap->n]);CHKERRQ(ierr); 3089cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 30902e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 3091cb5b572fSBarry Smith } else { 3092cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3093cb5b572fSBarry Smith } 3094cb5b572fSBarry Smith PetscFunctionReturn(0); 3095cb5b572fSBarry Smith } 3096cb5b572fSBarry Smith 30974994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 3098273d9f13SBarry Smith { 3099dfbe8321SBarry Smith PetscErrorCode ierr; 3100273d9f13SBarry Smith 3101273d9f13SBarry Smith PetscFunctionBegin; 3102f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 3103273d9f13SBarry Smith PetscFunctionReturn(0); 3104273d9f13SBarry Smith } 3105273d9f13SBarry Smith 3106f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 31076c0721eeSBarry Smith { 31086c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 31096e111a19SKarl Rupp 31106c0721eeSBarry Smith PetscFunctionBegin; 31116c0721eeSBarry Smith *array = a->a; 31126c0721eeSBarry Smith PetscFunctionReturn(0); 31136c0721eeSBarry Smith } 31146c0721eeSBarry Smith 3115f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 31166c0721eeSBarry Smith { 31176c0721eeSBarry Smith PetscFunctionBegin; 3118f38c1e66SStefano Zampini *array = NULL; 31196c0721eeSBarry Smith PetscFunctionReturn(0); 31206c0721eeSBarry Smith } 3121273d9f13SBarry Smith 31228229c054SShri Abhyankar /* 31238229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 31248229c054SShri Abhyankar have different nonzero structure. 31258229c054SShri Abhyankar */ 3126b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 3127ec7775f6SShri Abhyankar { 3128b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 3129ec7775f6SShri Abhyankar 3130ec7775f6SShri Abhyankar PetscFunctionBegin; 3131ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 3132ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 3133b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 3134b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 3135b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 31368af7cee1SJed Brown nnz[i] = 0; 31378af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 3138b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 3139b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 31408af7cee1SJed Brown nnz[i]++; 31418af7cee1SJed Brown } 31428af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 3143ec7775f6SShri Abhyankar } 3144ec7775f6SShri Abhyankar PetscFunctionReturn(0); 3145ec7775f6SShri Abhyankar } 3146ec7775f6SShri Abhyankar 3147b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 3148b264fe52SHong Zhang { 3149b264fe52SHong Zhang PetscInt m = Y->rmap->N; 3150b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 3151b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 3152b264fe52SHong Zhang PetscErrorCode ierr; 3153b264fe52SHong Zhang 3154b264fe52SHong Zhang PetscFunctionBegin; 3155b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 3156b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 3157b264fe52SHong Zhang PetscFunctionReturn(0); 3158b264fe52SHong Zhang } 3159b264fe52SHong Zhang 3160f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 3161ac90fabeSBarry Smith { 3162dfbe8321SBarry Smith PetscErrorCode ierr; 3163ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 3164ac90fabeSBarry Smith 3165ac90fabeSBarry Smith PetscFunctionBegin; 316641f5e1b1SStefano Zampini if (str == UNKNOWN_NONZERO_PATTERN && x->nz == y->nz) { 316781fa06acSBarry Smith PetscBool e; 316881fa06acSBarry Smith ierr = PetscArraycmp(x->i,y->i,Y->rmap->n+1,&e);CHKERRQ(ierr); 316981fa06acSBarry Smith if (e) { 317081fa06acSBarry Smith ierr = PetscArraycmp(x->j,y->j,y->nz,&e);CHKERRQ(ierr); 317181fa06acSBarry Smith if (e) { 317281fa06acSBarry Smith str = SAME_NONZERO_PATTERN; 317381fa06acSBarry Smith } 317481fa06acSBarry Smith } 317581fa06acSBarry Smith } 3176ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 31772e5835c6SStefano Zampini const PetscScalar *xa; 31782e5835c6SStefano Zampini PetscScalar *ya,alpha = a; 317981fa06acSBarry Smith PetscBLASInt one = 1,bnz; 318081fa06acSBarry Smith 318181fa06acSBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 31822e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(Y,&ya);CHKERRQ(ierr); 31832e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(X,&xa);CHKERRQ(ierr); 31842e5835c6SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,xa,&one,ya,&one)); 31852e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(X,&xa);CHKERRQ(ierr); 31862e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(Y,&ya);CHKERRQ(ierr); 318741f5e1b1SStefano Zampini ierr = PetscLogFlops(2.0*bnz);CHKERRQ(ierr); 3188acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 3189a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 3190ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 3191ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 3192ac90fabeSBarry Smith } else { 31938229c054SShri Abhyankar Mat B; 31948229c054SShri Abhyankar PetscInt *nnz; 3195785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 3196ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 3197bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 319881fa06acSBarry Smith ierr = MatSetLayouts(B,Y->rmap,Y->cmap);CHKERRQ(ierr); 31992e5835c6SStefano Zampini ierr = MatSetType(B,((PetscObject)Y)->type_name);CHKERRQ(ierr); 32008229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 3201ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 3202ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 320328be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 32048229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 3205ac90fabeSBarry Smith } 3206ac90fabeSBarry Smith PetscFunctionReturn(0); 3207ac90fabeSBarry Smith } 3208ac90fabeSBarry Smith 32092726fb6dSPierre Jolivet PETSC_INTERN PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3210354c94deSBarry Smith { 3211354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3212354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3213354c94deSBarry Smith PetscInt i,nz; 3214354c94deSBarry Smith PetscScalar *a; 3215ce496241SStefano Zampini PetscErrorCode ierr; 3216354c94deSBarry Smith 3217354c94deSBarry Smith PetscFunctionBegin; 3218354c94deSBarry Smith nz = aij->nz; 3219ce496241SStefano Zampini ierr = MatSeqAIJGetArray(mat,&a);CHKERRQ(ierr); 32202205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 3221ce496241SStefano Zampini ierr = MatSeqAIJRestoreArray(mat,&a);CHKERRQ(ierr); 3222354c94deSBarry Smith #else 3223354c94deSBarry Smith PetscFunctionBegin; 3224354c94deSBarry Smith #endif 3225354c94deSBarry Smith PetscFunctionReturn(0); 3226354c94deSBarry Smith } 3227354c94deSBarry Smith 3228985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3229e34fafa9SBarry Smith { 3230e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3231e34fafa9SBarry Smith PetscErrorCode ierr; 3232d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3233e34fafa9SBarry Smith PetscReal atmp; 3234985db425SBarry Smith PetscScalar *x; 3235ce496241SStefano Zampini const MatScalar *aa,*av; 3236e34fafa9SBarry Smith 3237e34fafa9SBarry Smith PetscFunctionBegin; 3238e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3239ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3240ce496241SStefano Zampini aa = av; 3241e34fafa9SBarry Smith ai = a->i; 3242e34fafa9SBarry Smith aj = a->j; 3243e34fafa9SBarry Smith 3244985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3245475b8b61SHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3246e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3247e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3248e34fafa9SBarry Smith for (i=0; i<m; i++) { 3249e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 3250e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3251985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3252985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3253985db425SBarry Smith aa++; aj++; 3254985db425SBarry Smith } 3255985db425SBarry Smith } 3256475b8b61SHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3257ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3258985db425SBarry Smith PetscFunctionReturn(0); 3259985db425SBarry Smith } 3260985db425SBarry Smith 3261985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3262985db425SBarry Smith { 3263985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3264985db425SBarry Smith PetscErrorCode ierr; 3265d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3266985db425SBarry Smith PetscScalar *x; 3267ce496241SStefano Zampini const MatScalar *aa,*av; 3268985db425SBarry Smith 3269985db425SBarry Smith PetscFunctionBegin; 3270e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3271ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3272ce496241SStefano Zampini aa = av; 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); 3303ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3304985db425SBarry Smith PetscFunctionReturn(0); 3305985db425SBarry Smith } 3306985db425SBarry Smith 3307c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3308c87e5d42SMatthew Knepley { 3309c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3310c87e5d42SMatthew Knepley PetscErrorCode ierr; 3311c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3312ce496241SStefano Zampini PetscScalar *x; 3313ce496241SStefano Zampini const MatScalar *aa,*av; 3314c87e5d42SMatthew Knepley 3315c87e5d42SMatthew Knepley PetscFunctionBegin; 3316ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3317ce496241SStefano Zampini aa = av; 3318c87e5d42SMatthew Knepley ai = a->i; 3319c87e5d42SMatthew Knepley aj = a->j; 3320c87e5d42SMatthew Knepley 3321c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3322f07e67edSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3323c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3324f07e67edSHong Zhang if (n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %D vs. %D rows", m, n); 3325c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3326c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3327f07e67edSHong Zhang if (ncols == A->cmap->n) { /* row is dense */ 3328f07e67edSHong Zhang x[i] = *aa; if (idx) idx[i] = 0; 3329f07e67edSHong Zhang } else { /* row is sparse so already KNOW minimum is 0.0 or higher */ 3330f07e67edSHong Zhang x[i] = 0.0; 3331f07e67edSHong Zhang if (idx) { /* find first implicit 0.0 in the row */ 3332289a08f5SMatthew Knepley for (j=0; j<ncols; j++) { 3333f07e67edSHong Zhang if (aj[j] > j) { 3334f07e67edSHong Zhang idx[i] = j; 33352205254eSKarl Rupp break; 33362205254eSKarl Rupp } 3337289a08f5SMatthew Knepley } 3338f07e67edSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3339f07e67edSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3340f07e67edSHong Zhang } 3341289a08f5SMatthew Knepley } 3342c87e5d42SMatthew Knepley for (j=0; j<ncols; j++) { 3343f07e67edSHong Zhang if (PetscAbsScalar(x[i]) > PetscAbsScalar(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3344c87e5d42SMatthew Knepley aa++; aj++; 3345c87e5d42SMatthew Knepley } 3346c87e5d42SMatthew Knepley } 3347f07e67edSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3348ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3349c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3350c87e5d42SMatthew Knepley } 3351c87e5d42SMatthew Knepley 3352985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3353985db425SBarry Smith { 3354985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3355985db425SBarry Smith PetscErrorCode ierr; 3356d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3357d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3358985db425SBarry Smith PetscScalar *x; 3359ce496241SStefano Zampini const MatScalar *aa,*av; 3360985db425SBarry Smith 3361985db425SBarry Smith PetscFunctionBegin; 3362e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3363ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3364ce496241SStefano Zampini aa = av; 3365985db425SBarry Smith ai = a->i; 3366985db425SBarry Smith aj = a->j; 3367985db425SBarry Smith 3368985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3369fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3370985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3371f07e67edSHong Zhang if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3372985db425SBarry Smith for (i=0; i<m; i++) { 3373985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3374d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3375985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3376985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3377985db425SBarry Smith x[i] = 0.0; 3378985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3379985db425SBarry Smith for (j=0; j<ncols; j++) { 3380985db425SBarry Smith if (aj[j] > j) { 3381985db425SBarry Smith idx[i] = j; 3382985db425SBarry Smith break; 3383985db425SBarry Smith } 3384985db425SBarry Smith } 3385fa213d2fSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3386fa213d2fSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3387985db425SBarry Smith } 3388985db425SBarry Smith } 3389985db425SBarry Smith for (j=0; j<ncols; j++) { 3390985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3391985db425SBarry Smith aa++; aj++; 3392e34fafa9SBarry Smith } 3393e34fafa9SBarry Smith } 3394fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3395ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3396e34fafa9SBarry Smith PetscFunctionReturn(0); 3397e34fafa9SBarry Smith } 3398bbead8a2SBarry Smith 3399713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3400bbead8a2SBarry Smith { 3401bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3402bbead8a2SBarry Smith PetscErrorCode ierr; 340333d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3404bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 34050da83c2eSBarry Smith const PetscReal shift = 0.0; 34061a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3407bbead8a2SBarry Smith 3408bbead8a2SBarry Smith PetscFunctionBegin; 3409a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 34104a0d0026SBarry Smith if (a->ibdiagvalid) { 34114a0d0026SBarry Smith if (values) *values = a->ibdiag; 34124a0d0026SBarry Smith PetscFunctionReturn(0); 34134a0d0026SBarry Smith } 3414bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3415bbead8a2SBarry Smith if (!a->ibdiag) { 3416785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 34173bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3418bbead8a2SBarry Smith } 3419bbead8a2SBarry Smith diag = a->ibdiag; 3420bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3421bbead8a2SBarry Smith /* factor and invert each block */ 3422bbead8a2SBarry Smith switch (bs) { 3423bbead8a2SBarry Smith case 1: 3424bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3425bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3426ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3427ec1892c8SHong Zhang if (allowzeropivot) { 34287b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 34297b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 34307b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 34317b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 34327b6c816cSBarry 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); 3433ec1892c8SHong Zhang } 3434bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3435bbead8a2SBarry Smith } 3436bbead8a2SBarry Smith break; 3437bbead8a2SBarry Smith case 2: 3438bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3439bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3440bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3441a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34427b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 344396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3444bbead8a2SBarry Smith diag += 4; 3445bbead8a2SBarry Smith } 3446bbead8a2SBarry Smith break; 3447bbead8a2SBarry Smith case 3: 3448bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3449bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3450bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3451a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34527b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 345396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3454bbead8a2SBarry Smith diag += 9; 3455bbead8a2SBarry Smith } 3456bbead8a2SBarry Smith break; 3457bbead8a2SBarry Smith case 4: 3458bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3459bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3460bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3461a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34627b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 346396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3464bbead8a2SBarry Smith diag += 16; 3465bbead8a2SBarry Smith } 3466bbead8a2SBarry Smith break; 3467bbead8a2SBarry Smith case 5: 3468bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3469bbead8a2SBarry 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; 3470bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3471a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34727b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 347396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3474bbead8a2SBarry Smith diag += 25; 3475bbead8a2SBarry Smith } 3476bbead8a2SBarry Smith break; 3477bbead8a2SBarry Smith case 6: 3478bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3479bbead8a2SBarry 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; 3480bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3481a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34827b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 348396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3484bbead8a2SBarry Smith diag += 36; 3485bbead8a2SBarry Smith } 3486bbead8a2SBarry Smith break; 3487bbead8a2SBarry Smith case 7: 3488bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3489bbead8a2SBarry 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; 3490bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3491a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34927b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 349396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3494bbead8a2SBarry Smith diag += 49; 3495bbead8a2SBarry Smith } 3496bbead8a2SBarry Smith break; 3497bbead8a2SBarry Smith default: 3498dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3499bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3500bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3501bbead8a2SBarry Smith IJ[j] = bs*i + j; 3502bbead8a2SBarry Smith } 3503bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 35045f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 35057b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 350696b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3507bbead8a2SBarry Smith diag += bs2; 3508bbead8a2SBarry Smith } 3509bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3510bbead8a2SBarry Smith } 3511bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3512bbead8a2SBarry Smith PetscFunctionReturn(0); 3513bbead8a2SBarry Smith } 3514bbead8a2SBarry Smith 351573a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 351673a71a0fSBarry Smith { 351773a71a0fSBarry Smith PetscErrorCode ierr; 351873a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 351973a71a0fSBarry Smith PetscScalar a; 352073a71a0fSBarry Smith PetscInt m,n,i,j,col; 352173a71a0fSBarry Smith 352273a71a0fSBarry Smith PetscFunctionBegin; 352373a71a0fSBarry Smith if (!x->assembled) { 352473a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 352573a71a0fSBarry Smith for (i=0; i<m; i++) { 352673a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 352773a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 352873a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 352973a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 353073a71a0fSBarry Smith } 353173a71a0fSBarry Smith } 3532e2ce353bSJunchao Zhang } else { 3533e2ce353bSJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aij->a+i);CHKERRQ(ierr);} 3534e2ce353bSJunchao Zhang } 3535ce496241SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 3536ce496241SStefano Zampini if (x->offloadmask != PETSC_OFFLOAD_UNALLOCATED) x->offloadmask = PETSC_OFFLOAD_CPU; 3537ce496241SStefano Zampini #endif 353873a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 353973a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 354073a71a0fSBarry Smith PetscFunctionReturn(0); 354173a71a0fSBarry Smith } 354273a71a0fSBarry Smith 3543679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3544679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3545679944adSJunchao Zhang { 3546679944adSJunchao Zhang PetscErrorCode ierr; 3547679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3548679944adSJunchao Zhang PetscScalar a; 3549679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3550679944adSJunchao Zhang 3551679944adSJunchao Zhang PetscFunctionBegin; 3552679944adSJunchao Zhang nskip = high - low; 3553679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3554679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3555679944adSJunchao Zhang for (i=0; i<m; i++) { 3556679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3557679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3558679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3559679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3560679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3561679944adSJunchao Zhang } 3562e2ce353bSJunchao Zhang } 3563679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3564679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3565679944adSJunchao Zhang PetscFunctionReturn(0); 3566679944adSJunchao Zhang } 3567679944adSJunchao Zhang 3568682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 35690a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3570cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3571cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3572cb5b572fSBarry Smith MatMult_SeqAIJ, 357397304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 35747c922b88SBarry Smith MatMultTranspose_SeqAIJ, 35757c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3576f4259b30SLisandro Dalcin NULL, 3577f4259b30SLisandro Dalcin NULL, 3578f4259b30SLisandro Dalcin NULL, 3579f4259b30SLisandro Dalcin /* 10*/ NULL, 3580cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3581f4259b30SLisandro Dalcin NULL, 358241f059aeSBarry Smith MatSOR_SeqAIJ, 358391e9d3e2SHong Zhang MatTranspose_SeqAIJ, 358497304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3585cb5b572fSBarry Smith MatEqual_SeqAIJ, 3586cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3587cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3588cb5b572fSBarry Smith MatNorm_SeqAIJ, 3589f4259b30SLisandro Dalcin /* 20*/ NULL, 3590cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3591cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3592cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3593d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3594f4259b30SLisandro Dalcin NULL, 3595f4259b30SLisandro Dalcin NULL, 3596f4259b30SLisandro Dalcin NULL, 3597f4259b30SLisandro Dalcin NULL, 35984994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3599f4259b30SLisandro Dalcin NULL, 3600f4259b30SLisandro Dalcin NULL, 3601f4259b30SLisandro Dalcin NULL, 3602f4259b30SLisandro Dalcin NULL, 3603d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3604f4259b30SLisandro Dalcin NULL, 3605f4259b30SLisandro Dalcin NULL, 3606cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3607f4259b30SLisandro Dalcin NULL, 3608d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 36097dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3610cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3611cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3612cb5b572fSBarry Smith MatCopy_SeqAIJ, 3613d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3614cb5b572fSBarry Smith MatScale_SeqAIJ, 36157d68702bSBarry Smith MatShift_SeqAIJ, 361679299369SBarry Smith MatDiagonalSet_SeqAIJ, 36176e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 361873a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 36193b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 36203b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 36213b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3622a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 362393dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3624f4259b30SLisandro Dalcin NULL, 3625f4259b30SLisandro Dalcin NULL, 3626cda55fadSBarry Smith MatPermute_SeqAIJ, 3627f4259b30SLisandro Dalcin NULL, 3628f4259b30SLisandro Dalcin /* 59*/ NULL, 3629b9b97703SBarry Smith MatDestroy_SeqAIJ, 3630b9b97703SBarry Smith MatView_SeqAIJ, 3631f4259b30SLisandro Dalcin NULL, 3632f4259b30SLisandro Dalcin NULL, 3633f4259b30SLisandro Dalcin /* 64*/ NULL, 3634321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3635f4259b30SLisandro Dalcin NULL, 3636f4259b30SLisandro Dalcin NULL, 3637f4259b30SLisandro Dalcin NULL, 3638d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3639c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3640f4259b30SLisandro Dalcin NULL, 3641f4259b30SLisandro Dalcin NULL, 3642f4259b30SLisandro Dalcin NULL, 3643f4259b30SLisandro Dalcin /* 74*/ NULL, 36443acb8795SBarry Smith MatFDColoringApply_AIJ, 3645f4259b30SLisandro Dalcin NULL, 3646f4259b30SLisandro Dalcin NULL, 3647f4259b30SLisandro Dalcin NULL, 36486ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 3649f4259b30SLisandro Dalcin NULL, 3650f4259b30SLisandro Dalcin NULL, 3651f4259b30SLisandro Dalcin NULL, 3652bc011b1eSHong Zhang MatLoad_SeqAIJ, 3653d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 36541cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 3655f4259b30SLisandro Dalcin NULL, 3656f4259b30SLisandro Dalcin NULL, 3657f4259b30SLisandro Dalcin NULL, 3658f4259b30SLisandro Dalcin /* 89*/ NULL, 3659f4259b30SLisandro Dalcin NULL, 366026be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3661f4259b30SLisandro Dalcin NULL, 3662f4259b30SLisandro Dalcin NULL, 36638fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 3664f4259b30SLisandro Dalcin NULL, 3665f4259b30SLisandro Dalcin NULL, 36666fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 3667f4259b30SLisandro Dalcin NULL, 36684222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqAIJ, 3669f4259b30SLisandro Dalcin NULL, 3670f4259b30SLisandro Dalcin NULL, 367187d4246cSBarry Smith MatConjugate_SeqAIJ, 3672f4259b30SLisandro Dalcin NULL, 3673d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 367499cafbc1SBarry Smith MatRealPart_SeqAIJ, 3675f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3676f4259b30SLisandro Dalcin NULL, 3677f4259b30SLisandro Dalcin NULL, 3678cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3679f4259b30SLisandro Dalcin NULL, 36802af78befSBarry Smith MatGetRowMin_SeqAIJ, 3681f4259b30SLisandro Dalcin NULL, 3682599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3683f4259b30SLisandro Dalcin /*114*/ NULL, 3684f4259b30SLisandro Dalcin NULL, 3685f4259b30SLisandro Dalcin NULL, 3686f4259b30SLisandro Dalcin NULL, 3687f4259b30SLisandro Dalcin NULL, 3688f4259b30SLisandro Dalcin /*119*/ NULL, 3689f4259b30SLisandro Dalcin NULL, 3690f4259b30SLisandro Dalcin NULL, 3691f4259b30SLisandro Dalcin NULL, 3692b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 36930716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3694bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 369537868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 36960da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 3697f4259b30SLisandro Dalcin NULL, 3698f4259b30SLisandro Dalcin /*129*/ NULL, 3699f4259b30SLisandro Dalcin NULL, 3700f4259b30SLisandro Dalcin NULL, 370175648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3702b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3703b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 37042b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 3705f4259b30SLisandro Dalcin NULL, 3706f4259b30SLisandro Dalcin NULL, 37073964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 3708f4259b30SLisandro Dalcin /*139*/NULL, 3709f4259b30SLisandro Dalcin NULL, 3710f4259b30SLisandro Dalcin NULL, 37113a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 37129c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 37134222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 37144222ddf1SHong Zhang /*145*/MatDestroySubMatrices_SeqAIJ, 3715f4259b30SLisandro Dalcin NULL, 3716f4259b30SLisandro Dalcin NULL 37179e29f15eSvictorle }; 371817ab2063SBarry Smith 37197087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3720bef8e0ddSBarry Smith { 3721bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 372297f1f81fSBarry Smith PetscInt i,nz,n; 3723bef8e0ddSBarry Smith 3724bef8e0ddSBarry Smith PetscFunctionBegin; 3725bef8e0ddSBarry Smith nz = aij->maxnz; 3726d0f46423SBarry Smith n = mat->rmap->n; 3727bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3728bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3729bef8e0ddSBarry Smith } 3730bef8e0ddSBarry Smith aij->nz = nz; 3731bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3732bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3733bef8e0ddSBarry Smith } 3734bef8e0ddSBarry Smith PetscFunctionReturn(0); 3735bef8e0ddSBarry Smith } 3736bef8e0ddSBarry Smith 3737a3bb6f32SFande Kong /* 3738e8b528d9SFande Kong * When a sparse matrix has many zero columns, we should compact them out to save the space 3739a3bb6f32SFande Kong * This happens in MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3740a3bb6f32SFande Kong * */ 3741a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3742a3bb6f32SFande Kong { 3743a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3744a3bb6f32SFande Kong PetscTable gid1_lid1; 3745a3bb6f32SFande Kong PetscTablePosition tpos; 374625b670f0SStefano Zampini PetscInt gid,lid,i,ec,nz = aij->nz; 374725b670f0SStefano Zampini PetscInt *garray,*jj = aij->j; 3748a3bb6f32SFande Kong PetscErrorCode ierr; 3749a3bb6f32SFande Kong 3750a3bb6f32SFande Kong PetscFunctionBegin; 3751a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3752a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3753a3bb6f32SFande Kong /* use a table */ 3754a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3755a3bb6f32SFande Kong ec = 0; 375625b670f0SStefano Zampini for (i=0; i<nz; i++) { 375725b670f0SStefano Zampini PetscInt data,gid1 = jj[i] + 1; 3758a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3759a3bb6f32SFande Kong if (!data) { 3760a3bb6f32SFande Kong /* one based table */ 3761a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3762a3bb6f32SFande Kong } 3763a3bb6f32SFande Kong } 3764a3bb6f32SFande Kong /* form array of columns we need */ 3765a3bb6f32SFande Kong ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); 3766a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3767a3bb6f32SFande Kong while (tpos) { 3768a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3769a3bb6f32SFande Kong gid--; 3770a3bb6f32SFande Kong lid--; 3771a3bb6f32SFande Kong garray[lid] = gid; 3772a3bb6f32SFande Kong } 3773a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3774a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3775a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3776a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3777a3bb6f32SFande Kong } 3778a3bb6f32SFande Kong /* compact out the extra columns in B */ 377925b670f0SStefano Zampini for (i=0; i<nz; i++) { 378025b670f0SStefano Zampini PetscInt gid1 = jj[i] + 1; 3781a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3782a3bb6f32SFande Kong lid--; 378325b670f0SStefano Zampini jj[i] = lid; 3784a3bb6f32SFande Kong } 3785ca5434daSLawrence Mitchell ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 3786a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 378725b670f0SStefano Zampini ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr); 3788a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3789a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3790a3bb6f32SFande Kong PetscFunctionReturn(0); 3791a3bb6f32SFande Kong } 3792a3bb6f32SFande Kong 3793bef8e0ddSBarry Smith /*@ 3794bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3795bef8e0ddSBarry Smith in the matrix. 3796bef8e0ddSBarry Smith 3797bef8e0ddSBarry Smith Input Parameters: 3798bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3799bef8e0ddSBarry Smith - indices - the column indices 3800bef8e0ddSBarry Smith 380115091d37SBarry Smith Level: advanced 380215091d37SBarry Smith 3803bef8e0ddSBarry Smith Notes: 3804bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3805bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3806bef8e0ddSBarry Smith of the MatSetValues() operation. 3807bef8e0ddSBarry Smith 3808bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3809d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3810bef8e0ddSBarry Smith 3811bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3812bef8e0ddSBarry Smith 3813b9617806SBarry Smith The indices should start with zero, not one. 3814b9617806SBarry Smith 3815bef8e0ddSBarry Smith @*/ 38167087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3817bef8e0ddSBarry Smith { 38184ac538c5SBarry Smith PetscErrorCode ierr; 3819bef8e0ddSBarry Smith 3820bef8e0ddSBarry Smith PetscFunctionBegin; 38210700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 38224482741eSBarry Smith PetscValidPointer(indices,2); 38234ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3824bef8e0ddSBarry Smith PetscFunctionReturn(0); 3825bef8e0ddSBarry Smith } 3826bef8e0ddSBarry Smith 3827be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3828be6bf707SBarry Smith 38297087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3830be6bf707SBarry Smith { 3831be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 38326849ba73SBarry Smith PetscErrorCode ierr; 3833d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3834be6bf707SBarry Smith 3835be6bf707SBarry Smith PetscFunctionBegin; 3836169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3837be6bf707SBarry Smith 3838be6bf707SBarry Smith /* allocate space for values if not already there */ 3839be6bf707SBarry Smith if (!aij->saved_values) { 3840854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 38413bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3842be6bf707SBarry Smith } 3843be6bf707SBarry Smith 3844be6bf707SBarry Smith /* copy values over */ 3845580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3846be6bf707SBarry Smith PetscFunctionReturn(0); 3847be6bf707SBarry Smith } 3848be6bf707SBarry Smith 3849be6bf707SBarry Smith /*@ 3850be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3851be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3852be6bf707SBarry Smith nonlinear portion. 3853be6bf707SBarry Smith 3854be6bf707SBarry Smith Collect on Mat 3855be6bf707SBarry Smith 3856be6bf707SBarry Smith Input Parameters: 38570e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3858be6bf707SBarry Smith 385915091d37SBarry Smith Level: advanced 386015091d37SBarry Smith 3861be6bf707SBarry Smith Common Usage, with SNESSolve(): 3862be6bf707SBarry Smith $ Create Jacobian matrix 3863be6bf707SBarry Smith $ Set linear terms into matrix 3864be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3865be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3866be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3867512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3868be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3869be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3870be6bf707SBarry Smith $ In your Jacobian routine 3871be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3872be6bf707SBarry Smith $ Set nonlinear terms in matrix 3873be6bf707SBarry Smith 3874be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3875be6bf707SBarry Smith $ // build linear portion of Jacobian 3876512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3877be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3878be6bf707SBarry Smith $ loop over nonlinear iterations 3879be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3880be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3881be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3882be6bf707SBarry Smith $ Solve linear system with Jacobian 3883be6bf707SBarry Smith $ endloop 3884be6bf707SBarry Smith 3885be6bf707SBarry Smith Notes: 3886be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3887512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3888be6bf707SBarry Smith calling this routine. 3889be6bf707SBarry Smith 38900c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 38910c468ba9SBarry Smith and does not allocated additional space. 38920c468ba9SBarry Smith 3893be6bf707SBarry Smith .seealso: MatRetrieveValues() 3894be6bf707SBarry Smith 3895be6bf707SBarry Smith @*/ 38967087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3897be6bf707SBarry Smith { 38984ac538c5SBarry Smith PetscErrorCode ierr; 3899be6bf707SBarry Smith 3900be6bf707SBarry Smith PetscFunctionBegin; 39010700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3902e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3903e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 39044ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3905be6bf707SBarry Smith PetscFunctionReturn(0); 3906be6bf707SBarry Smith } 3907be6bf707SBarry Smith 39087087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3909be6bf707SBarry Smith { 3910be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 39116849ba73SBarry Smith PetscErrorCode ierr; 3912d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3913be6bf707SBarry Smith 3914be6bf707SBarry Smith PetscFunctionBegin; 3915169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3916f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3917be6bf707SBarry Smith /* copy values over */ 3918580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3919be6bf707SBarry Smith PetscFunctionReturn(0); 3920be6bf707SBarry Smith } 3921be6bf707SBarry Smith 3922be6bf707SBarry Smith /*@ 3923be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3924be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3925be6bf707SBarry Smith nonlinear portion. 3926be6bf707SBarry Smith 3927be6bf707SBarry Smith Collect on Mat 3928be6bf707SBarry Smith 3929be6bf707SBarry Smith Input Parameters: 3930386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3931be6bf707SBarry Smith 393215091d37SBarry Smith Level: advanced 393315091d37SBarry Smith 3934be6bf707SBarry Smith .seealso: MatStoreValues() 3935be6bf707SBarry Smith 3936be6bf707SBarry Smith @*/ 39377087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3938be6bf707SBarry Smith { 39394ac538c5SBarry Smith PetscErrorCode ierr; 3940be6bf707SBarry Smith 3941be6bf707SBarry Smith PetscFunctionBegin; 39420700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3943e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3944e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 39454ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3946be6bf707SBarry Smith PetscFunctionReturn(0); 3947be6bf707SBarry Smith } 3948be6bf707SBarry Smith 3949be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 395017ab2063SBarry Smith /*@C 3951682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 39520d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 39536e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 395451c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 39552bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 395617ab2063SBarry Smith 3957d083f849SBarry Smith Collective 3958db81eaa0SLois Curfman McInnes 395917ab2063SBarry Smith Input Parameters: 3960db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 396117ab2063SBarry Smith . m - number of rows 396217ab2063SBarry Smith . n - number of columns 396317ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 396451c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39650298fd71SBarry Smith (possibly different for each row) or NULL 396617ab2063SBarry Smith 396717ab2063SBarry Smith Output Parameter: 3968416022c9SBarry Smith . A - the matrix 396917ab2063SBarry Smith 3970175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3971f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3972175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3973175b88e8SBarry Smith 3974b259b22eSLois Curfman McInnes Notes: 397549a6f317SBarry Smith If nnz is given then nz is ignored 397649a6f317SBarry Smith 397717ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 397817ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 39790002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 398044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 398117ab2063SBarry Smith 398217ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39830298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 39843d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 39856da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 398617ab2063SBarry Smith 3987682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 39884fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3989682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 39906c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 39916c7ebb05SLois Curfman McInnes 39926c7ebb05SLois Curfman McInnes Options Database Keys: 3993698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 39949db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 399517ab2063SBarry Smith 3996027ccd11SLois Curfman McInnes Level: intermediate 3997027ccd11SLois Curfman McInnes 399869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 399936db0b34SBarry Smith 400017ab2063SBarry Smith @*/ 40017087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 400217ab2063SBarry Smith { 4003dfbe8321SBarry Smith PetscErrorCode ierr; 40046945ee14SBarry Smith 40053a40ed3dSBarry Smith PetscFunctionBegin; 4006f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 4007117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 4008c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 4009d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 4010273d9f13SBarry Smith PetscFunctionReturn(0); 4011273d9f13SBarry Smith } 4012273d9f13SBarry Smith 4013273d9f13SBarry Smith /*@C 4014273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 4015273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 4016273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 4017273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 4018273d9f13SBarry Smith 4019d083f849SBarry Smith Collective 4020273d9f13SBarry Smith 4021273d9f13SBarry Smith Input Parameters: 40221c4f3114SJed Brown + B - The matrix 4023273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 4024273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 40250298fd71SBarry Smith (possibly different for each row) or NULL 4026273d9f13SBarry Smith 4027273d9f13SBarry Smith Notes: 402849a6f317SBarry Smith If nnz is given then nz is ignored 402949a6f317SBarry Smith 4030273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 4031273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 4032273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 4033273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 4034273d9f13SBarry Smith 4035273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 40360298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 4037273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 4038273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 4039273d9f13SBarry Smith 4040aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 4041aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 4042aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 4043aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 4044aa95bbe8SBarry Smith 4045a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 4046a96a251dSBarry Smith entries or columns indices 4047a96a251dSBarry Smith 4048273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 4049273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 4050273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 4051273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 4052273d9f13SBarry Smith 4053273d9f13SBarry Smith Options Database Keys: 4054698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 405547b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 4056273d9f13SBarry Smith 4057273d9f13SBarry Smith Level: intermediate 4058273d9f13SBarry Smith 405919b08ed1SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo(), 406019b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation() 4061273d9f13SBarry Smith 4062273d9f13SBarry Smith @*/ 40637087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 4064273d9f13SBarry Smith { 40654ac538c5SBarry Smith PetscErrorCode ierr; 4066a23d5eceSKris Buschelman 4067a23d5eceSKris Buschelman PetscFunctionBegin; 40686ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 40696ba663aaSJed Brown PetscValidType(B,1); 40704ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 4071a23d5eceSKris Buschelman PetscFunctionReturn(0); 4072a23d5eceSKris Buschelman } 4073a23d5eceSKris Buschelman 40747087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 4075a23d5eceSKris Buschelman { 4076273d9f13SBarry Smith Mat_SeqAIJ *b; 40772576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 40786849ba73SBarry Smith PetscErrorCode ierr; 407997f1f81fSBarry Smith PetscInt i; 4080273d9f13SBarry Smith 4081273d9f13SBarry Smith PetscFunctionBegin; 40822576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 4083a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 4084c461c341SBarry Smith skipallocation = PETSC_TRUE; 4085c461c341SBarry Smith nz = 0; 4086c461c341SBarry Smith } 408726283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 408826283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4089899cda47SBarry Smith 4090435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 409160e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 4092cf9c20a2SJed Brown if (PetscUnlikelyDebug(nnz)) { 4093d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 409460e0710aSBarry 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]); 409560e0710aSBarry 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); 4096b73539f3SBarry Smith } 4097b73539f3SBarry Smith } 4098b73539f3SBarry Smith 4099273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 41002205254eSKarl Rupp 4101273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 4102273d9f13SBarry Smith 4103ab93d7beSBarry Smith if (!skipallocation) { 41042ee49352SLisandro Dalcin if (!b->imax) { 4105071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 4106071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4107071fcb05SBarry Smith } 4108071fcb05SBarry Smith if (!b->ilen) { 4109071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 4110071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 4111071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4112071fcb05SBarry Smith } else { 4113071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 41142ee49352SLisandro Dalcin } 4115846b4da1SFande Kong if (!b->ipre) { 4116846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 4117846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4118846b4da1SFande Kong } 4119273d9f13SBarry Smith if (!nnz) { 4120435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 4121c62bd62aSJed Brown else if (nz < 0) nz = 1; 41225d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 4123d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 4124d0f46423SBarry Smith nz = nz*B->rmap->n; 4125273d9f13SBarry Smith } else { 4126c73702f5SBarry Smith PetscInt64 nz64 = 0; 4127c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 4128c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 4129273d9f13SBarry Smith } 4130ab93d7beSBarry Smith 4131273d9f13SBarry Smith /* allocate the matrix space */ 413253dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 41332ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 4134396832f4SHong Zhang if (B->structure_only) { 41355848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 41365848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 4137396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 4138396832f4SHong Zhang } else { 4139dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 41403bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 4141396832f4SHong Zhang } 4142bfeeae90SHong Zhang b->i[0] = 0; 4143d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 41445da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 41455da197adSKris Buschelman } 4146396832f4SHong Zhang if (B->structure_only) { 4147396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 4148396832f4SHong Zhang b->free_a = PETSC_FALSE; 4149396832f4SHong Zhang } else { 4150273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 4151e6b907acSBarry Smith b->free_a = PETSC_TRUE; 4152396832f4SHong Zhang } 4153e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 4154c461c341SBarry Smith } else { 4155e6b907acSBarry Smith b->free_a = PETSC_FALSE; 4156e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 4157c461c341SBarry Smith } 4158273d9f13SBarry Smith 4159846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 4160846b4da1SFande Kong /* reserve user-requested sparsity */ 4161580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 4162846b4da1SFande Kong } 4163846b4da1SFande Kong 4164273d9f13SBarry Smith b->nz = 0; 4165273d9f13SBarry Smith b->maxnz = nz; 4166273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 41672205254eSKarl Rupp if (realalloc) { 41682205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 41692205254eSKarl Rupp } 4170cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 4171cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 4172273d9f13SBarry Smith PetscFunctionReturn(0); 4173273d9f13SBarry Smith } 4174273d9f13SBarry Smith 4175846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 4176846b4da1SFande Kong { 4177846b4da1SFande Kong Mat_SeqAIJ *a; 4178a5bbaf83SFande Kong PetscInt i; 4179846b4da1SFande Kong PetscErrorCode ierr; 4180846b4da1SFande Kong 4181846b4da1SFande Kong PetscFunctionBegin; 4182846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 418314d0e64fSAlex Lindsay 418414d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 418514d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 418614d0e64fSAlex Lindsay 4187846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 41882c814fdeSFande Kong /* if no saved info, we error out */ 4189fb4dc15dSAlex Lindsay if (!a->ipre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 41902c814fdeSFande Kong 4191fb4dc15dSAlex 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"); 41922c814fdeSFande Kong 4193580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 4194580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 4195846b4da1SFande Kong a->i[0] = 0; 4196846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 4197846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 4198846b4da1SFande Kong } 4199846b4da1SFande Kong A->preallocated = PETSC_TRUE; 4200846b4da1SFande Kong a->nz = 0; 4201846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 4202846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 4203846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 4204846b4da1SFande Kong A->assembled = PETSC_FALSE; 4205846b4da1SFande Kong PetscFunctionReturn(0); 4206846b4da1SFande Kong } 4207846b4da1SFande Kong 420858d36128SBarry Smith /*@ 4209a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 4210a1661176SMatthew Knepley 4211a1661176SMatthew Knepley Input Parameters: 4212a1661176SMatthew Knepley + B - the matrix 4213a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4214a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4215a1661176SMatthew Knepley - v - optional values in the matrix 4216a1661176SMatthew Knepley 4217a1661176SMatthew Knepley Level: developer 4218a1661176SMatthew Knepley 42196a9b8d82SBarry Smith Notes: 422058d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 422158d36128SBarry Smith 42226a9b8d82SBarry Smith This routine may be called multiple times with different nonzero patterns (or the same nonzero pattern). The nonzero 42236a9b8d82SBarry Smith structure will be the union of all the previous nonzero structures. 42246a9b8d82SBarry Smith 42256a9b8d82SBarry Smith Developer Notes: 42266a9b8d82SBarry 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 42276a9b8d82SBarry Smith then just copies the v values directly with PetscMemcpy(). 42286a9b8d82SBarry Smith 42296a9b8d82SBarry Smith This routine could also take a PetscCopyMode argument to allow sharing the values instead of always copying them. 42306a9b8d82SBarry Smith 42316a9b8d82SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ, MatResetPreallocation() 4232a1661176SMatthew Knepley @*/ 4233a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4234a1661176SMatthew Knepley { 4235a1661176SMatthew Knepley PetscErrorCode ierr; 4236a1661176SMatthew Knepley 4237a1661176SMatthew Knepley PetscFunctionBegin; 42380700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 42396ba663aaSJed Brown PetscValidType(B,1); 42404ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 4241a1661176SMatthew Knepley PetscFunctionReturn(0); 4242a1661176SMatthew Knepley } 4243a1661176SMatthew Knepley 42447087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4245a1661176SMatthew Knepley { 4246a1661176SMatthew Knepley PetscInt i; 4247a1661176SMatthew Knepley PetscInt m,n; 4248a1661176SMatthew Knepley PetscInt nz; 42496a9b8d82SBarry Smith PetscInt *nnz; 4250a1661176SMatthew Knepley PetscErrorCode ierr; 4251a1661176SMatthew Knepley 4252a1661176SMatthew Knepley PetscFunctionBegin; 425365e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4254779a8d59SSatish Balay 4255779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4256779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4257779a8d59SSatish Balay 4258779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4259854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 4260a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4261b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 426265e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4263a1661176SMatthew Knepley nnz[i] = nz; 4264a1661176SMatthew Knepley } 4265a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4266a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4267a1661176SMatthew Knepley 4268a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4269071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 4270a1661176SMatthew Knepley } 4271a1661176SMatthew Knepley 4272a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4273a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4274a1661176SMatthew Knepley 42757827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4276a1661176SMatthew Knepley PetscFunctionReturn(0); 4277a1661176SMatthew Knepley } 4278a1661176SMatthew Knepley 4279c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4280af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4281170fe5c8SBarry Smith 4282170fe5c8SBarry Smith /* 4283170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4284170fe5c8SBarry Smith 4285170fe5c8SBarry Smith n p p 42862da392ccSBarry Smith [ ] [ ] [ ] 42872da392ccSBarry Smith m [ A ] * n [ B ] = m [ C ] 42882da392ccSBarry Smith [ ] [ ] [ ] 4289170fe5c8SBarry Smith 4290170fe5c8SBarry Smith */ 4291170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4292170fe5c8SBarry Smith { 4293170fe5c8SBarry Smith PetscErrorCode ierr; 4294170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4295170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4296170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 429786214ceeSStefano Zampini PetscInt i,j,n,m,q,p; 4298170fe5c8SBarry Smith const PetscInt *ii,*idx; 4299170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4300170fe5c8SBarry Smith PetscScalar *c,*c_q; 430186214ceeSStefano Zampini PetscInt clda = sub_c->lda; 430286214ceeSStefano Zampini PetscInt alda = sub_a->lda; 4303170fe5c8SBarry Smith 4304170fe5c8SBarry Smith PetscFunctionBegin; 4305d0f46423SBarry Smith m = A->rmap->n; 4306d0f46423SBarry Smith n = A->cmap->n; 4307d0f46423SBarry Smith p = B->cmap->n; 4308170fe5c8SBarry Smith a = sub_a->v; 4309170fe5c8SBarry Smith b = sub_b->a; 4310170fe5c8SBarry Smith c = sub_c->v; 431186214ceeSStefano Zampini if (clda == m) { 4312580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 431386214ceeSStefano Zampini } else { 431486214ceeSStefano Zampini for (j=0;j<p;j++) 431586214ceeSStefano Zampini for (i=0;i<m;i++) 431686214ceeSStefano Zampini c[j*clda + i] = 0.0; 431786214ceeSStefano Zampini } 4318170fe5c8SBarry Smith ii = sub_b->i; 4319170fe5c8SBarry Smith idx = sub_b->j; 4320170fe5c8SBarry Smith for (i=0; i<n; i++) { 4321170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4322170fe5c8SBarry Smith while (q-->0) { 432386214ceeSStefano Zampini c_q = c + clda*(*idx); 432486214ceeSStefano Zampini a_q = a + alda*i; 4325854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4326170fe5c8SBarry Smith idx++; 4327170fe5c8SBarry Smith b++; 4328170fe5c8SBarry Smith } 4329170fe5c8SBarry Smith } 4330170fe5c8SBarry Smith PetscFunctionReturn(0); 4331170fe5c8SBarry Smith } 4332170fe5c8SBarry Smith 43334222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C) 4334170fe5c8SBarry Smith { 4335170fe5c8SBarry Smith PetscErrorCode ierr; 4336d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 433786214ceeSStefano Zampini PetscBool cisdense; 4338170fe5c8SBarry Smith 4339170fe5c8SBarry Smith PetscFunctionBegin; 434060e0710aSBarry 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); 43414222ddf1SHong Zhang ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr); 43424222ddf1SHong Zhang ierr = MatSetBlockSizesFromMats(C,A,B);CHKERRQ(ierr); 434386214ceeSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr); 434486214ceeSStefano Zampini if (!cisdense) { 434586214ceeSStefano Zampini ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); 434686214ceeSStefano Zampini } 434786214ceeSStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 4348d73949e8SHong Zhang 43494222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 4350170fe5c8SBarry Smith PetscFunctionReturn(0); 4351170fe5c8SBarry Smith } 4352170fe5c8SBarry Smith 4353170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 43540bad9183SKris Buschelman /*MC 4355fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 43560bad9183SKris Buschelman based on compressed sparse row format. 43570bad9183SKris Buschelman 43580bad9183SKris Buschelman Options Database Keys: 43590bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 43600bad9183SKris Buschelman 43610bad9183SKris Buschelman Level: beginner 43620bad9183SKris Buschelman 43630cd7f59aSBarry Smith Notes: 43640cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 43650cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 43660cd7f59aSBarry Smith in the matrix 43670cd7f59aSBarry Smith 43680cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 43690cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 43700cd7f59aSBarry Smith 43710cd7f59aSBarry Smith Developer Notes: 43720cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 43730cd7f59aSBarry Smith 4374f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 43750bad9183SKris Buschelman M*/ 43760bad9183SKris Buschelman 4377ccd284c7SBarry Smith /*MC 4378ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4379ccd284c7SBarry Smith 4380ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4381ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 43820cd7f59aSBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation() is supported 4383ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4384ccd284c7SBarry Smith the above preallocation routines for simplicity. 4385ccd284c7SBarry Smith 4386ccd284c7SBarry Smith Options Database Keys: 4387ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4388ccd284c7SBarry Smith 438995452b02SPatrick Sanan Developer Notes: 4390ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4391ccd284c7SBarry Smith enough exist. 4392ccd284c7SBarry Smith 4393ccd284c7SBarry Smith Level: beginner 4394ccd284c7SBarry Smith 4395ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4396ccd284c7SBarry Smith M*/ 4397ccd284c7SBarry Smith 4398ccd284c7SBarry Smith /*MC 4399ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4400ccd284c7SBarry Smith 4401ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4402ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4403ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4404ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4405ccd284c7SBarry Smith the above preallocation routines for simplicity. 4406ccd284c7SBarry Smith 4407ccd284c7SBarry Smith Options Database Keys: 4408ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4409ccd284c7SBarry Smith 4410ccd284c7SBarry Smith Level: beginner 4411ccd284c7SBarry Smith 4412ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4413ccd284c7SBarry Smith M*/ 4414ccd284c7SBarry Smith 44157906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 44167906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 44177906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 44187906f579SHong Zhang #endif 4419d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4420d24d4204SJose E. Roman PETSC_INTERN PetscErrorCode MatConvert_AIJ_ScaLAPACK(Mat,MatType,MatReuse,Mat*); 4421d24d4204SJose E. Roman #endif 44227906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 44237906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 44247906f579SHong Zhang #endif 44257906f579SHong Zhang 4426d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4427c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 44284222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat); 44297906f579SHong Zhang 44308c778c55SBarry Smith /*@C 44318f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 44328c778c55SBarry Smith 44338c778c55SBarry Smith Not Collective 44348c778c55SBarry Smith 44358c778c55SBarry Smith Input Parameter: 4436579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 44378c778c55SBarry Smith 44388c778c55SBarry Smith Output Parameter: 44398c778c55SBarry Smith . array - pointer to the data 44408c778c55SBarry Smith 44418c778c55SBarry Smith Level: intermediate 44428c778c55SBarry Smith 4443774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 44448c778c55SBarry Smith @*/ 44458c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 44468c778c55SBarry Smith { 44478c778c55SBarry Smith PetscErrorCode ierr; 44488c778c55SBarry Smith 44498c778c55SBarry Smith PetscFunctionBegin; 44508c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 44512e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 44522e5835c6SStefano Zampini if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 44532e5835c6SStefano Zampini #endif 44548c778c55SBarry Smith PetscFunctionReturn(0); 44558c778c55SBarry Smith } 44568c778c55SBarry Smith 445721e72a00SBarry Smith /*@C 44588f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 44598f1ea47aSStefano Zampini 44608f1ea47aSStefano Zampini Not Collective 44618f1ea47aSStefano Zampini 44628f1ea47aSStefano Zampini Input Parameter: 44638f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44648f1ea47aSStefano Zampini 44658f1ea47aSStefano Zampini Output Parameter: 44668f1ea47aSStefano Zampini . array - pointer to the data 44678f1ea47aSStefano Zampini 44688f1ea47aSStefano Zampini Level: intermediate 44698f1ea47aSStefano Zampini 44708f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 44718f1ea47aSStefano Zampini @*/ 44728f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 44738f1ea47aSStefano Zampini { 44748c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4475c70f7ee4SJunchao Zhang PetscOffloadMask oval; 44768f1ea47aSStefano Zampini #endif 44778f1ea47aSStefano Zampini PetscErrorCode ierr; 44788f1ea47aSStefano Zampini 44798f1ea47aSStefano Zampini PetscFunctionBegin; 44808c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4481c70f7ee4SJunchao Zhang oval = A->offloadmask; 44828f1ea47aSStefano Zampini #endif 44838f1ea47aSStefano Zampini ierr = MatSeqAIJGetArray(A,(PetscScalar**)array);CHKERRQ(ierr); 44848c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4485c70f7ee4SJunchao Zhang if (oval == PETSC_OFFLOAD_GPU || oval == PETSC_OFFLOAD_BOTH) A->offloadmask = PETSC_OFFLOAD_BOTH; 44868f1ea47aSStefano Zampini #endif 44878f1ea47aSStefano Zampini PetscFunctionReturn(0); 44888f1ea47aSStefano Zampini } 44898f1ea47aSStefano Zampini 44908f1ea47aSStefano Zampini /*@C 44918f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 44928f1ea47aSStefano Zampini 44938f1ea47aSStefano Zampini Not Collective 44948f1ea47aSStefano Zampini 44958f1ea47aSStefano Zampini Input Parameter: 44968f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44978f1ea47aSStefano Zampini 44988f1ea47aSStefano Zampini Output Parameter: 44998f1ea47aSStefano Zampini . array - pointer to the data 45008f1ea47aSStefano Zampini 45018f1ea47aSStefano Zampini Level: intermediate 45028f1ea47aSStefano Zampini 45038f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 45048f1ea47aSStefano Zampini @*/ 45058f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 45068f1ea47aSStefano Zampini { 45078c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4508c70f7ee4SJunchao Zhang PetscOffloadMask oval; 45098f1ea47aSStefano Zampini #endif 45108f1ea47aSStefano Zampini PetscErrorCode ierr; 45118f1ea47aSStefano Zampini 45128f1ea47aSStefano Zampini PetscFunctionBegin; 45138c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4514c70f7ee4SJunchao Zhang oval = A->offloadmask; 45158f1ea47aSStefano Zampini #endif 45168f1ea47aSStefano Zampini ierr = MatSeqAIJRestoreArray(A,(PetscScalar**)array);CHKERRQ(ierr); 45178c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4518c70f7ee4SJunchao Zhang A->offloadmask = oval; 45198f1ea47aSStefano Zampini #endif 45208f1ea47aSStefano Zampini PetscFunctionReturn(0); 45218f1ea47aSStefano Zampini } 45228f1ea47aSStefano Zampini 45238f1ea47aSStefano Zampini /*@C 452421e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 452521e72a00SBarry Smith 452621e72a00SBarry Smith Not Collective 452721e72a00SBarry Smith 452821e72a00SBarry Smith Input Parameter: 4529579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 453021e72a00SBarry Smith 453121e72a00SBarry Smith Output Parameter: 453221e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 453321e72a00SBarry Smith 453421e72a00SBarry Smith Level: intermediate 453521e72a00SBarry Smith 453621e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 453721e72a00SBarry Smith @*/ 453821e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 453921e72a00SBarry Smith { 454021e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 454121e72a00SBarry Smith 454221e72a00SBarry Smith PetscFunctionBegin; 454321e72a00SBarry Smith *nz = aij->rmax; 454421e72a00SBarry Smith PetscFunctionReturn(0); 454521e72a00SBarry Smith } 454621e72a00SBarry Smith 45478c778c55SBarry Smith /*@C 4548579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 45498c778c55SBarry Smith 45508c778c55SBarry Smith Not Collective 45518c778c55SBarry Smith 45528c778c55SBarry Smith Input Parameters: 4553a2b725a8SWilliam Gropp + mat - a MATSEQAIJ matrix 4554a2b725a8SWilliam Gropp - array - pointer to the data 45558c778c55SBarry Smith 45568c778c55SBarry Smith Level: intermediate 45578c778c55SBarry Smith 4558774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 45598c778c55SBarry Smith @*/ 45608c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 45618c778c55SBarry Smith { 45628c778c55SBarry Smith PetscErrorCode ierr; 45638c778c55SBarry Smith 45648c778c55SBarry Smith PetscFunctionBegin; 45658c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 45668c778c55SBarry Smith PetscFunctionReturn(0); 45678c778c55SBarry Smith } 45688c778c55SBarry Smith 456934b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 45700ce8acdeSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat); 457102fe1965SBarry Smith #endif 45723d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 45733d0639e7SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJKokkos(Mat); 45743d0639e7SStefano Zampini #endif 457502fe1965SBarry Smith 45768cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4577273d9f13SBarry Smith { 4578273d9f13SBarry Smith Mat_SeqAIJ *b; 4579dfbe8321SBarry Smith PetscErrorCode ierr; 458038baddfdSBarry Smith PetscMPIInt size; 4581273d9f13SBarry Smith 4582273d9f13SBarry Smith PetscFunctionBegin; 4583ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr); 4584e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4585273d9f13SBarry Smith 4586b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 45872205254eSKarl Rupp 4588b0a32e0cSBarry Smith B->data = (void*)b; 45892205254eSKarl Rupp 4590549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4591071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 45922205254eSKarl Rupp 4593f4259b30SLisandro Dalcin b->row = NULL; 4594f4259b30SLisandro Dalcin b->col = NULL; 4595f4259b30SLisandro Dalcin b->icol = NULL; 4596b810aeb4SBarry Smith b->reallocs = 0; 459736db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4598f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4599416022c9SBarry Smith b->nonew = 0; 4600f4259b30SLisandro Dalcin b->diag = NULL; 4601f4259b30SLisandro Dalcin b->solve_work = NULL; 4602f4259b30SLisandro Dalcin B->spptr = NULL; 4603f4259b30SLisandro Dalcin b->saved_values = NULL; 4604f4259b30SLisandro Dalcin b->idiag = NULL; 4605f4259b30SLisandro Dalcin b->mdiag = NULL; 4606f4259b30SLisandro Dalcin b->ssor_work = NULL; 460771f1c65dSBarry Smith b->omega = 1.0; 460871f1c65dSBarry Smith b->fshift = 0.0; 460971f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4610bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4611a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 461217ab2063SBarry Smith 461335d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4614bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4615bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 46168c778c55SBarry Smith 4617b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4618bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4619bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4620b3866ffcSBarry Smith #endif 462117f1a0eaSHong Zhang 4622bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4623bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4624bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4625bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4626bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4627bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 46284dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 46299779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 46304a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4631191b95cbSRichard Tran Mills #endif 463234b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 463302fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 46344222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 4635fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 463602fe1965SBarry Smith #endif 46373d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 46383d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijkokkos_C",MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr); 46393d0639e7SStefano Zampini #endif 4640bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4641af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4642af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4643af8000cdSHong Zhang #endif 4644d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4645d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_scalapack_C",MatConvert_AIJ_ScaLAPACK);CHKERRQ(ierr); 4646d24d4204SJose E. Roman #endif 464763c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 464863c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 46494222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ);CHKERRQ(ierr); 465063c07aadSStefano Zampini #endif 4651b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4652d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4653c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4654bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4655bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4656bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4657846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4658bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4659bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 46604222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ);CHKERRQ(ierr); 46614222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ);CHKERRQ(ierr); 46624222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 46634108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 466417667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 46654099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 46663a40ed3dSBarry Smith PetscFunctionReturn(0); 466717ab2063SBarry Smith } 466817ab2063SBarry Smith 4669b24902e0SBarry Smith /* 4670b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4671b24902e0SBarry Smith */ 4672ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 467317ab2063SBarry Smith { 46742a350339SBarry Smith Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data,*a = (Mat_SeqAIJ*)A->data; 46756849ba73SBarry Smith PetscErrorCode ierr; 4676071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 467717ab2063SBarry Smith 46783a40ed3dSBarry Smith PetscFunctionBegin; 4679ca133879SJose E. Roman if (!A->assembled && cpvalues!=MAT_DO_NOT_COPY_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot duplicate unassembled matrix"); 4680273d9f13SBarry Smith 4681d5f3da31SBarry Smith C->factortype = A->factortype; 4682f4259b30SLisandro Dalcin c->row = NULL; 4683f4259b30SLisandro Dalcin c->col = NULL; 4684f4259b30SLisandro Dalcin c->icol = NULL; 46856ad4291fSHong Zhang c->reallocs = 0; 468617ab2063SBarry Smith 46876ad4291fSHong Zhang C->assembled = PETSC_TRUE; 468817ab2063SBarry Smith 4689aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4690aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4691eec197d1SBarry Smith 4692071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4693071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4694071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4695071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 46963bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 469717ab2063SBarry Smith 469817ab2063SBarry Smith /* allocate the matrix space */ 4699f77e22a1SHong Zhang if (mallocmatspace) { 4700dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 47013bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 47022205254eSKarl Rupp 4703f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 47042205254eSKarl Rupp 4705580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 470617ab2063SBarry Smith if (m > 0) { 4707580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4708be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 47092e5835c6SStefano Zampini const PetscScalar *aa; 47102e5835c6SStefano Zampini 47112e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 47122e5835c6SStefano Zampini ierr = PetscArraycpy(c->a,aa,a->i[m]);CHKERRQ(ierr); 47132e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 4714be6bf707SBarry Smith } else { 4715580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 471617ab2063SBarry Smith } 471708480c60SBarry Smith } 4718f77e22a1SHong Zhang } 471917ab2063SBarry Smith 47206ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4721416022c9SBarry Smith c->roworiented = a->roworiented; 4722416022c9SBarry Smith c->nonew = a->nonew; 4723416022c9SBarry Smith if (a->diag) { 4724854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4725071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 47263bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4727071fcb05SBarry Smith } else c->diag = NULL; 47282205254eSKarl Rupp 4729f4259b30SLisandro Dalcin c->solve_work = NULL; 4730f4259b30SLisandro Dalcin c->saved_values = NULL; 4731f4259b30SLisandro Dalcin c->idiag = NULL; 4732f4259b30SLisandro Dalcin c->ssor_work = NULL; 4733a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4734e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4735e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 47366ad4291fSHong Zhang 4737893ad86cSHong Zhang c->rmax = a->rmax; 4738416022c9SBarry Smith c->nz = a->nz; 47398ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4740273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4741754ec7b1SSatish Balay 47426ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 47436ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4744cd6b891eSBarry Smith if (a->compressedrow.use) { 47456ad4291fSHong Zhang i = a->compressedrow.nrows; 4746dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4747580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4748580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 474927ea64f8SHong Zhang } else { 475027ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 47510298fd71SBarry Smith c->compressedrow.i = NULL; 47520298fd71SBarry Smith c->compressedrow.rindex = NULL; 47536ad4291fSHong Zhang } 4754ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4755e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 47564846f1f5SKris Buschelman 47572205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4758140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 47593a40ed3dSBarry Smith PetscFunctionReturn(0); 476017ab2063SBarry Smith } 476117ab2063SBarry Smith 4762b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4763b24902e0SBarry Smith { 4764b24902e0SBarry Smith PetscErrorCode ierr; 4765b24902e0SBarry Smith 4766b24902e0SBarry Smith PetscFunctionBegin; 4767ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 47684b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4769cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 477033d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4771cfd3f464SBarry Smith } 4772a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4773f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4774b24902e0SBarry Smith PetscFunctionReturn(0); 4775b24902e0SBarry Smith } 4776b24902e0SBarry Smith 4777112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4778fbdbba38SShri Abhyankar { 477952f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 478052f91c60SVaclav Hapla PetscErrorCode ierr; 478152f91c60SVaclav Hapla 478252f91c60SVaclav Hapla PetscFunctionBegin; 478352f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 478452f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4785c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4786c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 478752f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 478852f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 478952f91c60SVaclav Hapla if (isbinary) { 479052f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 479152f91c60SVaclav Hapla } else if (ishdf5) { 479252f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 479352f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 479452f91c60SVaclav Hapla #else 479552f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 479652f91c60SVaclav Hapla #endif 479752f91c60SVaclav Hapla } else { 479852f91c60SVaclav 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); 479952f91c60SVaclav Hapla } 480052f91c60SVaclav Hapla PetscFunctionReturn(0); 480152f91c60SVaclav Hapla } 480252f91c60SVaclav Hapla 48033ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer) 480452f91c60SVaclav Hapla { 48053ea6fe3dSLisandro Dalcin Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 4806fbdbba38SShri Abhyankar PetscErrorCode ierr; 48073ea6fe3dSLisandro Dalcin PetscInt header[4],*rowlens,M,N,nz,sum,rows,cols,i; 4808fbdbba38SShri Abhyankar 4809fbdbba38SShri Abhyankar PetscFunctionBegin; 48103ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4811bbead8a2SBarry Smith 48123ea6fe3dSLisandro Dalcin /* read in matrix header */ 48133ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 48143ea6fe3dSLisandro Dalcin if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 4815fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 48163ea6fe3dSLisandro Dalcin if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M); 48173ea6fe3dSLisandro Dalcin if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N); 4818bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 4819fbdbba38SShri Abhyankar 48203ea6fe3dSLisandro Dalcin /* set block sizes from the viewer's .info file */ 48213ea6fe3dSLisandro Dalcin ierr = MatLoad_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 48223ea6fe3dSLisandro Dalcin /* set local and global sizes if not set already */ 48233ea6fe3dSLisandro Dalcin if (mat->rmap->n < 0) mat->rmap->n = M; 48243ea6fe3dSLisandro Dalcin if (mat->cmap->n < 0) mat->cmap->n = N; 48253ea6fe3dSLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 48263ea6fe3dSLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 48273ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 48283ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 48293ea6fe3dSLisandro Dalcin 48303ea6fe3dSLisandro Dalcin /* check if the matrix sizes are correct */ 48313ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 48323ea6fe3dSLisandro 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); 48333ea6fe3dSLisandro Dalcin 4834fbdbba38SShri Abhyankar /* read in row lengths */ 48353ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(M,&rowlens);CHKERRQ(ierr); 48363ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT);CHKERRQ(ierr); 48373ea6fe3dSLisandro Dalcin /* check if sum(rowlens) is same as nz */ 48383ea6fe3dSLisandro Dalcin sum = 0; for (i=0; i<M; i++) sum += rowlens[i]; 48393ea6fe3dSLisandro 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); 48403ea6fe3dSLisandro Dalcin /* preallocate and check sizes */ 48413ea6fe3dSLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens);CHKERRQ(ierr); 48423ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 484360e0710aSBarry 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); 48443ea6fe3dSLisandro Dalcin /* store row lengths */ 48453ea6fe3dSLisandro Dalcin ierr = PetscArraycpy(a->ilen,rowlens,M);CHKERRQ(ierr); 48463ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 4847fbdbba38SShri Abhyankar 48483ea6fe3dSLisandro Dalcin /* fill in "i" row pointers */ 48493ea6fe3dSLisandro Dalcin a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i]; 48503ea6fe3dSLisandro Dalcin /* read in "j" column indices */ 48513ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 48523ea6fe3dSLisandro Dalcin /* read in "a" nonzero values */ 48533ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4854fbdbba38SShri Abhyankar 48553ea6fe3dSLisandro Dalcin ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 48563ea6fe3dSLisandro Dalcin ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4857fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4858fbdbba38SShri Abhyankar } 4859fbdbba38SShri Abhyankar 4860ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 48617264ac53SSatish Balay { 48627264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4863dfbe8321SBarry Smith PetscErrorCode ierr; 4864eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4865eeffb40dSHong Zhang PetscInt k; 4866eeffb40dSHong Zhang #endif 48677264ac53SSatish Balay 48683a40ed3dSBarry Smith PetscFunctionBegin; 4869bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4870d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4871ca44d042SBarry Smith *flg = PETSC_FALSE; 4872ca44d042SBarry Smith PetscFunctionReturn(0); 4873bcd2baecSBarry Smith } 48747264ac53SSatish Balay 48757264ac53SSatish Balay /* if the a->i are the same */ 4876580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4877abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 48787264ac53SSatish Balay 48797264ac53SSatish Balay /* if a->j are the same */ 4880580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 4881abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4882bcd2baecSBarry Smith 4883bcd2baecSBarry Smith /* if a->a are the same */ 4884eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4885eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4886eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4887eeffb40dSHong Zhang *flg = PETSC_FALSE; 48883a40ed3dSBarry Smith PetscFunctionReturn(0); 4889eeffb40dSHong Zhang } 4890eeffb40dSHong Zhang } 4891eeffb40dSHong Zhang #else 4892580bdb30SBarry Smith ierr = PetscArraycmp(a->a,b->a,a->nz,flg);CHKERRQ(ierr); 4893eeffb40dSHong Zhang #endif 4894eeffb40dSHong Zhang PetscFunctionReturn(0); 48957264ac53SSatish Balay } 489636db0b34SBarry Smith 489705869f15SSatish Balay /*@ 489836db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 489936db0b34SBarry Smith provided by the user. 490036db0b34SBarry Smith 4901d083f849SBarry Smith Collective 490236db0b34SBarry Smith 490336db0b34SBarry Smith Input Parameters: 490436db0b34SBarry Smith + comm - must be an MPI communicator of size 1 490536db0b34SBarry Smith . m - number of rows 490636db0b34SBarry Smith . n - number of columns 4907483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 490836db0b34SBarry Smith . j - column indices 490936db0b34SBarry Smith - a - matrix values 491036db0b34SBarry Smith 491136db0b34SBarry Smith Output Parameter: 491236db0b34SBarry Smith . mat - the matrix 491336db0b34SBarry Smith 491436db0b34SBarry Smith Level: intermediate 491536db0b34SBarry Smith 491636db0b34SBarry Smith Notes: 49170551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4918292fb18eSBarry Smith once the matrix is destroyed and not before 491936db0b34SBarry Smith 492036db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 492136db0b34SBarry Smith 4922bfeeae90SHong Zhang The i and j indices are 0 based 492336db0b34SBarry Smith 4924a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4925a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 49268eef79e4SBarry Smith as shown 4927a4552177SSatish Balay 49288eef79e4SBarry Smith $ 1 0 0 49298eef79e4SBarry Smith $ 2 0 3 49308eef79e4SBarry Smith $ 4 5 6 49318eef79e4SBarry Smith $ 49328eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 49338eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 49348eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4935a4552177SSatish Balay 493669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 493736db0b34SBarry Smith 493836db0b34SBarry Smith @*/ 4939c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 494036db0b34SBarry Smith { 4941dfbe8321SBarry Smith PetscErrorCode ierr; 4942cbcfb4deSHong Zhang PetscInt ii; 494336db0b34SBarry Smith Mat_SeqAIJ *aij; 4944cbcfb4deSHong Zhang PetscInt jj; 494536db0b34SBarry Smith 494636db0b34SBarry Smith PetscFunctionBegin; 494741096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4948f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4949f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4950a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4951ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4952f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,NULL);CHKERRQ(ierr); 4953ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4954071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 4955071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 4956ab93d7beSBarry Smith 495736db0b34SBarry Smith aij->i = i; 495836db0b34SBarry Smith aij->j = j; 495936db0b34SBarry Smith aij->a = a; 496036db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 496136db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4962e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4963e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 496436db0b34SBarry Smith 496536db0b34SBarry Smith for (ii=0; ii<m; ii++) { 496636db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 496776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 496860e0710aSBarry 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]); 49699985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4970a061629eSStefano 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); 4971a061629eSStefano 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); 49729985e31cSBarry Smith } 497336db0b34SBarry Smith } 497476bd3646SJed Brown } 497576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 497636db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 497760e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 497860e0710aSBarry 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]); 497936db0b34SBarry Smith } 498076bd3646SJed Brown } 498136db0b34SBarry Smith 4982b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4983b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 498436db0b34SBarry Smith PetscFunctionReturn(0); 498536db0b34SBarry Smith } 498680ef6e79SMatthew G Knepley /*@C 4987d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 49888a0b0e6bSVictor Minden provided by the user. 49898a0b0e6bSVictor Minden 4990d083f849SBarry Smith Collective 49918a0b0e6bSVictor Minden 49928a0b0e6bSVictor Minden Input Parameters: 49938a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 49948a0b0e6bSVictor Minden . m - number of rows 49958a0b0e6bSVictor Minden . n - number of columns 49968a0b0e6bSVictor Minden . i - row indices 49978a0b0e6bSVictor Minden . j - column indices 49981230e6d1SVictor Minden . a - matrix values 49991230e6d1SVictor Minden . nz - number of nonzeros 50001230e6d1SVictor Minden - idx - 0 or 1 based 50018a0b0e6bSVictor Minden 50028a0b0e6bSVictor Minden Output Parameter: 50038a0b0e6bSVictor Minden . mat - the matrix 50048a0b0e6bSVictor Minden 50058a0b0e6bSVictor Minden Level: intermediate 50068a0b0e6bSVictor Minden 50078a0b0e6bSVictor Minden Notes: 50088a0b0e6bSVictor Minden The i and j indices are 0 based 50098a0b0e6bSVictor Minden 50108a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 50118a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 50128a0b0e6bSVictor Minden as shown: 50138a0b0e6bSVictor Minden 50148a0b0e6bSVictor Minden 1 0 0 50158a0b0e6bSVictor Minden 2 0 3 50168a0b0e6bSVictor Minden 4 5 6 50178a0b0e6bSVictor Minden 50188a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 50198a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 50208a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 50218a0b0e6bSVictor Minden 502269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 50238a0b0e6bSVictor Minden 50248a0b0e6bSVictor Minden @*/ 5025c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 50268a0b0e6bSVictor Minden { 50278a0b0e6bSVictor Minden PetscErrorCode ierr; 5028d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 50298a0b0e6bSVictor Minden 50308a0b0e6bSVictor Minden PetscFunctionBegin; 50311795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 50321230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 5033c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 50341230e6d1SVictor Minden } 50358a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 50368a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 50378a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 50381230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 50391230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 50401230e6d1SVictor Minden if (idx) { 50411230e6d1SVictor Minden row = i[ii] - 1; 50421230e6d1SVictor Minden col = j[ii] - 1; 50431230e6d1SVictor Minden } else { 50441230e6d1SVictor Minden row = i[ii]; 50451230e6d1SVictor Minden col = j[ii]; 50468a0b0e6bSVictor Minden } 50471230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 50488a0b0e6bSVictor Minden } 50498a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 50508a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5051d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 50528a0b0e6bSVictor Minden PetscFunctionReturn(0); 50538a0b0e6bSVictor Minden } 505436db0b34SBarry Smith 5055acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 5056acf2f550SJed Brown { 5057acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 5058acf2f550SJed Brown PetscErrorCode ierr; 5059acf2f550SJed Brown 5060acf2f550SJed Brown PetscFunctionBegin; 5061acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 5062acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 50632205254eSKarl Rupp 5064acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 5065acf2f550SJed Brown PetscFunctionReturn(0); 5066acf2f550SJed Brown } 5067acf2f550SJed Brown 50689c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 50699c8f2541SHong Zhang { 50709c8f2541SHong Zhang PetscErrorCode ierr; 50718761c3d6SHong Zhang PetscMPIInt size; 50729c8f2541SHong Zhang 50739c8f2541SHong Zhang PetscFunctionBegin; 5074ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 50757bbdc51dSHong Zhang if (size == 1) { 50767bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 50777bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 50787bbdc51dSHong Zhang } else { 50798761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 50807bbdc51dSHong Zhang } 50818761c3d6SHong Zhang } else { 50829c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 50838761c3d6SHong Zhang } 50849c8f2541SHong Zhang PetscFunctionReturn(0); 50859c8f2541SHong Zhang } 50869c8f2541SHong Zhang 508781824310SBarry Smith /* 508853dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 508953dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 509053dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 509153dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 509253dd7562SDmitry Karpeev */ 509353dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 509453dd7562SDmitry Karpeev { 509553dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 509653dd7562SDmitry Karpeev PetscErrorCode ierr; 509753dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 509853dd7562SDmitry Karpeev PetscBool seqaij; 509953dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 510053dd7562SDmitry Karpeev PetscScalar v; 510153dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 510253dd7562SDmitry Karpeev 510353dd7562SDmitry Karpeev PetscFunctionBegin; 510453dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 510553dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 51064099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 510753dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 510853dd7562SDmitry Karpeev if (rowemb) { 510953dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 511053dd7562SDmitry 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); 511153dd7562SDmitry Karpeev } else { 51126c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 511353dd7562SDmitry Karpeev } 511453dd7562SDmitry Karpeev if (colemb) { 511553dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 511653dd7562SDmitry 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); 511753dd7562SDmitry Karpeev } else { 511853dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 511953dd7562SDmitry Karpeev } 512053dd7562SDmitry Karpeev 512153dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 512253dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 512353dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 512453dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 512553dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 512653dd7562SDmitry Karpeev } 512753dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 512853dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 512953dd7562SDmitry Karpeev } 513053dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 513153dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 513253dd7562SDmitry Karpeev } 513353dd7562SDmitry Karpeev count = 0; 513453dd7562SDmitry Karpeev rowindices = NULL; 513553dd7562SDmitry Karpeev colindices = NULL; 513653dd7562SDmitry Karpeev if (rowemb) { 513753dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 513853dd7562SDmitry Karpeev } 513953dd7562SDmitry Karpeev if (colemb) { 514053dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 514153dd7562SDmitry Karpeev } 514253dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 514353dd7562SDmitry Karpeev PetscInt row; 514453dd7562SDmitry Karpeev row = i; 514553dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 514653dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 514753dd7562SDmitry Karpeev PetscInt col; 514853dd7562SDmitry Karpeev col = Baij->j[count]; 514953dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 515053dd7562SDmitry Karpeev v = Baij->a[count]; 515153dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 515253dd7562SDmitry Karpeev ++count; 515353dd7562SDmitry Karpeev } 515453dd7562SDmitry Karpeev } 515553dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 515653dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 515753dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 515853dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 515953dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 516053dd7562SDmitry Karpeev PetscFunctionReturn(0); 516153dd7562SDmitry Karpeev } 516253dd7562SDmitry Karpeev 51634099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 51644099cc6bSBarry Smith 51654099cc6bSBarry Smith /*@C 51664099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 51674099cc6bSBarry Smith 51684099cc6bSBarry Smith Collective on Mat 51694099cc6bSBarry Smith 51704099cc6bSBarry Smith Input Parameters: 51714099cc6bSBarry Smith + mat - the matrix object 51724099cc6bSBarry Smith - matype - matrix type 51734099cc6bSBarry Smith 51744099cc6bSBarry Smith Options Database Key: 51754099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 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 /*@C 51984099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 51994099cc6bSBarry Smith 52004099cc6bSBarry Smith Not Collective 52014099cc6bSBarry Smith 52024099cc6bSBarry Smith Input Parameters: 52034099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 52044099cc6bSBarry Smith - function - routine to convert to subtype 52054099cc6bSBarry Smith 52064099cc6bSBarry Smith Notes: 52074099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 52084099cc6bSBarry Smith 52094099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 52104099cc6bSBarry Smith $ -mat_seqaij_type my_mat 52114099cc6bSBarry Smith 52124099cc6bSBarry Smith Level: advanced 52134099cc6bSBarry Smith 52144099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 52154099cc6bSBarry Smith 52164099cc6bSBarry Smith Level: advanced 52174099cc6bSBarry Smith @*/ 5218388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 52194099cc6bSBarry Smith { 52204099cc6bSBarry Smith PetscErrorCode ierr; 52214099cc6bSBarry Smith 52224099cc6bSBarry Smith PetscFunctionBegin; 52239cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 52244099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 52254099cc6bSBarry Smith PetscFunctionReturn(0); 52264099cc6bSBarry Smith } 52274099cc6bSBarry Smith 52284099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 52294099cc6bSBarry Smith 52304099cc6bSBarry Smith /*@C 52314099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 52324099cc6bSBarry Smith 52334099cc6bSBarry Smith Not Collective 52344099cc6bSBarry Smith 52354099cc6bSBarry Smith Level: advanced 52364099cc6bSBarry Smith 5237f719121fSJed Brown Developers Note: CUSPARSE does not yet support the MatConvert_SeqAIJ..() paradigm and thus cannot be registered here 52384099cc6bSBarry Smith 52394099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 52404099cc6bSBarry Smith @*/ 52414099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 52424099cc6bSBarry Smith { 52434099cc6bSBarry Smith PetscErrorCode ierr; 52444099cc6bSBarry Smith 52454099cc6bSBarry Smith PetscFunctionBegin; 52464099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 52474099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 52484099cc6bSBarry Smith 52494099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 52504099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 52514dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 52529779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 52536b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 5254485f9817SRichard Tran Mills #endif 52554099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 52564099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 52574099cc6bSBarry Smith #endif 52584099cc6bSBarry Smith PetscFunctionReturn(0); 52594099cc6bSBarry Smith } 526053dd7562SDmitry Karpeev 526153dd7562SDmitry Karpeev /* 526281824310SBarry Smith Special version for direct calls from Fortran 526381824310SBarry Smith */ 5264af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 526581824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 526681824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 526781824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 526881824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 526981824310SBarry Smith #endif 527081824310SBarry Smith 527181824310SBarry Smith /* Change these macros so can be used in void function */ 527281824310SBarry Smith #undef CHKERRQ 5273ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 527481824310SBarry Smith #undef SETERRQ2 5275e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 52764994cf47SJed Brown #undef SETERRQ3 52774994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 527881824310SBarry Smith 527919caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 528081824310SBarry Smith { 528181824310SBarry Smith Mat A = *AA; 528281824310SBarry Smith PetscInt m = *mm, n = *nn; 528381824310SBarry Smith InsertMode is = *isis; 528481824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 528581824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 528681824310SBarry Smith PetscInt *imax,*ai,*ailen; 528781824310SBarry Smith PetscErrorCode ierr; 528881824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 528954f21887SBarry Smith MatScalar *ap,value,*aa; 5290ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5291ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 529281824310SBarry Smith 529381824310SBarry Smith PetscFunctionBegin; 52944994cf47SJed Brown MatCheckPreallocated(A,1); 529581824310SBarry Smith imax = a->imax; 529681824310SBarry Smith ai = a->i; 529781824310SBarry Smith ailen = a->ilen; 529881824310SBarry Smith aj = a->j; 529981824310SBarry Smith aa = a->a; 530081824310SBarry Smith 530181824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 530281824310SBarry Smith row = im[k]; 530381824310SBarry Smith if (row < 0) continue; 5304cf9c20a2SJed Brown if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 530581824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 530681824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 530781824310SBarry Smith low = 0; 530881824310SBarry Smith high = nrow; 530981824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 531081824310SBarry Smith if (in[l] < 0) continue; 5311cf9c20a2SJed Brown if (PetscUnlikelyDebug(in[l] >= A->cmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 531281824310SBarry Smith col = in[l]; 53132205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 53142205254eSKarl Rupp else value = v[k + l*m]; 53152205254eSKarl Rupp 531681824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 531781824310SBarry Smith 53182205254eSKarl Rupp if (col <= lastcol) low = 0; 53192205254eSKarl Rupp else high = nrow; 532081824310SBarry Smith lastcol = col; 532181824310SBarry Smith while (high-low > 5) { 532281824310SBarry Smith t = (low+high)/2; 532381824310SBarry Smith if (rp[t] > col) high = t; 532481824310SBarry Smith else low = t; 532581824310SBarry Smith } 532681824310SBarry Smith for (i=low; i<high; i++) { 532781824310SBarry Smith if (rp[i] > col) break; 532881824310SBarry Smith if (rp[i] == col) { 532981824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 533081824310SBarry Smith else ap[i] = value; 533181824310SBarry Smith goto noinsert; 533281824310SBarry Smith } 533381824310SBarry Smith } 533481824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 533581824310SBarry Smith if (nonew == 1) goto noinsert; 5336ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5337fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 533881824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 533981824310SBarry Smith /* shift up all the later entries in this row */ 534081824310SBarry Smith for (ii=N; ii>=i; ii--) { 534181824310SBarry Smith rp[ii+1] = rp[ii]; 534281824310SBarry Smith ap[ii+1] = ap[ii]; 534381824310SBarry Smith } 534481824310SBarry Smith rp[i] = col; 534581824310SBarry Smith ap[i] = value; 5346e56f5c9eSBarry Smith A->nonzerostate++; 534781824310SBarry Smith noinsert:; 534881824310SBarry Smith low = i + 1; 534981824310SBarry Smith } 535081824310SBarry Smith ailen[row] = nrow; 535181824310SBarry Smith } 535281824310SBarry Smith PetscFunctionReturnVoid(); 535381824310SBarry Smith } 5354