1b377110cSBarry Smith 2d5d45c9bSBarry Smith /* 33369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 4d5d45c9bSBarry Smith matrix storage format. 5d5d45c9bSBarry Smith */ 63369ce9aSBarry Smith 77c4f633dSBarry Smith 8c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 9c6db04a5SJed Brown #include <petscblaslapack.h> 10c6db04a5SJed Brown #include <petscbt.h> 11af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h> 120716a85fSBarry Smith 134099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetTypeFromOptions(Mat A) 144099cc6bSBarry Smith { 154099cc6bSBarry Smith PetscErrorCode ierr; 164099cc6bSBarry Smith PetscBool flg; 174099cc6bSBarry Smith char type[256]; 184099cc6bSBarry Smith 194099cc6bSBarry Smith PetscFunctionBegin; 204099cc6bSBarry Smith ierr = PetscObjectOptionsBegin((PetscObject)A); 214099cc6bSBarry Smith ierr = PetscOptionsFList("-mat_seqaij_type","Matrix SeqAIJ type","MatSeqAIJSetType",MatSeqAIJList,"seqaij",type,256,&flg);CHKERRQ(ierr); 224099cc6bSBarry Smith if (flg) { 234099cc6bSBarry Smith ierr = MatSeqAIJSetType(A,type);CHKERRQ(ierr); 244099cc6bSBarry Smith } 254099cc6bSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 264099cc6bSBarry Smith PetscFunctionReturn(0); 274099cc6bSBarry Smith } 284099cc6bSBarry Smith 290716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms) 300716a85fSBarry Smith { 310716a85fSBarry Smith PetscErrorCode ierr; 320716a85fSBarry Smith PetscInt i,m,n; 330716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 340716a85fSBarry Smith 350716a85fSBarry Smith PetscFunctionBegin; 360716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 37580bdb30SBarry Smith ierr = PetscArrayzero(norms,n);CHKERRQ(ierr); 380716a85fSBarry Smith if (type == NORM_2) { 390716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 400716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 410716a85fSBarry Smith } 420716a85fSBarry Smith } else if (type == NORM_1) { 430716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 440716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]); 450716a85fSBarry Smith } 460716a85fSBarry Smith } else if (type == NORM_INFINITY) { 470716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 480716a85fSBarry Smith norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]); 490716a85fSBarry Smith } 500716a85fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType"); 510716a85fSBarry Smith 520716a85fSBarry Smith if (type == NORM_2) { 538f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 540716a85fSBarry Smith } 550716a85fSBarry Smith PetscFunctionReturn(0); 560716a85fSBarry Smith } 570716a85fSBarry Smith 583a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 593a062f41SBarry Smith { 603a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 613a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 623a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 633a062f41SBarry Smith PetscInt *rows; 643a062f41SBarry Smith PetscErrorCode ierr; 653a062f41SBarry Smith 663a062f41SBarry Smith PetscFunctionBegin; 673a062f41SBarry Smith for (i=0; i<m; i++) { 683a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 693a062f41SBarry Smith cnt++; 703a062f41SBarry Smith } 713a062f41SBarry Smith } 723a062f41SBarry Smith ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 733a062f41SBarry Smith cnt = 0; 743a062f41SBarry Smith for (i=0; i<m; i++) { 753a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 763a062f41SBarry Smith rows[cnt] = i; 773a062f41SBarry Smith cnt++; 783a062f41SBarry Smith } 793a062f41SBarry Smith } 803a062f41SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr); 813a062f41SBarry Smith PetscFunctionReturn(0); 823a062f41SBarry Smith } 833a062f41SBarry Smith 84f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 856ce1633cSBarry Smith { 866ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 876ce1633cSBarry Smith const MatScalar *aa = a->a; 886ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 89b2db7409Sstefano_zampini const PetscInt *ii = a->i,*jj = a->j,*diag; 906ce1633cSBarry Smith PetscInt *rows; 916ce1633cSBarry Smith PetscErrorCode ierr; 926ce1633cSBarry Smith 936ce1633cSBarry Smith PetscFunctionBegin; 946ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 956ce1633cSBarry Smith diag = a->diag; 966ce1633cSBarry Smith for (i=0; i<m; i++) { 97b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 986ce1633cSBarry Smith cnt++; 996ce1633cSBarry Smith } 1006ce1633cSBarry Smith } 101785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 1026ce1633cSBarry Smith cnt = 0; 1036ce1633cSBarry Smith for (i=0; i<m; i++) { 104b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1056ce1633cSBarry Smith rows[cnt++] = i; 1066ce1633cSBarry Smith } 1076ce1633cSBarry Smith } 108f1f41ecbSJed Brown *nrows = cnt; 109f1f41ecbSJed Brown *zrows = rows; 110f1f41ecbSJed Brown PetscFunctionReturn(0); 111f1f41ecbSJed Brown } 112f1f41ecbSJed Brown 113f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 114f1f41ecbSJed Brown { 115f1f41ecbSJed Brown PetscInt nrows,*rows; 116f1f41ecbSJed Brown PetscErrorCode ierr; 117f1f41ecbSJed Brown 118f1f41ecbSJed Brown PetscFunctionBegin; 1190298fd71SBarry Smith *zrows = NULL; 120f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 121ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1226ce1633cSBarry Smith PetscFunctionReturn(0); 1236ce1633cSBarry Smith } 1246ce1633cSBarry Smith 125b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 126b3a44c85SBarry Smith { 127b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 128b3a44c85SBarry Smith const MatScalar *aa; 129b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 130b3a44c85SBarry Smith const PetscInt *ii; 131b3a44c85SBarry Smith PetscInt n,i,j,*rows; 132b3a44c85SBarry Smith PetscErrorCode ierr; 133b3a44c85SBarry Smith 134b3a44c85SBarry Smith PetscFunctionBegin; 135b3a44c85SBarry Smith *keptrows = 0; 136b3a44c85SBarry Smith ii = a->i; 137b3a44c85SBarry Smith for (i=0; i<m; i++) { 138b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 139b3a44c85SBarry Smith if (!n) { 140b3a44c85SBarry Smith cnt++; 141b3a44c85SBarry Smith goto ok1; 142b3a44c85SBarry Smith } 143b3a44c85SBarry Smith aa = a->a + ii[i]; 144b3a44c85SBarry Smith for (j=0; j<n; j++) { 145b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 146b3a44c85SBarry Smith } 147b3a44c85SBarry Smith cnt++; 148b3a44c85SBarry Smith ok1:; 149b3a44c85SBarry Smith } 150b3a44c85SBarry Smith if (!cnt) PetscFunctionReturn(0); 151854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr); 152b3a44c85SBarry Smith cnt = 0; 153b3a44c85SBarry Smith for (i=0; i<m; i++) { 154b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 155b3a44c85SBarry Smith if (!n) continue; 156b3a44c85SBarry Smith aa = a->a + ii[i]; 157b3a44c85SBarry Smith for (j=0; j<n; j++) { 158b3a44c85SBarry Smith if (aa[j] != 0.0) { 159b3a44c85SBarry Smith rows[cnt++] = i; 160b3a44c85SBarry Smith break; 161b3a44c85SBarry Smith } 162b3a44c85SBarry Smith } 163b3a44c85SBarry Smith } 164b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 165b3a44c85SBarry Smith PetscFunctionReturn(0); 166b3a44c85SBarry Smith } 167b3a44c85SBarry Smith 1687087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 16979299369SBarry Smith { 17079299369SBarry Smith PetscErrorCode ierr; 17179299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 17299e65526SBarry Smith PetscInt i,m = Y->rmap->n; 17399e65526SBarry Smith const PetscInt *diag; 17454f21887SBarry Smith MatScalar *aa = aij->a; 17599e65526SBarry Smith const PetscScalar *v; 176ace3abfcSBarry Smith PetscBool missing; 17779299369SBarry Smith 17879299369SBarry Smith PetscFunctionBegin; 17909f38230SBarry Smith if (Y->assembled) { 1800298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 18109f38230SBarry Smith if (!missing) { 18279299369SBarry Smith diag = aij->diag; 18399e65526SBarry Smith ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr); 18479299369SBarry Smith if (is == INSERT_VALUES) { 18579299369SBarry Smith for (i=0; i<m; i++) { 18679299369SBarry Smith aa[diag[i]] = v[i]; 18779299369SBarry Smith } 18879299369SBarry Smith } else { 18979299369SBarry Smith for (i=0; i<m; i++) { 19079299369SBarry Smith aa[diag[i]] += v[i]; 19179299369SBarry Smith } 19279299369SBarry Smith } 19399e65526SBarry Smith ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr); 19479299369SBarry Smith PetscFunctionReturn(0); 19579299369SBarry Smith } 196acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 19709f38230SBarry Smith } 19809f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 19909f38230SBarry Smith PetscFunctionReturn(0); 20009f38230SBarry Smith } 20179299369SBarry Smith 2021a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 20317ab2063SBarry Smith { 204416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 205dfbe8321SBarry Smith PetscErrorCode ierr; 20697f1f81fSBarry Smith PetscInt i,ishift; 20717ab2063SBarry Smith 2083a40ed3dSBarry Smith PetscFunctionBegin; 209d0f46423SBarry Smith *m = A->rmap->n; 2103a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 211bfeeae90SHong Zhang ishift = 0; 21253e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 2132462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 214bfeeae90SHong Zhang } else if (oshift == 1) { 2151a83f524SJed Brown PetscInt *tia; 216d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2173b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 218854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr); 2191a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2201a83f524SJed Brown *ia = tia; 221ecc77c7aSBarry Smith if (ja) { 2221a83f524SJed Brown PetscInt *tja; 223854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr); 2241a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2251a83f524SJed Brown *ja = tja; 226ecc77c7aSBarry Smith } 2276945ee14SBarry Smith } else { 228ecc77c7aSBarry Smith *ia = a->i; 229ecc77c7aSBarry Smith if (ja) *ja = a->j; 230a2ce50c7SBarry Smith } 2313a40ed3dSBarry Smith PetscFunctionReturn(0); 232a2744918SBarry Smith } 233a2744918SBarry Smith 2341a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2356945ee14SBarry Smith { 236dfbe8321SBarry Smith PetscErrorCode ierr; 2376945ee14SBarry Smith 2383a40ed3dSBarry Smith PetscFunctionBegin; 2393a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 240bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 241606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 242ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 243bcd2baecSBarry Smith } 2443a40ed3dSBarry Smith PetscFunctionReturn(0); 24517ab2063SBarry Smith } 24617ab2063SBarry Smith 2471a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2483b2fbd54SBarry Smith { 2493b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 250dfbe8321SBarry Smith PetscErrorCode ierr; 251d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 25297f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2533b2fbd54SBarry Smith 2543a40ed3dSBarry Smith PetscFunctionBegin; 255899cda47SBarry Smith *nn = n; 2563a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2573b2fbd54SBarry Smith if (symmetric) { 2582462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2593b2fbd54SBarry Smith } else { 260b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 261854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 262b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 2633b2fbd54SBarry Smith jj = a->j; 2643b2fbd54SBarry Smith for (i=0; i<nz; i++) { 265bfeeae90SHong Zhang collengths[jj[i]]++; 2663b2fbd54SBarry Smith } 2673b2fbd54SBarry Smith cia[0] = oshift; 2683b2fbd54SBarry Smith for (i=0; i<n; i++) { 2693b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2703b2fbd54SBarry Smith } 271580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 2723b2fbd54SBarry Smith jj = a->j; 273a93ec695SBarry Smith for (row=0; row<m; row++) { 274a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 275a93ec695SBarry Smith for (i=0; i<mr; i++) { 276bfeeae90SHong Zhang col = *jj++; 2772205254eSKarl Rupp 2783b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2793b2fbd54SBarry Smith } 2803b2fbd54SBarry Smith } 281606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2823b2fbd54SBarry Smith *ia = cia; *ja = cja; 2833b2fbd54SBarry Smith } 2843a40ed3dSBarry Smith PetscFunctionReturn(0); 2853b2fbd54SBarry Smith } 2863b2fbd54SBarry Smith 2871a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2883b2fbd54SBarry Smith { 289dfbe8321SBarry Smith PetscErrorCode ierr; 290606d414cSSatish Balay 2913a40ed3dSBarry Smith PetscFunctionBegin; 2923a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2933b2fbd54SBarry Smith 294606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 295606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 2963a40ed3dSBarry Smith PetscFunctionReturn(0); 2973b2fbd54SBarry Smith } 2983b2fbd54SBarry Smith 2997cee066cSHong Zhang /* 3007cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 3017cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 302040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 3037cee066cSHong Zhang */ 3047cee066cSHong 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) 3057cee066cSHong Zhang { 3067cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3077cee066cSHong Zhang PetscErrorCode ierr; 3087cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 309071fcb05SBarry Smith PetscInt nz = a->i[m],row,mr,col,tmp; 3107cee066cSHong Zhang PetscInt *cspidx; 311071fcb05SBarry Smith const PetscInt *jj; 3127cee066cSHong Zhang 3137cee066cSHong Zhang PetscFunctionBegin; 3147cee066cSHong Zhang *nn = n; 3157cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 316625f6d37SHong Zhang 317b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 318854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 319b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 320b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cspidx);CHKERRQ(ierr); 3217cee066cSHong Zhang jj = a->j; 3227cee066cSHong Zhang for (i=0; i<nz; i++) { 3237cee066cSHong Zhang collengths[jj[i]]++; 3247cee066cSHong Zhang } 3257cee066cSHong Zhang cia[0] = oshift; 3267cee066cSHong Zhang for (i=0; i<n; i++) { 3277cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3287cee066cSHong Zhang } 329580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 3307cee066cSHong Zhang jj = a->j; 3317cee066cSHong Zhang for (row=0; row<m; row++) { 3327cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3337cee066cSHong Zhang for (i=0; i<mr; i++) { 3347cee066cSHong Zhang col = *jj++; 335071fcb05SBarry Smith tmp = cia[col] + collengths[col]++ - oshift; 336071fcb05SBarry Smith cspidx[tmp] = a->i[row] + i; /* index of a->j */ 337071fcb05SBarry Smith cja[tmp] = row + oshift; 3387cee066cSHong Zhang } 3397cee066cSHong Zhang } 3407cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 341071fcb05SBarry Smith *ia = cia; 342071fcb05SBarry Smith *ja = cja; 3437cee066cSHong Zhang *spidx = cspidx; 3447cee066cSHong Zhang PetscFunctionReturn(0); 3457cee066cSHong Zhang } 3467cee066cSHong Zhang 3477cee066cSHong 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) 3487cee066cSHong Zhang { 3497cee066cSHong Zhang PetscErrorCode ierr; 3507cee066cSHong Zhang 3517cee066cSHong Zhang PetscFunctionBegin; 3525243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3537cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3547cee066cSHong Zhang PetscFunctionReturn(0); 3557cee066cSHong Zhang } 3567cee066cSHong Zhang 35787d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 35887d4246cSBarry Smith { 35987d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 36087d4246cSBarry Smith PetscInt *ai = a->i; 36187d4246cSBarry Smith PetscErrorCode ierr; 36287d4246cSBarry Smith 36387d4246cSBarry Smith PetscFunctionBegin; 364580bdb30SBarry Smith ierr = PetscArraycpy(a->a+ai[row],v,ai[row+1]-ai[row]);CHKERRQ(ierr); 365e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 366*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && ai[row+1]-ai[row]) A->offloadmask = PETSC_OFFLOAD_CPU; 367e2cf4d64SStefano Zampini #endif 36887d4246cSBarry Smith PetscFunctionReturn(0); 36987d4246cSBarry Smith } 37087d4246cSBarry Smith 371bd04181cSBarry Smith /* 372bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 373bd04181cSBarry Smith 374bd04181cSBarry Smith - a single row of values is set with each call 375bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 376bd04181cSBarry Smith - the values are always added to the matrix, not set 377bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 378bd04181cSBarry Smith 3791f763a69SBarry Smith This does NOT assume the global column indices are sorted 380bd04181cSBarry Smith 3811f763a69SBarry Smith */ 382bd04181cSBarry Smith 383af0996ceSBarry Smith #include <petsc/private/isimpl.h> 384189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 385189e4007SBarry Smith { 386189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3871f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 3881f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 3891f763a69SBarry Smith PetscInt lastcol = -1; 390189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 391189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 392189e4007SBarry Smith 393f38dd0b8SBarry Smith row = ridx[im[0]]; 3941f763a69SBarry Smith rp = aj + ai[row]; 3951f763a69SBarry Smith ap = aa + ai[row]; 3961f763a69SBarry Smith nrow = ailen[row]; 397189e4007SBarry Smith low = 0; 398189e4007SBarry Smith high = nrow; 399189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 400189e4007SBarry Smith col = cidx[in[l]]; 401f38dd0b8SBarry Smith value = v[l]; 402189e4007SBarry Smith 403189e4007SBarry Smith if (col <= lastcol) low = 0; 404189e4007SBarry Smith else high = nrow; 405189e4007SBarry Smith lastcol = col; 406189e4007SBarry Smith while (high-low > 5) { 407189e4007SBarry Smith t = (low+high)/2; 408189e4007SBarry Smith if (rp[t] > col) high = t; 409189e4007SBarry Smith else low = t; 410189e4007SBarry Smith } 411189e4007SBarry Smith for (i=low; i<high; i++) { 412189e4007SBarry Smith if (rp[i] == col) { 4131f763a69SBarry Smith ap[i] += value; 414189e4007SBarry Smith low = i + 1; 4151f763a69SBarry Smith break; 416189e4007SBarry Smith } 417189e4007SBarry Smith } 418189e4007SBarry Smith } 419e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 420*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 421e2cf4d64SStefano Zampini #endif 422f38dd0b8SBarry Smith return 0; 423189e4007SBarry Smith } 424189e4007SBarry Smith 42597f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 42617ab2063SBarry Smith { 427416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 428e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 42997f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 4306849ba73SBarry Smith PetscErrorCode ierr; 431e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 432d8cdefa3SHong Zhang MatScalar *ap=NULL,value=0.0,*aa = a->a; 433ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 434ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 435e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 436e2cf4d64SStefano Zampini PetscBool inserted = PETSC_FALSE; 437e2cf4d64SStefano Zampini #endif 43817ab2063SBarry Smith 4393a40ed3dSBarry Smith PetscFunctionBegin; 44017ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 441416022c9SBarry Smith row = im[k]; 4425ef9f2a5SBarry Smith if (row < 0) continue; 4432515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 444e32f2f54SBarry 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); 4453b2fbd54SBarry Smith #endif 446720833daSHong Zhang rp = aj + ai[row]; 447876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 44817ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 449416022c9SBarry Smith low = 0; 450c71e6ed7SBarry Smith high = nrow; 45117ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4525ef9f2a5SBarry Smith if (in[l] < 0) continue; 4532515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 454e32f2f54SBarry 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); 4553b2fbd54SBarry Smith #endif 456bfeeae90SHong Zhang col = in[l]; 457071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 458071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 45936db0b34SBarry Smith 4602205254eSKarl Rupp if (col <= lastcol) low = 0; 4612205254eSKarl Rupp else high = nrow; 462e2ee6c50SBarry Smith lastcol = col; 463416022c9SBarry Smith while (high-low > 5) { 464416022c9SBarry Smith t = (low+high)/2; 465416022c9SBarry Smith if (rp[t] > col) high = t; 466416022c9SBarry Smith else low = t; 46717ab2063SBarry Smith } 468416022c9SBarry Smith for (i=low; i<high; i++) { 46917ab2063SBarry Smith if (rp[i] > col) break; 47017ab2063SBarry Smith if (rp[i] == col) { 471876c6284SHong Zhang if (!A->structure_only) { 4720c0d7e18SFande Kong if (is == ADD_VALUES) { 4730c0d7e18SFande Kong ap[i] += value; 4740c0d7e18SFande Kong (void)PetscLogFlops(1.0); 4750c0d7e18SFande Kong } 47617ab2063SBarry Smith else ap[i] = value; 477e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 478e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 479e2cf4d64SStefano Zampini #endif 480720833daSHong Zhang } 481e44c0bd4SBarry Smith low = i + 1; 48217ab2063SBarry Smith goto noinsert; 48317ab2063SBarry Smith } 48417ab2063SBarry Smith } 485dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 486c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 487e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 488720833daSHong Zhang if (A->structure_only) { 489876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 490720833daSHong Zhang } else { 491fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 492720833daSHong Zhang } 493c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 494416022c9SBarry Smith /* shift up all the later entries in this row */ 495580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 49617ab2063SBarry Smith rp[i] = col; 497580bdb30SBarry Smith if (!A->structure_only){ 498580bdb30SBarry Smith ierr = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr); 499580bdb30SBarry Smith ap[i] = value; 500580bdb30SBarry Smith } 501416022c9SBarry Smith low = i + 1; 502e56f5c9eSBarry Smith A->nonzerostate++; 503e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 504e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 505e2cf4d64SStefano Zampini #endif 506e44c0bd4SBarry Smith noinsert:; 50717ab2063SBarry Smith } 50817ab2063SBarry Smith ailen[row] = nrow; 50917ab2063SBarry Smith } 510e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 511*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && inserted) A->offloadmask = PETSC_OFFLOAD_CPU; 512e2cf4d64SStefano Zampini #endif 5133a40ed3dSBarry Smith PetscFunctionReturn(0); 51417ab2063SBarry Smith } 51517ab2063SBarry Smith 516071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 517071fcb05SBarry Smith { 518071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 519071fcb05SBarry Smith PetscInt *rp,k,row; 520071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 521071fcb05SBarry Smith PetscErrorCode ierr; 522071fcb05SBarry Smith PetscInt *aj = a->j; 523071fcb05SBarry Smith MatScalar *aa = a->a,*ap; 524071fcb05SBarry Smith 525071fcb05SBarry Smith PetscFunctionBegin; 526071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 527071fcb05SBarry Smith row = im[k]; 528071fcb05SBarry Smith rp = aj + ai[row]; 529071fcb05SBarry Smith ap = aa + ai[row]; 530071fcb05SBarry Smith if (!A->was_assembled) { 531071fcb05SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 532071fcb05SBarry Smith } 533071fcb05SBarry Smith if (!A->structure_only) { 534071fcb05SBarry Smith if (v) { 535071fcb05SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 536071fcb05SBarry Smith v += n; 537071fcb05SBarry Smith } else { 538071fcb05SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 539071fcb05SBarry Smith } 540071fcb05SBarry Smith } 541071fcb05SBarry Smith ailen[row] = n; 542071fcb05SBarry Smith a->nz += n; 543071fcb05SBarry Smith } 544e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 545*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 546e2cf4d64SStefano Zampini #endif 547071fcb05SBarry Smith PetscFunctionReturn(0); 548071fcb05SBarry Smith } 549071fcb05SBarry Smith 55081824310SBarry Smith 551a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 5527eb43aa7SLois Curfman McInnes { 5537eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 55497f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 55597f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 55654f21887SBarry Smith MatScalar *ap,*aa = a->a; 5577eb43aa7SLois Curfman McInnes 5583a40ed3dSBarry Smith PetscFunctionBegin; 5597eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 5607eb43aa7SLois Curfman McInnes row = im[k]; 561e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 562e32f2f54SBarry 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); 563bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 5647eb43aa7SLois Curfman McInnes nrow = ailen[row]; 5657eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 566e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 567e32f2f54SBarry 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); 568bfeeae90SHong Zhang col = in[l]; 5697eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 5707eb43aa7SLois Curfman McInnes while (high-low > 5) { 5717eb43aa7SLois Curfman McInnes t = (low+high)/2; 5727eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 5737eb43aa7SLois Curfman McInnes else low = t; 5747eb43aa7SLois Curfman McInnes } 5757eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 5767eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 5777eb43aa7SLois Curfman McInnes if (rp[i] == col) { 578b49de8d1SLois Curfman McInnes *v++ = ap[i]; 5797eb43aa7SLois Curfman McInnes goto finished; 5807eb43aa7SLois Curfman McInnes } 5817eb43aa7SLois Curfman McInnes } 58297e567efSBarry Smith *v++ = 0.0; 5837eb43aa7SLois Curfman McInnes finished:; 5847eb43aa7SLois Curfman McInnes } 5857eb43aa7SLois Curfman McInnes } 5863a40ed3dSBarry Smith PetscFunctionReturn(0); 5877eb43aa7SLois Curfman McInnes } 5887eb43aa7SLois Curfman McInnes 58917ab2063SBarry Smith 590dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 59117ab2063SBarry Smith { 592416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 5936849ba73SBarry Smith PetscErrorCode ierr; 5946f69ff64SBarry Smith PetscInt i,*col_lens; 5956f69ff64SBarry Smith int fd; 596b37d52dbSMark F. Adams FILE *file; 59717ab2063SBarry Smith 5983a40ed3dSBarry Smith PetscFunctionBegin; 599b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 600854ce69bSBarry Smith ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr); 6012205254eSKarl Rupp 6020700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 603d0f46423SBarry Smith col_lens[1] = A->rmap->n; 604d0f46423SBarry Smith col_lens[2] = A->cmap->n; 605416022c9SBarry Smith col_lens[3] = a->nz; 606416022c9SBarry Smith 607416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 608d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 609416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 61017ab2063SBarry Smith } 611d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 612606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 613416022c9SBarry Smith 614416022c9SBarry Smith /* store column indices (zero start index) */ 6156f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 616416022c9SBarry Smith 617416022c9SBarry Smith /* store nonzero values */ 6186f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 619b37d52dbSMark F. Adams 620b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 621b37d52dbSMark F. Adams if (file) { 62233d57670SJed Brown fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs)); 623b37d52dbSMark F. Adams } 6243a40ed3dSBarry Smith PetscFunctionReturn(0); 62517ab2063SBarry Smith } 626416022c9SBarry Smith 6277dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 6287dc0baabSHong Zhang { 6297dc0baabSHong Zhang PetscErrorCode ierr; 6307dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 6317dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 6327dc0baabSHong Zhang 6337dc0baabSHong Zhang PetscFunctionBegin; 6347dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 6357dc0baabSHong Zhang for (i=0; i<m; i++) { 6367dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 6377dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 6387dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 6397dc0baabSHong Zhang } 6407dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 6417dc0baabSHong Zhang } 6427dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6437dc0baabSHong Zhang PetscFunctionReturn(0); 6447dc0baabSHong Zhang } 6457dc0baabSHong Zhang 64609573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 647cd155464SBarry Smith 648dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 649416022c9SBarry Smith { 650416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 651dfbe8321SBarry Smith PetscErrorCode ierr; 65260e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 653e060cb09SBarry Smith const char *name; 654f3ef73ceSBarry Smith PetscViewerFormat format; 65517ab2063SBarry Smith 6563a40ed3dSBarry Smith PetscFunctionBegin; 6577dc0baabSHong Zhang if (A->structure_only) { 6587dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 6597dc0baabSHong Zhang PetscFunctionReturn(0); 6607dc0baabSHong Zhang } 66143e49210SHong Zhang 662b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 66371c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 66497f1f81fSBarry Smith PetscInt nofinalvalue = 0; 66560e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 666c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 667d00d2cf4SBarry Smith nofinalvalue = 1; 668d00d2cf4SBarry Smith } 669d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 670d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 67177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 672fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 673fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 674fbfe6fa7SJed Brown #else 67577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 676fbfe6fa7SJed Brown #endif 677b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 67817ab2063SBarry Smith 67917ab2063SBarry Smith for (i=0; i<m; i++) { 68060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 681aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 682a9bf72d8SJed 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); 68317ab2063SBarry Smith #else 68460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 68517ab2063SBarry Smith #endif 68617ab2063SBarry Smith } 68717ab2063SBarry Smith } 688d00d2cf4SBarry Smith if (nofinalvalue) { 689c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 690c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 691c337ccceSJed Brown #else 692d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 693c337ccceSJed Brown #endif 694d00d2cf4SBarry Smith } 695317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 696fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 697d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6982950ac48SStefano Zampini } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 699cd155464SBarry Smith PetscFunctionReturn(0); 700fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 701d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 70244cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 70377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 70460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 705aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 70636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 70760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 70836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 70960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 71036db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 71160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 7126831982aSBarry Smith } 71344cd7ae7SLois Curfman McInnes #else 71460e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 71544cd7ae7SLois Curfman McInnes #endif 71644cd7ae7SLois Curfman McInnes } 717b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 71844cd7ae7SLois Curfman McInnes } 719d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 720fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 72197f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 722d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 723854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 724496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 725496be53dSLois Curfman McInnes sptr[i] = nzd+1; 72660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 727496be53dSLois Curfman McInnes if (a->j[j] >= i) { 728aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 72936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 730496be53dSLois Curfman McInnes #else 731496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 732496be53dSLois Curfman McInnes #endif 733496be53dSLois Curfman McInnes } 734496be53dSLois Curfman McInnes } 735496be53dSLois Curfman McInnes } 7362e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 73777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 7382e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 7392205254eSKarl Rupp if (i+4<m) { 7402205254eSKarl 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); 7412205254eSKarl Rupp } else if (i+3<m) { 7422205254eSKarl 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); 7432205254eSKarl Rupp } else if (i+2<m) { 7442205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 7452205254eSKarl Rupp } else if (i+1<m) { 7462205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 7472205254eSKarl Rupp } else if (i<m) { 7482205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 7492205254eSKarl Rupp } else { 7502205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 7512205254eSKarl Rupp } 752496be53dSLois Curfman McInnes } 753b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 754606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 755496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 75660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 75777431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 758496be53dSLois Curfman McInnes } 759b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 760496be53dSLois Curfman McInnes } 761b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 762496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 76360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 764496be53dSLois Curfman McInnes if (a->j[j] >= i) { 765aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 76636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 76760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7686831982aSBarry Smith } 769496be53dSLois Curfman McInnes #else 77060e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 771496be53dSLois Curfman McInnes #endif 772496be53dSLois Curfman McInnes } 773496be53dSLois Curfman McInnes } 774b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 775496be53dSLois Curfman McInnes } 776d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 777fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 77897f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 77987828ca2SBarry Smith PetscScalar value; 78068f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 78168f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 78268f1ed48SBarry Smith 78368f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 78468f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 78568f1ed48SBarry Smith realonly = PETSC_FALSE; 78668f1ed48SBarry Smith break; 78768f1ed48SBarry Smith } 78868f1ed48SBarry Smith } 78968f1ed48SBarry Smith #endif 79002594712SBarry Smith 791d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 79202594712SBarry Smith for (i=0; i<m; i++) { 79302594712SBarry Smith jcnt = 0; 794d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 795e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 79602594712SBarry Smith value = a->a[cnt++]; 797e24b481bSBarry Smith jcnt++; 79802594712SBarry Smith } else { 79902594712SBarry Smith value = 0.0; 80002594712SBarry Smith } 801aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 80268f1ed48SBarry Smith if (realonly) { 80360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 80468f1ed48SBarry Smith } else { 80560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 80668f1ed48SBarry Smith } 80702594712SBarry Smith #else 80860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 80902594712SBarry Smith #endif 81002594712SBarry Smith } 811b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 81202594712SBarry Smith } 813d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 8143c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 815150b93efSMatthew G. Knepley PetscInt fshift=1; 816d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 8173c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 81819303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 8193c215bfdSMatthew Knepley #else 82019303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 8213c215bfdSMatthew Knepley #endif 822d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 8233c215bfdSMatthew Knepley for (i=0; i<m; i++) { 82460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 8253c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 826a9a0e077SKarl 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); 8273c215bfdSMatthew Knepley #else 828150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 8293c215bfdSMatthew Knepley #endif 8303c215bfdSMatthew Knepley } 8313c215bfdSMatthew Knepley } 832d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 8333a40ed3dSBarry Smith } else { 834d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 835d5f3da31SBarry Smith if (A->factortype) { 83616cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 83716cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 83816cd7e1dSShri Abhyankar /* L part */ 83960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 84016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 84116cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 84260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 84316cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 8446712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 84516cd7e1dSShri Abhyankar } else { 84660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 84716cd7e1dSShri Abhyankar } 84816cd7e1dSShri Abhyankar #else 84960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 85016cd7e1dSShri Abhyankar #endif 85116cd7e1dSShri Abhyankar } 85216cd7e1dSShri Abhyankar /* diagonal */ 85316cd7e1dSShri Abhyankar j = a->diag[i]; 85416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 85516cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 85660e0710aSBarry 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); 85716cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 8586712e2f1SBarry 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); 85916cd7e1dSShri Abhyankar } else { 86060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 86116cd7e1dSShri Abhyankar } 86216cd7e1dSShri Abhyankar #else 86360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 86416cd7e1dSShri Abhyankar #endif 86516cd7e1dSShri Abhyankar 86616cd7e1dSShri Abhyankar /* U part */ 86760e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 86816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 86916cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 87060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 87116cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 87222ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 87316cd7e1dSShri Abhyankar } else { 87460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 87516cd7e1dSShri Abhyankar } 87616cd7e1dSShri Abhyankar #else 87760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 87816cd7e1dSShri Abhyankar #endif 87916cd7e1dSShri Abhyankar } 88016cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 88116cd7e1dSShri Abhyankar } 88216cd7e1dSShri Abhyankar } else { 88317ab2063SBarry Smith for (i=0; i<m; i++) { 88477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 88560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 886aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 88736db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 88860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 88936db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 89060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8913a40ed3dSBarry Smith } else { 89260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 89317ab2063SBarry Smith } 89417ab2063SBarry Smith #else 89560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 89617ab2063SBarry Smith #endif 89717ab2063SBarry Smith } 898b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 89917ab2063SBarry Smith } 90016cd7e1dSShri Abhyankar } 901d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 90217ab2063SBarry Smith } 903b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9043a40ed3dSBarry Smith PetscFunctionReturn(0); 905416022c9SBarry Smith } 906416022c9SBarry Smith 9079804daf3SBarry Smith #include <petscdraw.h> 908dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 909416022c9SBarry Smith { 910480ef9eaSBarry Smith Mat A = (Mat) Aa; 911416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 912dfbe8321SBarry Smith PetscErrorCode ierr; 913383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 914383922c3SLisandro Dalcin int color; 915b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 916b0a32e0cSBarry Smith PetscViewer viewer; 917f3ef73ceSBarry Smith PetscViewerFormat format; 918cddf8d76SBarry Smith 9193a40ed3dSBarry Smith PetscFunctionBegin; 920480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 921b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 922b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 923383922c3SLisandro Dalcin 924416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 9250513a670SBarry Smith 926fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 927383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 9280513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 929b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 930416022c9SBarry Smith for (i=0; i<m; i++) { 931cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 932bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 933bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 93436db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 935b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 936cddf8d76SBarry Smith } 937cddf8d76SBarry Smith } 938b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 939cddf8d76SBarry Smith for (i=0; i<m; i++) { 940cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 941bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 942bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 943cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 944b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 945cddf8d76SBarry Smith } 946cddf8d76SBarry Smith } 947b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 948cddf8d76SBarry Smith for (i=0; i<m; i++) { 949cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 950bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 951bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 95236db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 953b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 954416022c9SBarry Smith } 955416022c9SBarry Smith } 956383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 9570513a670SBarry Smith } else { 9580513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 9590513a670SBarry Smith /* first determine max of all nonzero values */ 960b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 961383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 962b0a32e0cSBarry Smith PetscDraw popup; 9630513a670SBarry Smith 9640513a670SBarry Smith for (i=0; i<nz; i++) { 9650513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 9660513a670SBarry Smith } 967383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 968b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 96945f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 970383922c3SLisandro Dalcin 971383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 9720513a670SBarry Smith for (i=0; i<m; i++) { 973383922c3SLisandro Dalcin y_l = m - i - 1.0; 974383922c3SLisandro Dalcin y_r = y_l + 1.0; 975bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 976383922c3SLisandro Dalcin x_l = a->j[j]; 977383922c3SLisandro Dalcin x_r = x_l + 1.0; 978b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 979b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 9800513a670SBarry Smith count++; 9810513a670SBarry Smith } 9820513a670SBarry Smith } 983383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 9840513a670SBarry Smith } 985480ef9eaSBarry Smith PetscFunctionReturn(0); 986480ef9eaSBarry Smith } 987cddf8d76SBarry Smith 9889804daf3SBarry Smith #include <petscdraw.h> 989dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 990480ef9eaSBarry Smith { 991dfbe8321SBarry Smith PetscErrorCode ierr; 992b0a32e0cSBarry Smith PetscDraw draw; 99336db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 994ace3abfcSBarry Smith PetscBool isnull; 995480ef9eaSBarry Smith 996480ef9eaSBarry Smith PetscFunctionBegin; 997b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 998b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 999480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1000480ef9eaSBarry Smith 1001d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1002480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1003b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1004832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1005b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 10060298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1007832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 10083a40ed3dSBarry Smith PetscFunctionReturn(0); 1009416022c9SBarry Smith } 1010416022c9SBarry Smith 1011dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1012416022c9SBarry Smith { 1013dfbe8321SBarry Smith PetscErrorCode ierr; 1014ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1015416022c9SBarry Smith 10163a40ed3dSBarry Smith PetscFunctionBegin; 1017251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1018251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1019251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1020c45a1595SBarry Smith if (iascii) { 10213a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 10220f5bd95cSBarry Smith } else if (isbinary) { 10233a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 10240f5bd95cSBarry Smith } else if (isdraw) { 10253a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 102611aeaf0aSBarry Smith } 10274108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 10283a40ed3dSBarry Smith PetscFunctionReturn(0); 102917ab2063SBarry Smith } 103019bcc07fSBarry Smith 1031dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 103217ab2063SBarry Smith { 1033416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10346849ba73SBarry Smith PetscErrorCode ierr; 1035580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1036d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 103754f21887SBarry Smith MatScalar *aa = a->a,*ap; 10383447b6efSHong Zhang PetscReal ratio = 0.6; 103917ab2063SBarry Smith 10403a40ed3dSBarry Smith PetscFunctionBegin; 10413a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1042071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1043071fcb05SBarry Smith if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) PetscFunctionReturn(0); 104417ab2063SBarry Smith 104543ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 104617ab2063SBarry Smith for (i=1; i<m; i++) { 1047416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 104817ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 104994a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 105017ab2063SBarry Smith if (fshift) { 1051bfeeae90SHong Zhang ip = aj + ai[i]; 1052bfeeae90SHong Zhang ap = aa + ai[i]; 105317ab2063SBarry Smith N = ailen[i]; 1054580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1055580bdb30SBarry Smith if (!A->structure_only) { 1056580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 105717ab2063SBarry Smith } 105817ab2063SBarry Smith } 105917ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 106017ab2063SBarry Smith } 106117ab2063SBarry Smith if (m) { 106217ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 106317ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 106417ab2063SBarry Smith } 10657b083b7cSBarry Smith 106617ab2063SBarry Smith /* reset ilen and imax for each row */ 10677b083b7cSBarry Smith a->nonzerorowcnt = 0; 1068396832f4SHong Zhang if (A->structure_only) { 1069071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1070071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1071396832f4SHong Zhang } else { /* !A->structure_only */ 107217ab2063SBarry Smith for (i=0; i<m; i++) { 107317ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 10747b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 107517ab2063SBarry Smith } 1076396832f4SHong Zhang } 1077bfeeae90SHong Zhang a->nz = ai[m]; 107865e19b50SBarry 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); 107917ab2063SBarry Smith 108009f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1081d0f46423SBarry 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); 1082ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1083ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 10842205254eSKarl Rupp 10858e58a170SBarry Smith A->info.mallocs += a->reallocs; 1086dd5f02e7SSatish Balay a->reallocs = 0; 10876712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 108836db0b34SBarry Smith a->rmax = rmax; 10894e220ebcSLois Curfman McInnes 1090396832f4SHong Zhang if (!A->structure_only) { 109111e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1092396832f4SHong Zhang } 10934108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 10943a40ed3dSBarry Smith PetscFunctionReturn(0); 109517ab2063SBarry Smith } 109617ab2063SBarry Smith 109799cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 109899cafbc1SBarry Smith { 109999cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 110099cafbc1SBarry Smith PetscInt i,nz = a->nz; 110154f21887SBarry Smith MatScalar *aa = a->a; 1102acf2f550SJed Brown PetscErrorCode ierr; 110399cafbc1SBarry Smith 110499cafbc1SBarry Smith PetscFunctionBegin; 110599cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1106acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1107e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1108*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1109e2cf4d64SStefano Zampini #endif 111099cafbc1SBarry Smith PetscFunctionReturn(0); 111199cafbc1SBarry Smith } 111299cafbc1SBarry Smith 111399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 111499cafbc1SBarry Smith { 111599cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 111699cafbc1SBarry Smith PetscInt i,nz = a->nz; 111754f21887SBarry Smith MatScalar *aa = a->a; 1118acf2f550SJed Brown PetscErrorCode ierr; 111999cafbc1SBarry Smith 112099cafbc1SBarry Smith PetscFunctionBegin; 112199cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1122acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1123e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1124*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1125e2cf4d64SStefano Zampini #endif 112699cafbc1SBarry Smith PetscFunctionReturn(0); 112799cafbc1SBarry Smith } 112899cafbc1SBarry Smith 1129dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 113017ab2063SBarry Smith { 1131416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1132dfbe8321SBarry Smith PetscErrorCode ierr; 11333a40ed3dSBarry Smith 11343a40ed3dSBarry Smith PetscFunctionBegin; 1135580bdb30SBarry Smith ierr = PetscArrayzero(a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 1136acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1137e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1138*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1139e2cf4d64SStefano Zampini #endif 11403a40ed3dSBarry Smith PetscFunctionReturn(0); 114117ab2063SBarry Smith } 1142416022c9SBarry Smith 1143dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 114417ab2063SBarry Smith { 1145416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1146dfbe8321SBarry Smith PetscErrorCode ierr; 1147d5d45c9bSBarry Smith 11483a40ed3dSBarry Smith PetscFunctionBegin; 1149aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1150d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 115117ab2063SBarry Smith #endif 1152e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 11536bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 11546bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 115505b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1156d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1157071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1158071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1159846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 116071f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 116105b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 11626bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 116305b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 11646bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 1165cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 11660b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1167a30b2313SHong Zhang 11684108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1169bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1170901853e0SKris Buschelman 1171dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1172bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1173bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1174bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1175bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1176bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1177bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1178af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1179af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1180af8000cdSHong Zhang #endif 118163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 118263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 11833dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 118463c07aadSStefano Zampini #endif 1185b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1186c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1187c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1188bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1189bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1190846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1191bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1192bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 119375d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatPtAP_is_seqaij_C",NULL);CHKERRQ(ierr); 11943a40ed3dSBarry Smith PetscFunctionReturn(0); 119517ab2063SBarry Smith } 119617ab2063SBarry Smith 1197ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 119817ab2063SBarry Smith { 1199416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12004846f1f5SKris Buschelman PetscErrorCode ierr; 12013a40ed3dSBarry Smith 12023a40ed3dSBarry Smith PetscFunctionBegin; 1203a65d3064SKris Buschelman switch (op) { 1204a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 12054e0d8c25SBarry Smith a->roworiented = flg; 1206a65d3064SKris Buschelman break; 1207a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1208a9817697SBarry Smith a->keepnonzeropattern = flg; 1209a65d3064SKris Buschelman break; 1210512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1211512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1212a65d3064SKris Buschelman break; 1213a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 12144e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1215a65d3064SKris Buschelman break; 1216a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 12174e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1218a65d3064SKris Buschelman break; 121928b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 122028b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 122128b2fa4aSMatthew Knepley break; 1222a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 12234e0d8c25SBarry Smith a->ignorezeroentries = flg; 12240df259c2SBarry Smith break; 12253d472b54SHong Zhang case MAT_SPD: 1226b1646e73SJed Brown case MAT_SYMMETRIC: 1227b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1228b1646e73SJed Brown case MAT_HERMITIAN: 1229b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1230957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 12315021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 12325021d80fSJed Brown break; 12334e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1234a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1235a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1236290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1237a65d3064SKris Buschelman break; 1238b87ac2d8SJed Brown case MAT_USE_INODES: 1239b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1240b87ac2d8SJed Brown break; 1241c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1242c10200c1SHong Zhang A->submat_singleis = flg; 1243c10200c1SHong Zhang break; 1244071fcb05SBarry Smith case MAT_SORTED_FULL: 1245071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1246071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1247071fcb05SBarry Smith break; 1248a65d3064SKris Buschelman default: 1249e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1250a65d3064SKris Buschelman } 12514108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 12523a40ed3dSBarry Smith PetscFunctionReturn(0); 125317ab2063SBarry Smith } 125417ab2063SBarry Smith 1255dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 125617ab2063SBarry Smith { 1257416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12586849ba73SBarry Smith PetscErrorCode ierr; 1259fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1260fdc842d1SBarry Smith PetscScalar *aa=a->a,*x; 126117ab2063SBarry Smith 12623a40ed3dSBarry Smith PetscFunctionBegin; 1263d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1264e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 126535e7444dSHong Zhang 1266d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1267d3e70bfaSHong Zhang PetscInt *diag=a->diag; 1268fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 12692c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 1270fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 127135e7444dSHong Zhang PetscFunctionReturn(0); 127235e7444dSHong Zhang } 127335e7444dSHong Zhang 1274fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 127535e7444dSHong Zhang for (i=0; i<n; i++) { 1276fdc842d1SBarry Smith x[i] = 0.0; 127735e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 127835e7444dSHong Zhang if (aj[j] == i) { 127935e7444dSHong Zhang x[i] = aa[j]; 128017ab2063SBarry Smith break; 128117ab2063SBarry Smith } 128217ab2063SBarry Smith } 128317ab2063SBarry Smith } 1284fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 12853a40ed3dSBarry Smith PetscFunctionReturn(0); 128617ab2063SBarry Smith } 128717ab2063SBarry Smith 1288c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1289dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 129017ab2063SBarry Smith { 1291416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1292d9ca1df4SBarry Smith PetscScalar *y; 1293d9ca1df4SBarry Smith const PetscScalar *x; 1294dfbe8321SBarry Smith PetscErrorCode ierr; 1295d0f46423SBarry Smith PetscInt m = A->rmap->n; 12965c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1297d9ca1df4SBarry Smith const MatScalar *v; 1298a77337e4SBarry Smith PetscScalar alpha; 1299d9ca1df4SBarry Smith PetscInt n,i,j; 1300d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 13013447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1302ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 13035c897100SBarry Smith #endif 130417ab2063SBarry Smith 13053a40ed3dSBarry Smith PetscFunctionBegin; 13062e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1307d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 13081ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 13095c897100SBarry Smith 13105c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1311bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 13125c897100SBarry Smith #else 13133447b6efSHong Zhang if (usecprow) { 13143447b6efSHong Zhang m = cprow.nrows; 13153447b6efSHong Zhang ii = cprow.i; 13167b2bb3b9SHong Zhang ridx = cprow.rindex; 13173447b6efSHong Zhang } else { 13183447b6efSHong Zhang ii = a->i; 13193447b6efSHong Zhang } 132017ab2063SBarry Smith for (i=0; i<m; i++) { 13213447b6efSHong Zhang idx = a->j + ii[i]; 13223447b6efSHong Zhang v = a->a + ii[i]; 13233447b6efSHong Zhang n = ii[i+1] - ii[i]; 13243447b6efSHong Zhang if (usecprow) { 13257b2bb3b9SHong Zhang alpha = x[ridx[i]]; 13263447b6efSHong Zhang } else { 132717ab2063SBarry Smith alpha = x[i]; 13283447b6efSHong Zhang } 132904fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 133017ab2063SBarry Smith } 13315c897100SBarry Smith #endif 1332dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1333d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 13341ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13353a40ed3dSBarry Smith PetscFunctionReturn(0); 133617ab2063SBarry Smith } 133717ab2063SBarry Smith 1338dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 13395c897100SBarry Smith { 1340dfbe8321SBarry Smith PetscErrorCode ierr; 13415c897100SBarry Smith 13425c897100SBarry Smith PetscFunctionBegin; 1343170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 13445c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 13455c897100SBarry Smith PetscFunctionReturn(0); 13465c897100SBarry Smith } 13475c897100SBarry Smith 1348c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 134978b84d54SShri Abhyankar 1350dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 135117ab2063SBarry Smith { 1352416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1353d9fead3dSBarry Smith PetscScalar *y; 135454f21887SBarry Smith const PetscScalar *x; 135554f21887SBarry Smith const MatScalar *aa; 1356dfbe8321SBarry Smith PetscErrorCode ierr; 1357003131ecSBarry Smith PetscInt m=A->rmap->n; 13580298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 13597b083b7cSBarry Smith PetscInt n,i; 1360362ced78SSatish Balay PetscScalar sum; 1361ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 136217ab2063SBarry Smith 1363b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 136497952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1365fee21e36SBarry Smith #endif 1366fee21e36SBarry Smith 13673a40ed3dSBarry Smith PetscFunctionBegin; 13683649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 13691ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1370416022c9SBarry Smith ii = a->i; 13714eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1372580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 137397952fefSHong Zhang m = a->compressedrow.nrows; 137497952fefSHong Zhang ii = a->compressedrow.i; 137597952fefSHong Zhang ridx = a->compressedrow.rindex; 137697952fefSHong Zhang for (i=0; i<m; i++) { 137797952fefSHong Zhang n = ii[i+1] - ii[i]; 137897952fefSHong Zhang aj = a->j + ii[i]; 137997952fefSHong Zhang aa = a->a + ii[i]; 138097952fefSHong Zhang sum = 0.0; 1381003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1382003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 138397952fefSHong Zhang y[*ridx++] = sum; 138497952fefSHong Zhang } 138597952fefSHong Zhang } else { /* do not use compressed row format */ 1386b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 13873d3eaba7SBarry Smith aj = a->j; 13883d3eaba7SBarry Smith aa = a->a; 1389b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1390b05257ddSBarry Smith #else 139117ab2063SBarry Smith for (i=0; i<m; i++) { 1392003131ecSBarry Smith n = ii[i+1] - ii[i]; 1393003131ecSBarry Smith aj = a->j + ii[i]; 1394003131ecSBarry Smith aa = a->a + ii[i]; 139517ab2063SBarry Smith sum = 0.0; 1396003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 139717ab2063SBarry Smith y[i] = sum; 139817ab2063SBarry Smith } 13998d195f9aSBarry Smith #endif 1400b05257ddSBarry Smith } 14017b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 14023649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14031ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14043a40ed3dSBarry Smith PetscFunctionReturn(0); 140517ab2063SBarry Smith } 140617ab2063SBarry Smith 1407b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1408b434eb95SMatthew G. Knepley { 1409b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1410b434eb95SMatthew G. Knepley PetscScalar *y; 1411b434eb95SMatthew G. Knepley const PetscScalar *x; 1412b434eb95SMatthew G. Knepley const MatScalar *aa; 1413b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1414b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1415b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1416b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1417b434eb95SMatthew G. Knepley PetscScalar sum; 1418b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1419b434eb95SMatthew G. Knepley 1420b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1421b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1422b434eb95SMatthew G. Knepley #endif 1423b434eb95SMatthew G. Knepley 1424b434eb95SMatthew G. Knepley PetscFunctionBegin; 1425b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1426b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1427b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1428b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1429b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1430b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1431b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1432b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1433b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1434b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1435b434eb95SMatthew G. Knepley sum = 0.0; 1436b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1437b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1438b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1439b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1440b434eb95SMatthew G. Knepley } 1441b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 14423d3eaba7SBarry Smith ii = a->i; 1443b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1444b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1445b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1446b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1447b434eb95SMatthew G. Knepley sum = 0.0; 1448b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1449b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1450b434eb95SMatthew G. Knepley y[i] = sum; 1451b434eb95SMatthew G. Knepley } 1452b434eb95SMatthew G. Knepley } 1453b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1454b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1455b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1456b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1457b434eb95SMatthew G. Knepley } 1458b434eb95SMatthew G. Knepley 1459b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1460b434eb95SMatthew G. Knepley { 1461b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1462b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1463b434eb95SMatthew G. Knepley const PetscScalar *x; 1464b434eb95SMatthew G. Knepley const MatScalar *aa; 1465b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1466b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1467b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1468b434eb95SMatthew G. Knepley PetscScalar sum; 1469b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1470b434eb95SMatthew G. Knepley 1471b434eb95SMatthew G. Knepley PetscFunctionBegin; 1472b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1473d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1474b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1475b434eb95SMatthew G. Knepley if (zz != yy) { 1476580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1477b434eb95SMatthew G. Knepley } 1478b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1479b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1480b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1481b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1482b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1483b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1484b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1485b434eb95SMatthew G. Knepley sum = y[*ridx]; 1486b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1487b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1488b434eb95SMatthew G. Knepley } 1489b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 14903d3eaba7SBarry Smith ii = a->i; 1491b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1492b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1493b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1494b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1495b434eb95SMatthew G. Knepley sum = y[i]; 1496b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1497b434eb95SMatthew G. Knepley z[i] = sum; 1498b434eb95SMatthew G. Knepley } 1499b434eb95SMatthew G. Knepley } 1500b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1501b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1502d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1503b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1504b434eb95SMatthew G. Knepley } 1505b434eb95SMatthew G. Knepley 1506c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1507dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 150817ab2063SBarry Smith { 1509416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1510f15663dcSBarry Smith PetscScalar *y,*z; 1511f15663dcSBarry Smith const PetscScalar *x; 151254f21887SBarry Smith const MatScalar *aa; 1513dfbe8321SBarry Smith PetscErrorCode ierr; 1514d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1515d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1516362ced78SSatish Balay PetscScalar sum; 1517ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 15189ea0dfa2SSatish Balay 15193a40ed3dSBarry Smith PetscFunctionBegin; 1520f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1521d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 15224eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 15234eb6d288SHong Zhang if (zz != yy) { 1524580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 15254eb6d288SHong Zhang } 152697952fefSHong Zhang m = a->compressedrow.nrows; 152797952fefSHong Zhang ii = a->compressedrow.i; 152897952fefSHong Zhang ridx = a->compressedrow.rindex; 152997952fefSHong Zhang for (i=0; i<m; i++) { 153097952fefSHong Zhang n = ii[i+1] - ii[i]; 153197952fefSHong Zhang aj = a->j + ii[i]; 153297952fefSHong Zhang aa = a->a + ii[i]; 153397952fefSHong Zhang sum = y[*ridx]; 1534f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 153597952fefSHong Zhang z[*ridx++] = sum; 153697952fefSHong Zhang } 153797952fefSHong Zhang } else { /* do not use compressed row format */ 15383d3eaba7SBarry Smith ii = a->i; 1539f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 15403d3eaba7SBarry Smith aj = a->j; 15413d3eaba7SBarry Smith aa = a->a; 1542f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1543f15663dcSBarry Smith #else 154417ab2063SBarry Smith for (i=0; i<m; i++) { 1545f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1546f15663dcSBarry Smith aj = a->j + ii[i]; 1547f15663dcSBarry Smith aa = a->a + ii[i]; 154817ab2063SBarry Smith sum = y[i]; 1549f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 155017ab2063SBarry Smith z[i] = sum; 155117ab2063SBarry Smith } 155202ab625aSSatish Balay #endif 1553f15663dcSBarry Smith } 1554dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1555f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1556d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 15573a40ed3dSBarry Smith PetscFunctionReturn(0); 155817ab2063SBarry Smith } 155917ab2063SBarry Smith 156017ab2063SBarry Smith /* 156117ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 156217ab2063SBarry Smith */ 1563dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 156417ab2063SBarry Smith { 1565416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15666849ba73SBarry Smith PetscErrorCode ierr; 1567d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 156817ab2063SBarry Smith 15693a40ed3dSBarry Smith PetscFunctionBegin; 157009f38230SBarry Smith if (!a->diag) { 1571785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 15723bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 157309f38230SBarry Smith } 1574d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 157509f38230SBarry Smith a->diag[i] = a->i[i+1]; 1576bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1577bfeeae90SHong Zhang if (a->j[j] == i) { 157809f38230SBarry Smith a->diag[i] = j; 157917ab2063SBarry Smith break; 158017ab2063SBarry Smith } 158117ab2063SBarry Smith } 158217ab2063SBarry Smith } 15833a40ed3dSBarry Smith PetscFunctionReturn(0); 158417ab2063SBarry Smith } 158517ab2063SBarry Smith 158661ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 158761ecd0c6SBarry Smith { 158861ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 158961ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 159061ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 159161ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 159261ecd0c6SBarry Smith PetscErrorCode ierr; 159361ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 159461ecd0c6SBarry Smith 159561ecd0c6SBarry Smith PetscFunctionBegin; 159661ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 159761ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 159861ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 159961ecd0c6SBarry Smith PetscFunctionReturn(0); 160061ecd0c6SBarry Smith } 160161ecd0c6SBarry Smith 160261ecd0c6SBarry Smith if (a->diagonaldense) { 160361ecd0c6SBarry Smith cnt = 0; 160461ecd0c6SBarry Smith } else { 160561ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 160661ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 160761ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 160861ecd0c6SBarry Smith cnt++; 160961ecd0c6SBarry Smith mdiag[i] = 1; 161061ecd0c6SBarry Smith } 161161ecd0c6SBarry Smith } 161261ecd0c6SBarry Smith } 161361ecd0c6SBarry Smith if (!cnt) { 161461ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 161561ecd0c6SBarry Smith } else { 1616b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1617b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 161861ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 161961ecd0c6SBarry Smith 162061ecd0c6SBarry Smith a->a = NULL; 162161ecd0c6SBarry Smith a->j = NULL; 162261ecd0c6SBarry Smith a->i = NULL; 162361ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 162461ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 162561ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1626447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 162761ecd0c6SBarry Smith } 162861ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 162961ecd0c6SBarry Smith 163061ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 163161ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 163261ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1633447d62f5SStefano Zampini if (i < A->cmap->n) { 163461ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 163561ecd0c6SBarry Smith } 1636447d62f5SStefano Zampini } 163761ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 163861ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 163961ecd0c6SBarry Smith if (singlemalloc) { 164061ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 164161ecd0c6SBarry Smith } else { 164261ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 164361ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 164461ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 164561ecd0c6SBarry Smith } 164661ecd0c6SBarry Smith } 164761ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 164861ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 164961ecd0c6SBarry Smith PetscFunctionReturn(0); 165061ecd0c6SBarry Smith } 165161ecd0c6SBarry Smith 1652be5855fcSBarry Smith /* 1653be5855fcSBarry Smith Checks for missing diagonals 1654be5855fcSBarry Smith */ 1655ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1656be5855fcSBarry Smith { 1657be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 16587734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1659994fe344SLisandro Dalcin PetscErrorCode ierr; 1660be5855fcSBarry Smith 1661be5855fcSBarry Smith PetscFunctionBegin; 166209f38230SBarry Smith *missing = PETSC_FALSE; 16637734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 166409f38230SBarry Smith *missing = PETSC_TRUE; 166509f38230SBarry Smith if (d) *d = 0; 1666994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 166709f38230SBarry Smith } else { 166801445905SHong Zhang PetscInt n; 166901445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1670f1e2ffcdSBarry Smith diag = a->diag; 167101445905SHong Zhang for (i=0; i<n; i++) { 16727734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 167309f38230SBarry Smith *missing = PETSC_TRUE; 167409f38230SBarry Smith if (d) *d = i; 1675994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1676358d2f5dSShri Abhyankar break; 167709f38230SBarry Smith } 1678be5855fcSBarry Smith } 1679be5855fcSBarry Smith } 1680be5855fcSBarry Smith PetscFunctionReturn(0); 1681be5855fcSBarry Smith } 1682be5855fcSBarry Smith 16830da83c2eSBarry Smith #include <petscblaslapack.h> 16840da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 16850da83c2eSBarry Smith 16860da83c2eSBarry Smith /* 16870da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 16880da83c2eSBarry Smith */ 16890da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 16900da83c2eSBarry Smith { 16910da83c2eSBarry Smith PetscErrorCode ierr; 16920da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 16930da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 16940da83c2eSBarry Smith const PetscReal shift = 0.0; 16950da83c2eSBarry Smith PetscInt ipvt[5]; 16960da83c2eSBarry Smith PetscScalar work[25],*v_work; 16970da83c2eSBarry Smith 16980da83c2eSBarry Smith PetscFunctionBegin; 16990da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 17000da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 17010da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 17020da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 17030da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 17040da83c2eSBarry Smith } 17050da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 17060da83c2eSBarry Smith if (bsizemax > 7) { 17070da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 17080da83c2eSBarry Smith } 17090da83c2eSBarry Smith ncnt = 0; 17100da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 17110da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 17120da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 17130da83c2eSBarry Smith switch (bsizes[i]) { 17140da83c2eSBarry Smith case 1: 17150da83c2eSBarry Smith *diag = 1.0/(*diag); 17160da83c2eSBarry Smith break; 17170da83c2eSBarry Smith case 2: 17180da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17190da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17200da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 17210da83c2eSBarry Smith break; 17220da83c2eSBarry Smith case 3: 17230da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17240da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17250da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 17260da83c2eSBarry Smith break; 17270da83c2eSBarry Smith case 4: 17280da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17290da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17300da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 17310da83c2eSBarry Smith break; 17320da83c2eSBarry Smith case 5: 17330da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17340da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17350da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 17360da83c2eSBarry Smith break; 17370da83c2eSBarry Smith case 6: 17380da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17390da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17400da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 17410da83c2eSBarry Smith break; 17420da83c2eSBarry Smith case 7: 17430da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17440da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17450da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 17460da83c2eSBarry Smith break; 17470da83c2eSBarry Smith default: 17480da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17490da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17500da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 17510da83c2eSBarry Smith } 17520da83c2eSBarry Smith ncnt += bsizes[i]; 17530da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 17540da83c2eSBarry Smith } 17550da83c2eSBarry Smith if (bsizemax > 7) { 17560da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 17570da83c2eSBarry Smith } 17580da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 17590da83c2eSBarry Smith PetscFunctionReturn(0); 17600da83c2eSBarry Smith } 17610da83c2eSBarry Smith 1762422a814eSBarry Smith /* 1763422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1764422a814eSBarry Smith */ 17657087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 176671f1c65dSBarry Smith { 176771f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 176871f1c65dSBarry Smith PetscErrorCode ierr; 1769d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 177054f21887SBarry Smith MatScalar *v = a->a; 177154f21887SBarry Smith PetscScalar *idiag,*mdiag; 177271f1c65dSBarry Smith 177371f1c65dSBarry Smith PetscFunctionBegin; 177471f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 177571f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 177671f1c65dSBarry Smith diag = a->diag; 177771f1c65dSBarry Smith if (!a->idiag) { 1778dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 17793bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 178071f1c65dSBarry Smith v = a->a; 178171f1c65dSBarry Smith } 178271f1c65dSBarry Smith mdiag = a->mdiag; 178371f1c65dSBarry Smith idiag = a->idiag; 178471f1c65dSBarry Smith 1785422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 178671f1c65dSBarry Smith for (i=0; i<m; i++) { 178771f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1788899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1789899639b0SHong Zhang if (PetscRealPart(fshift)) { 1790899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 17917b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17927b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 17937b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1794a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1795899639b0SHong Zhang } 179671f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 179771f1c65dSBarry Smith } 179871f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 179971f1c65dSBarry Smith } else { 180071f1c65dSBarry Smith for (i=0; i<m; i++) { 180171f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 180271f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 180371f1c65dSBarry Smith } 1804dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 180571f1c65dSBarry Smith } 180671f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 180771f1c65dSBarry Smith PetscFunctionReturn(0); 180871f1c65dSBarry Smith } 180971f1c65dSBarry Smith 1810c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 181141f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 181217ab2063SBarry Smith { 1813416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1814e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 18153d3eaba7SBarry Smith const MatScalar *v,*idiag=0,*mdiag; 181654f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1817dfbe8321SBarry Smith PetscErrorCode ierr; 18183d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 181997f1f81fSBarry Smith const PetscInt *idx,*diag; 182017ab2063SBarry Smith 18213a40ed3dSBarry Smith PetscFunctionBegin; 1822b965ef7fSBarry Smith its = its*lits; 182391723122SBarry Smith 182471f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 182571f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 182671f1c65dSBarry Smith a->fshift = fshift; 182771f1c65dSBarry Smith a->omega = omega; 1828ed480e8bSBarry Smith 182971f1c65dSBarry Smith diag = a->diag; 183071f1c65dSBarry Smith t = a->ssor_work; 1831ed480e8bSBarry Smith idiag = a->idiag; 183271f1c65dSBarry Smith mdiag = a->mdiag; 1833ed480e8bSBarry Smith 18341ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 18353649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1836ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 183717ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 183817ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1839ed480e8bSBarry Smith bs = b; 184017ab2063SBarry Smith for (i=0; i<m; i++) { 184171f1c65dSBarry Smith d = fshift + mdiag[i]; 1842416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1843ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1844ed480e8bSBarry Smith v = a->a + diag[i] + 1; 184517ab2063SBarry Smith sum = b[i]*d/omega; 1846003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 184717ab2063SBarry Smith x[i] = sum; 184817ab2063SBarry Smith } 18491ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 18503649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1851efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 18523a40ed3dSBarry Smith PetscFunctionReturn(0); 185317ab2063SBarry Smith } 1854c783ea89SBarry Smith 18552205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 18562205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 18574c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 1858887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 185917ab2063SBarry Smith 186017ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 186117ab2063SBarry Smith 1862887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 186317ab2063SBarry Smith */ 186417ab2063SBarry Smith scale = (2.0/omega) - 1.0; 186517ab2063SBarry Smith 186617ab2063SBarry Smith /* x = (E + U)^{-1} b */ 186717ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1868416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1869ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1870ed480e8bSBarry Smith v = a->a + diag[i] + 1; 187117ab2063SBarry Smith sum = b[i]; 1872e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1873ed480e8bSBarry Smith x[i] = sum*idiag[i]; 187417ab2063SBarry Smith } 187517ab2063SBarry Smith 187617ab2063SBarry Smith /* t = b - (2*E - D)x */ 1877416022c9SBarry Smith v = a->a; 18782205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 187917ab2063SBarry Smith 188017ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1881ed480e8bSBarry Smith ts = t; 1882416022c9SBarry Smith diag = a->diag; 188317ab2063SBarry Smith for (i=0; i<m; i++) { 1884416022c9SBarry Smith n = diag[i] - a->i[i]; 1885ed480e8bSBarry Smith idx = a->j + a->i[i]; 1886ed480e8bSBarry Smith v = a->a + a->i[i]; 188717ab2063SBarry Smith sum = t[i]; 1888003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1889ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1890733d66baSBarry Smith /* x = x + t */ 1891733d66baSBarry Smith x[i] += t[i]; 189217ab2063SBarry Smith } 189317ab2063SBarry Smith 1894dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 18951ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 18963649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 18973a40ed3dSBarry Smith PetscFunctionReturn(0); 189817ab2063SBarry Smith } 189917ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 190017ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 190117ab2063SBarry Smith for (i=0; i<m; i++) { 1902416022c9SBarry Smith n = diag[i] - a->i[i]; 1903ed480e8bSBarry Smith idx = a->j + a->i[i]; 1904ed480e8bSBarry Smith v = a->a + a->i[i]; 190517ab2063SBarry Smith sum = b[i]; 1906e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 19075c99c7daSBarry Smith t[i] = sum; 1908ed480e8bSBarry Smith x[i] = sum*idiag[i]; 190917ab2063SBarry Smith } 19105c99c7daSBarry Smith xb = t; 1911efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 19123a40ed3dSBarry Smith } else xb = b; 191317ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 191417ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1915416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1916ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1917ed480e8bSBarry Smith v = a->a + diag[i] + 1; 191817ab2063SBarry Smith sum = xb[i]; 1919e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 19205c99c7daSBarry Smith if (xb == b) { 1921ed480e8bSBarry Smith x[i] = sum*idiag[i]; 19225c99c7daSBarry Smith } else { 1923b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 192417ab2063SBarry Smith } 19255c99c7daSBarry Smith } 1926b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 192717ab2063SBarry Smith } 192817ab2063SBarry Smith its--; 192917ab2063SBarry Smith } 193017ab2063SBarry Smith while (its--) { 193117ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 193217ab2063SBarry Smith for (i=0; i<m; i++) { 1933b19a5dc2SMark Adams /* lower */ 1934b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1935ed480e8bSBarry Smith idx = a->j + a->i[i]; 1936ed480e8bSBarry Smith v = a->a + a->i[i]; 193717ab2063SBarry Smith sum = b[i]; 1938e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1939b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1940b19a5dc2SMark Adams /* upper */ 1941b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1942b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1943b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1944b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1945b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 194617ab2063SBarry Smith } 1947b19a5dc2SMark Adams xb = t; 19489f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1949b19a5dc2SMark Adams } else xb = b; 195017ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 195117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1952b19a5dc2SMark Adams sum = xb[i]; 1953b19a5dc2SMark Adams if (xb == b) { 1954b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1955416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1956ed480e8bSBarry Smith idx = a->j + a->i[i]; 1957ed480e8bSBarry Smith v = a->a + a->i[i]; 1958e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1959ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1960b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1961b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1962b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1963b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1964b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1965b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 196617ab2063SBarry Smith } 1967b19a5dc2SMark Adams } 1968b19a5dc2SMark Adams if (xb == b) { 19699f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1970b19a5dc2SMark Adams } else { 1971b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1972b19a5dc2SMark Adams } 197317ab2063SBarry Smith } 197417ab2063SBarry Smith } 19751ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 19763649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1977365a8a9eSBarry Smith PetscFunctionReturn(0); 197817ab2063SBarry Smith } 197917ab2063SBarry Smith 19802af78befSBarry Smith 1981dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 198217ab2063SBarry Smith { 1983416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19844e220ebcSLois Curfman McInnes 19853a40ed3dSBarry Smith PetscFunctionBegin; 19864e220ebcSLois Curfman McInnes info->block_size = 1.0; 19874e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 19884e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 19894e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 19904e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 19918e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 19927adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1993d5f3da31SBarry Smith if (A->factortype) { 19944e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 19954e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 19964e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 19974e220ebcSLois Curfman McInnes } else { 19984e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 19994e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 20004e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 20014e220ebcSLois Curfman McInnes } 20023a40ed3dSBarry Smith PetscFunctionReturn(0); 200317ab2063SBarry Smith } 200417ab2063SBarry Smith 20052b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 200617ab2063SBarry Smith { 2007416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2008c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 20096849ba73SBarry Smith PetscErrorCode ierr; 201097b48c8fSBarry Smith const PetscScalar *xx; 201197b48c8fSBarry Smith PetscScalar *bb; 2012c7da8527SEric Chamberland PetscInt d = 0; 201317ab2063SBarry Smith 20143a40ed3dSBarry Smith PetscFunctionBegin; 201597b48c8fSBarry Smith if (x && b) { 201697b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 201797b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 201897b48c8fSBarry Smith for (i=0; i<N; i++) { 201997b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2020447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 202197b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 202297b48c8fSBarry Smith } 202397b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 202497b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 202597b48c8fSBarry Smith } 202697b48c8fSBarry Smith 2027a9817697SBarry Smith if (a->keepnonzeropattern) { 2028f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2029e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2030580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2031f1e2ffcdSBarry Smith } 2032f4df32b1SMatthew Knepley if (diag != 0.0) { 2033c7da8527SEric Chamberland for (i=0; i<N; i++) { 2034c7da8527SEric Chamberland d = rows[i]; 2035447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2036c7da8527SEric 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); 2037c7da8527SEric Chamberland } 2038f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2039447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2040f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 2041f1e2ffcdSBarry Smith } 2042f1e2ffcdSBarry Smith } 2043f1e2ffcdSBarry Smith } else { 2044f4df32b1SMatthew Knepley if (diag != 0.0) { 204517ab2063SBarry Smith for (i=0; i<N; i++) { 2046e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 20477ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2048447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2049447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2050447d62f5SStefano Zampini } else { 2051416022c9SBarry Smith a->ilen[rows[i]] = 1; 2052f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 2053bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2054447d62f5SStefano Zampini } 2055447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2056f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 205717ab2063SBarry Smith } 205817ab2063SBarry Smith } 20593a40ed3dSBarry Smith } else { 206017ab2063SBarry Smith for (i=0; i<N; i++) { 2061e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2062416022c9SBarry Smith a->ilen[rows[i]] = 0; 206317ab2063SBarry Smith } 206417ab2063SBarry Smith } 2065e56f5c9eSBarry Smith A->nonzerostate++; 2066f1e2ffcdSBarry Smith } 2067e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2068*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2069e2cf4d64SStefano Zampini #endif 20704099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20713a40ed3dSBarry Smith PetscFunctionReturn(0); 207217ab2063SBarry Smith } 207317ab2063SBarry Smith 20746e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 20756e169961SBarry Smith { 20766e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20776e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 20786e169961SBarry Smith PetscErrorCode ierr; 20792b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 20806e169961SBarry Smith const PetscScalar *xx; 20816e169961SBarry Smith PetscScalar *bb; 20826e169961SBarry Smith 20836e169961SBarry Smith PetscFunctionBegin; 20846e169961SBarry Smith if (x && b) { 20856e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 20866e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 20872b40b63fSBarry Smith vecs = PETSC_TRUE; 20886e169961SBarry Smith } 20891795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 20906e169961SBarry Smith for (i=0; i<N; i++) { 20916e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2092580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 20932205254eSKarl Rupp 20946e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 20956e169961SBarry Smith } 20966e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 20976e169961SBarry Smith if (!zeroed[i]) { 20986e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 20994cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 21002b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 21016e169961SBarry Smith a->a[j] = 0.0; 21026e169961SBarry Smith } 21036e169961SBarry Smith } 21044cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 21056e169961SBarry Smith } 21066e169961SBarry Smith if (x && b) { 21076e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 21086e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 21096e169961SBarry Smith } 21106e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 21116e169961SBarry Smith if (diag != 0.0) { 21126e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 21131d5a398dSstefano_zampini if (missing) { 21141d5a398dSstefano_zampini for (i=0; i<N; i++) { 21154cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 21164cf107fdSStefano 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]); 21171d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 21181d5a398dSstefano_zampini } 21191d5a398dSstefano_zampini } else { 21206e169961SBarry Smith for (i=0; i<N; i++) { 21216e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 21226e169961SBarry Smith } 21236e169961SBarry Smith } 21241d5a398dSstefano_zampini } 2125e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2126*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2127e2cf4d64SStefano Zampini #endif 21284099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21296e169961SBarry Smith PetscFunctionReturn(0); 21306e169961SBarry Smith } 21316e169961SBarry Smith 2132a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 213317ab2063SBarry Smith { 2134416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 213597f1f81fSBarry Smith PetscInt *itmp; 213617ab2063SBarry Smith 21373a40ed3dSBarry Smith PetscFunctionBegin; 2138e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 213917ab2063SBarry Smith 2140416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 2141bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 214217ab2063SBarry Smith if (idx) { 2143bfeeae90SHong Zhang itmp = a->j + a->i[row]; 214426fbe8dcSKarl Rupp if (*nz) *idx = itmp; 214517ab2063SBarry Smith else *idx = 0; 214617ab2063SBarry Smith } 21473a40ed3dSBarry Smith PetscFunctionReturn(0); 214817ab2063SBarry Smith } 214917ab2063SBarry Smith 2150bfeeae90SHong Zhang /* remove this function? */ 2151a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 215217ab2063SBarry Smith { 21533a40ed3dSBarry Smith PetscFunctionBegin; 21543a40ed3dSBarry Smith PetscFunctionReturn(0); 215517ab2063SBarry Smith } 215617ab2063SBarry Smith 2157dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 215817ab2063SBarry Smith { 2159416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 216054f21887SBarry Smith MatScalar *v = a->a; 216136db0b34SBarry Smith PetscReal sum = 0.0; 21626849ba73SBarry Smith PetscErrorCode ierr; 216397f1f81fSBarry Smith PetscInt i,j; 216417ab2063SBarry Smith 21653a40ed3dSBarry Smith PetscFunctionBegin; 216617ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2167570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2168570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 2169570b7f6dSBarry Smith *nrm = BLASnrm2_(&nz,v,&one); 2170570b7f6dSBarry Smith #else 2171416022c9SBarry Smith for (i=0; i<a->nz; i++) { 217236db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 217317ab2063SBarry Smith } 21748f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2175570b7f6dSBarry Smith #endif 217651f70360SJed Brown ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 21773a40ed3dSBarry Smith } else if (type == NORM_1) { 217836db0b34SBarry Smith PetscReal *tmp; 217997f1f81fSBarry Smith PetscInt *jj = a->j; 21801795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2181064f8208SBarry Smith *nrm = 0.0; 2182416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2183bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 218417ab2063SBarry Smith } 2185d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2186064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 218717ab2063SBarry Smith } 2188606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 218951f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 21903a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2191064f8208SBarry Smith *nrm = 0.0; 2192d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 2193bfeeae90SHong Zhang v = a->a + a->i[j]; 219417ab2063SBarry Smith sum = 0.0; 2195416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 2196cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 219717ab2063SBarry Smith } 2198064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 219917ab2063SBarry Smith } 220051f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2201f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 22023a40ed3dSBarry Smith PetscFunctionReturn(0); 220317ab2063SBarry Smith } 220417ab2063SBarry Smith 22054e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 22064e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 22074e938277SHong Zhang { 22084e938277SHong Zhang PetscErrorCode ierr; 22094e938277SHong Zhang PetscInt i,j,anzj; 22104e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 22114e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 22124e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 22134e938277SHong Zhang 22144e938277SHong Zhang PetscFunctionBegin; 22154e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2216854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2217785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2218785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 22194e938277SHong Zhang 22204e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 22214e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 222226fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 22234e938277SHong Zhang /* Form ati for csr format of A^T. */ 222426fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 22254e938277SHong Zhang 22264e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2227580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 22284e938277SHong Zhang 22294e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 22304e938277SHong Zhang for (i=0;i<am;i++) { 22314e938277SHong Zhang anzj = ai[i+1] - ai[i]; 22324e938277SHong Zhang for (j=0;j<anzj;j++) { 22334e938277SHong Zhang atj[atfill[*aj]] = i; 22344e938277SHong Zhang atfill[*aj++] += 1; 22354e938277SHong Zhang } 22364e938277SHong Zhang } 22374e938277SHong Zhang 22384e938277SHong Zhang /* Clean up temporary space and complete requests. */ 22394e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2240ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 224133d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2242b5bb3eecSMark Adams ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2243a2f3521dSMark F. Adams 22444e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 22454e938277SHong Zhang b->free_a = PETSC_FALSE; 22464e938277SHong Zhang b->free_ij = PETSC_TRUE; 22474e938277SHong Zhang b->nonew = 0; 22484e938277SHong Zhang PetscFunctionReturn(0); 22494e938277SHong Zhang } 22504e938277SHong Zhang 22517087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2252cd0d46ebSvictorle { 22533d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 225454f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 225554f21887SBarry Smith MatScalar *va,*vb; 22566849ba73SBarry Smith PetscErrorCode ierr; 225797f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2258cd0d46ebSvictorle 2259cd0d46ebSvictorle PetscFunctionBegin; 2260cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2261cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 22625485867bSBarry Smith if (ma!=nb || na!=mb) { 22635485867bSBarry Smith *f = PETSC_FALSE; 22645485867bSBarry Smith PetscFunctionReturn(0); 22655485867bSBarry Smith } 2266cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2267cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2268cd0d46ebSvictorle va = aij->a; vb = bij->a; 2269785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2270785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2271cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2272cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2273cd0d46ebSvictorle 2274cd0d46ebSvictorle *f = PETSC_TRUE; 2275cd0d46ebSvictorle for (i=0; i<ma; i++) { 2276cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 227797f1f81fSBarry Smith PetscInt idc,idr; 22785485867bSBarry Smith PetscScalar vc,vr; 2279cd0d46ebSvictorle /* column/row index/value */ 22805485867bSBarry Smith idc = adx[aptr[i]]; 22815485867bSBarry Smith idr = bdx[bptr[idc]]; 22825485867bSBarry Smith vc = va[aptr[i]]; 22835485867bSBarry Smith vr = vb[bptr[idc]]; 22845485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 22855485867bSBarry Smith *f = PETSC_FALSE; 22865485867bSBarry Smith goto done; 2287cd0d46ebSvictorle } else { 22885485867bSBarry Smith aptr[i]++; 22895485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2290cd0d46ebSvictorle } 2291cd0d46ebSvictorle } 2292cd0d46ebSvictorle } 2293cd0d46ebSvictorle done: 2294cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 22953aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2296cd0d46ebSvictorle PetscFunctionReturn(0); 2297cd0d46ebSvictorle } 2298cd0d46ebSvictorle 22997087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 23001cbb95d3SBarry Smith { 23013d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 230254f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 230354f21887SBarry Smith MatScalar *va,*vb; 23041cbb95d3SBarry Smith PetscErrorCode ierr; 23051cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 23061cbb95d3SBarry Smith 23071cbb95d3SBarry Smith PetscFunctionBegin; 23081cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 23091cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 23101cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 23111cbb95d3SBarry Smith *f = PETSC_FALSE; 23121cbb95d3SBarry Smith PetscFunctionReturn(0); 23131cbb95d3SBarry Smith } 23141cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 23151cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 23161cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2317785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2318785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 23191cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 23201cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 23211cbb95d3SBarry Smith 23221cbb95d3SBarry Smith *f = PETSC_TRUE; 23231cbb95d3SBarry Smith for (i=0; i<ma; i++) { 23241cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 23251cbb95d3SBarry Smith PetscInt idc,idr; 23261cbb95d3SBarry Smith PetscScalar vc,vr; 23271cbb95d3SBarry Smith /* column/row index/value */ 23281cbb95d3SBarry Smith idc = adx[aptr[i]]; 23291cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 23301cbb95d3SBarry Smith vc = va[aptr[i]]; 23311cbb95d3SBarry Smith vr = vb[bptr[idc]]; 23321cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 23331cbb95d3SBarry Smith *f = PETSC_FALSE; 23341cbb95d3SBarry Smith goto done; 23351cbb95d3SBarry Smith } else { 23361cbb95d3SBarry Smith aptr[i]++; 23371cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 23381cbb95d3SBarry Smith } 23391cbb95d3SBarry Smith } 23401cbb95d3SBarry Smith } 23411cbb95d3SBarry Smith done: 23421cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 23431cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 23441cbb95d3SBarry Smith PetscFunctionReturn(0); 23451cbb95d3SBarry Smith } 23461cbb95d3SBarry Smith 2347ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 23489e29f15eSvictorle { 2349dfbe8321SBarry Smith PetscErrorCode ierr; 23506e111a19SKarl Rupp 23519e29f15eSvictorle PetscFunctionBegin; 23525485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 23539e29f15eSvictorle PetscFunctionReturn(0); 23549e29f15eSvictorle } 23559e29f15eSvictorle 2356ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 23571cbb95d3SBarry Smith { 23581cbb95d3SBarry Smith PetscErrorCode ierr; 23596e111a19SKarl Rupp 23601cbb95d3SBarry Smith PetscFunctionBegin; 23611cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 23621cbb95d3SBarry Smith PetscFunctionReturn(0); 23631cbb95d3SBarry Smith } 23641cbb95d3SBarry Smith 2365dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 236617ab2063SBarry Smith { 2367416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2368fff8e43fSBarry Smith const PetscScalar *l,*r; 2369fff8e43fSBarry Smith PetscScalar x; 237054f21887SBarry Smith MatScalar *v; 2371dfbe8321SBarry Smith PetscErrorCode ierr; 2372fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2373fff8e43fSBarry Smith const PetscInt *jj; 237417ab2063SBarry Smith 23753a40ed3dSBarry Smith PetscFunctionBegin; 237617ab2063SBarry Smith if (ll) { 23773ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 23783ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2379e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2380e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2381fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 2382416022c9SBarry Smith v = a->a; 238317ab2063SBarry Smith for (i=0; i<m; i++) { 238417ab2063SBarry Smith x = l[i]; 2385416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 23862205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 238717ab2063SBarry Smith } 2388fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2389efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 239017ab2063SBarry Smith } 239117ab2063SBarry Smith if (rr) { 2392e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2393e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2394fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 2395416022c9SBarry Smith v = a->a; jj = a->j; 23962205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 2397fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2398efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 239917ab2063SBarry Smith } 2400acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 2401e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2402*c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2403e2cf4d64SStefano Zampini #endif 24043a40ed3dSBarry Smith PetscFunctionReturn(0); 240517ab2063SBarry Smith } 240617ab2063SBarry Smith 24077dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 240817ab2063SBarry Smith { 2409db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 24106849ba73SBarry Smith PetscErrorCode ierr; 2411d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 241297f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 24135d0c19d7SBarry Smith const PetscInt *irow,*icol; 24145d0c19d7SBarry Smith PetscInt nrows,ncols; 241597f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 241654f21887SBarry Smith MatScalar *a_new,*mat_a; 2417416022c9SBarry Smith Mat C; 2418cdc6f3adSToby Isaac PetscBool stride; 241917ab2063SBarry Smith 24203a40ed3dSBarry Smith PetscFunctionBegin; 242199141d43SSatish Balay 242217ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2423b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2424b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 242517ab2063SBarry Smith 2426251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2427ff718158SBarry Smith if (stride) { 2428ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2429ff718158SBarry Smith } else { 2430ff718158SBarry Smith first = 0; 2431ff718158SBarry Smith step = 0; 2432ff718158SBarry Smith } 2433fee21e36SBarry Smith if (stride && step == 1) { 243402834360SBarry Smith /* special case of contiguous rows */ 2435dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 243602834360SBarry Smith /* loop over new rows determining lens and starting points */ 243702834360SBarry Smith for (i=0; i<nrows; i++) { 2438bfeeae90SHong Zhang kstart = ai[irow[i]]; 2439a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2440a91a9bebSLisandro Dalcin starts[i] = kstart; 244102834360SBarry Smith for (k=kstart; k<kend; k++) { 2442bfeeae90SHong Zhang if (aj[k] >= first) { 244302834360SBarry Smith starts[i] = k; 244402834360SBarry Smith break; 244502834360SBarry Smith } 244602834360SBarry Smith } 2447a2744918SBarry Smith sum = 0; 244802834360SBarry Smith while (k < kend) { 2449bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2450a2744918SBarry Smith sum++; 245102834360SBarry Smith } 2452a2744918SBarry Smith lens[i] = sum; 245302834360SBarry Smith } 245402834360SBarry Smith /* create submatrix */ 2455cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 245697f1f81fSBarry Smith PetscInt n_cols,n_rows; 245708480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2458e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2459d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 246008480c60SBarry Smith C = *B; 24613a40ed3dSBarry Smith } else { 24623bef6203SJed Brown PetscInt rbs,cbs; 2463ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2464f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 24653bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 24663bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 24673bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 24687adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2469ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 247008480c60SBarry Smith } 2471db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2472db02288aSLois Curfman McInnes 247302834360SBarry Smith /* loop over rows inserting into submatrix */ 2474db02288aSLois Curfman McInnes a_new = c->a; 2475db02288aSLois Curfman McInnes j_new = c->j; 2476db02288aSLois Curfman McInnes i_new = c->i; 2477bfeeae90SHong Zhang 247802834360SBarry Smith for (i=0; i<nrows; i++) { 2479a2744918SBarry Smith ii = starts[i]; 2480a2744918SBarry Smith lensi = lens[i]; 2481a2744918SBarry Smith for (k=0; k<lensi; k++) { 2482a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 248302834360SBarry Smith } 2484580bdb30SBarry Smith ierr = PetscArraycpy(a_new,a->a + starts[i],lensi);CHKERRQ(ierr); 2485a2744918SBarry Smith a_new += lensi; 2486a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2487a2744918SBarry Smith c->ilen[i] = lensi; 248802834360SBarry Smith } 24890e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 24903a40ed3dSBarry Smith } else { 249102834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 24921795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2493854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 24944dcab191SBarry Smith for (i=0; i<ncols; i++) { 24954dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 24964dcab191SBarry Smith if (icol[i] >= oldcols) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%D] %D <= A->cmap->n %D",i,icol[i],oldcols); 24974dcab191SBarry Smith #endif 24984dcab191SBarry Smith smap[icol[i]] = i+1; 24994dcab191SBarry Smith } 25004dcab191SBarry Smith 250102834360SBarry Smith /* determine lens of each row */ 250202834360SBarry Smith for (i=0; i<nrows; i++) { 2503bfeeae90SHong Zhang kstart = ai[irow[i]]; 250402834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 250502834360SBarry Smith lens[i] = 0; 250602834360SBarry Smith for (k=kstart; k<kend; k++) { 2507bfeeae90SHong Zhang if (smap[aj[k]]) { 250802834360SBarry Smith lens[i]++; 250902834360SBarry Smith } 251002834360SBarry Smith } 251102834360SBarry Smith } 251217ab2063SBarry Smith /* Create and fill new matrix */ 2513a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2514ace3abfcSBarry Smith PetscBool equal; 25150f5bd95cSBarry Smith 251699141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2517e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2518580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2519f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2520580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 252108480c60SBarry Smith C = *B; 25223a40ed3dSBarry Smith } else { 25233bef6203SJed Brown PetscInt rbs,cbs; 2524ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2525f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 25263bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 25273bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 25283bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 25297adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2530ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 253108480c60SBarry Smith } 253299141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 253317ab2063SBarry Smith for (i=0; i<nrows; i++) { 253499141d43SSatish Balay row = irow[i]; 2535bfeeae90SHong Zhang kstart = ai[row]; 253699141d43SSatish Balay kend = kstart + a->ilen[row]; 2537bfeeae90SHong Zhang mat_i = c->i[i]; 253899141d43SSatish Balay mat_j = c->j + mat_i; 253999141d43SSatish Balay mat_a = c->a + mat_i; 254099141d43SSatish Balay mat_ilen = c->ilen + i; 254117ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2542bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2543ed480e8bSBarry Smith *mat_j++ = tcol - 1; 254499141d43SSatish Balay *mat_a++ = a->a[k]; 254599141d43SSatish Balay (*mat_ilen)++; 254699141d43SSatish Balay 254717ab2063SBarry Smith } 254817ab2063SBarry Smith } 254917ab2063SBarry Smith } 255002834360SBarry Smith /* Free work space */ 255102834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2552606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2553606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2554cdc6f3adSToby Isaac /* sort */ 2555cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2556cdc6f3adSToby Isaac PetscInt ilen; 2557cdc6f3adSToby Isaac 2558cdc6f3adSToby Isaac mat_i = c->i[i]; 2559cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2560cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2561cdc6f3adSToby Isaac ilen = c->ilen[i]; 2562390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2563cdc6f3adSToby Isaac } 256402834360SBarry Smith } 2565305c6ccfSStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2566305c6ccfSStefano Zampini ierr = MatPinToCPU(C,A->pinnedtocpu);CHKERRQ(ierr); 2567305c6ccfSStefano Zampini #endif 25686d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 25696d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 257017ab2063SBarry Smith 257117ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2572416022c9SBarry Smith *B = C; 25733a40ed3dSBarry Smith PetscFunctionReturn(0); 257417ab2063SBarry Smith } 257517ab2063SBarry Smith 2576fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 257782d44351SHong Zhang { 257882d44351SHong Zhang PetscErrorCode ierr; 257982d44351SHong Zhang Mat B; 258082d44351SHong Zhang 258182d44351SHong Zhang PetscFunctionBegin; 2582c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 258382d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 258482d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 258533d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 258682d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 258782d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 258882d44351SHong Zhang *subMat = B; 2589c2d650bdSHong Zhang } else { 2590c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2591c2d650bdSHong Zhang } 259282d44351SHong Zhang PetscFunctionReturn(0); 259382d44351SHong Zhang } 259482d44351SHong Zhang 25959a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2596a871dcd8SBarry Smith { 259763b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2598dfbe8321SBarry Smith PetscErrorCode ierr; 259963b91edcSBarry Smith Mat outA; 2600ace3abfcSBarry Smith PetscBool row_identity,col_identity; 260163b91edcSBarry Smith 26023a40ed3dSBarry Smith PetscFunctionBegin; 2603e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 26041df811f5SHong Zhang 2605b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2606b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2607a871dcd8SBarry Smith 260863b91edcSBarry Smith outA = inA; 2609d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2610f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2611f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 26122205254eSKarl Rupp 2613c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 26146bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 26152205254eSKarl Rupp 2616c3122656SLisandro Dalcin a->row = row; 26172205254eSKarl Rupp 2618c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 26196bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 26202205254eSKarl Rupp 2621c3122656SLisandro Dalcin a->col = col; 262263b91edcSBarry Smith 262336db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 26246bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 26254c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 26263bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2627f0ec6fceSSatish Balay 262894a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2629854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 26303bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 263194a9d846SBarry Smith } 263263b91edcSBarry Smith 2633f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2634137fb511SHong Zhang if (row_identity && col_identity) { 2635ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2636137fb511SHong Zhang } else { 2637719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2638137fb511SHong Zhang } 26393a40ed3dSBarry Smith PetscFunctionReturn(0); 2640a871dcd8SBarry Smith } 2641a871dcd8SBarry Smith 2642f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2643f0b747eeSBarry Smith { 2644f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2645f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2646efee365bSSatish Balay PetscErrorCode ierr; 2647c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 26483a40ed3dSBarry Smith 26493a40ed3dSBarry Smith PetscFunctionBegin; 2650c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 26518b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2652efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2653acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 2654e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2655*c70f7ee4SJunchao Zhang if (inA->offloadmask != PETSC_OFFLOAD_UNALLOCATED) inA->offloadmask = PETSC_OFFLOAD_CPU; 2656e2cf4d64SStefano Zampini #endif 26573a40ed3dSBarry Smith PetscFunctionReturn(0); 2658f0b747eeSBarry Smith } 2659f0b747eeSBarry Smith 2660f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 266116b64355SHong Zhang { 266216b64355SHong Zhang PetscErrorCode ierr; 266316b64355SHong Zhang PetscInt i; 266416b64355SHong Zhang 266516b64355SHong Zhang PetscFunctionBegin; 266616b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 266716b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 266816b64355SHong Zhang 266916b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 267016b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 267116b64355SHong Zhang } 267216b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 267316b64355SHong Zhang 267416b64355SHong Zhang if (submatj->rbuf1) { 267516b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 267616b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 267716b64355SHong Zhang } 267816b64355SHong Zhang 267916b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 268016b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 268116b64355SHong Zhang } 268216b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 268316b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 268416b64355SHong Zhang } 268516b64355SHong Zhang 268616b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 268716b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 268816b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 268916b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 269016b64355SHong Zhang #else 269116b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 269216b64355SHong Zhang #endif 269316b64355SHong Zhang 269416b64355SHong Zhang if (!submatj->allcolumns) { 269516b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 269616b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 269716b64355SHong Zhang #else 269816b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 269916b64355SHong Zhang #endif 270016b64355SHong Zhang } 270116b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 270216b64355SHong Zhang 270316b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 270416b64355SHong Zhang PetscFunctionReturn(0); 270516b64355SHong Zhang } 270616b64355SHong Zhang 27070fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 270816b64355SHong Zhang { 270916b64355SHong Zhang PetscErrorCode ierr; 271016b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 27115c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 271216b64355SHong Zhang 271316b64355SHong Zhang PetscFunctionBegin; 271434136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2715f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 271616b64355SHong Zhang PetscFunctionReturn(0); 271716b64355SHong Zhang } 271816b64355SHong Zhang 27192d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 27202d033e1fSHong Zhang { 27212d033e1fSHong Zhang PetscErrorCode ierr; 27222d033e1fSHong Zhang PetscInt i; 27230fb991dcSHong Zhang Mat C; 27240fb991dcSHong Zhang Mat_SeqAIJ *c; 27250fb991dcSHong Zhang Mat_SubSppt *submatj; 27262d033e1fSHong Zhang 27272d033e1fSHong Zhang PetscFunctionBegin; 27282d033e1fSHong Zhang for (i=0; i<n; i++) { 27290fb991dcSHong Zhang C = (*mat)[i]; 27300fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 27310fb991dcSHong Zhang submatj = c->submatis1; 27322d033e1fSHong Zhang if (submatj) { 2733682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 273434136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2735f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 273634136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 27372d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 27382d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 27392d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2740682e4c99SStefano Zampini } 27412d033e1fSHong Zhang } else { 27422d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 27432d033e1fSHong Zhang } 27442d033e1fSHong Zhang } 274586e85357SHong Zhang 274663a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 274763a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 274863a75b2aSHong Zhang 27492d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 27502d033e1fSHong Zhang PetscFunctionReturn(0); 27512d033e1fSHong Zhang } 27522d033e1fSHong Zhang 27537dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2754cddf8d76SBarry Smith { 2755dfbe8321SBarry Smith PetscErrorCode ierr; 275697f1f81fSBarry Smith PetscInt i; 2757cddf8d76SBarry Smith 27583a40ed3dSBarry Smith PetscFunctionBegin; 2759cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2760df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2761cddf8d76SBarry Smith } 2762cddf8d76SBarry Smith 2763cddf8d76SBarry Smith for (i=0; i<n; i++) { 27647dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2765cddf8d76SBarry Smith } 27663a40ed3dSBarry Smith PetscFunctionReturn(0); 2767cddf8d76SBarry Smith } 2768cddf8d76SBarry Smith 276997f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 27704dcbc457SBarry Smith { 2771e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 27726849ba73SBarry Smith PetscErrorCode ierr; 27735d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 27745d0c19d7SBarry Smith const PetscInt *idx; 277597f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2776f1af5d2fSBarry Smith PetscBT table; 2777bbd702dbSSatish Balay 27783a40ed3dSBarry Smith PetscFunctionBegin; 2779d0f46423SBarry Smith m = A->rmap->n; 2780e4d965acSSatish Balay ai = a->i; 2781bfeeae90SHong Zhang aj = a->j; 27828a047759SSatish Balay 2783e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 278406763907SSatish Balay 2785854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 278653b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 278706763907SSatish Balay 2788e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2789b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2790e4d965acSSatish Balay isz = 0; 27916831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2792e4d965acSSatish Balay 2793e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 27944dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2795b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2796e4d965acSSatish Balay 2797dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2798e4d965acSSatish Balay for (j=0; j<n; ++j) { 27992205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 28004dcbc457SBarry Smith } 280106763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 28026bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2803e4d965acSSatish Balay 280404a348a9SBarry Smith k = 0; 280504a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 280604a348a9SBarry Smith n = isz; 280706763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2808e4d965acSSatish Balay row = nidx[k]; 2809e4d965acSSatish Balay start = ai[row]; 2810e4d965acSSatish Balay end = ai[row+1]; 281104a348a9SBarry Smith for (l = start; l<end; l++) { 2812efb16452SHong Zhang val = aj[l]; 28132205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2814e4d965acSSatish Balay } 2815e4d965acSSatish Balay } 2816e4d965acSSatish Balay } 281770b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2818e4d965acSSatish Balay } 281994bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2820606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 28213a40ed3dSBarry Smith PetscFunctionReturn(0); 28224dcbc457SBarry Smith } 282317ab2063SBarry Smith 28240513a670SBarry Smith /* -------------------------------------------------------------- */ 2825dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 28260513a670SBarry Smith { 28270513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 28286849ba73SBarry Smith PetscErrorCode ierr; 28293b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 28305d0c19d7SBarry Smith const PetscInt *row,*col; 28315d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 283256cd22aeSBarry Smith IS icolp,irowp; 28330298fd71SBarry Smith PetscInt *cwork = NULL; 28340298fd71SBarry Smith PetscScalar *vwork = NULL; 28350513a670SBarry Smith 28363a40ed3dSBarry Smith PetscFunctionBegin; 28374c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 283856cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 28394c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 284056cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 28410513a670SBarry Smith 28420513a670SBarry Smith /* determine lengths of permuted rows */ 2843854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 28442205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2845ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2846f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 284733d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 28487adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2849ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2850606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 28510513a670SBarry Smith 2852785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 28530513a670SBarry Smith for (i=0; i<m; i++) { 285432ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 28552205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2856cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 285732ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 28580513a670SBarry Smith } 2859606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 28602205254eSKarl Rupp 28613c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 28622205254eSKarl Rupp 28639fe5e383SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 28649fe5e383SStefano Zampini ierr = MatPinToCPU(*B,A->pinnedtocpu);CHKERRQ(ierr); 28659fe5e383SStefano Zampini #endif 28660513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28670513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 286856cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 286956cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 28706bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 28716bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 28723a40ed3dSBarry Smith PetscFunctionReturn(0); 28730513a670SBarry Smith } 28740513a670SBarry Smith 2875dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2876cb5b572fSBarry Smith { 2877dfbe8321SBarry Smith PetscErrorCode ierr; 2878cb5b572fSBarry Smith 2879cb5b572fSBarry Smith PetscFunctionBegin; 288033f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 288133f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2882be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2883be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2884be6bf707SBarry Smith 2885700c5bfcSBarry Smith if (a->i[A->rmap->n] != b->i[B->rmap->n]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 2886580bdb30SBarry Smith ierr = PetscArraycpy(b->a,a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 2887cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 2888cb5b572fSBarry Smith } else { 2889cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2890cb5b572fSBarry Smith } 2891cb5b572fSBarry Smith PetscFunctionReturn(0); 2892cb5b572fSBarry Smith } 2893cb5b572fSBarry Smith 28944994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2895273d9f13SBarry Smith { 2896dfbe8321SBarry Smith PetscErrorCode ierr; 2897273d9f13SBarry Smith 2898273d9f13SBarry Smith PetscFunctionBegin; 2899ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2900273d9f13SBarry Smith PetscFunctionReturn(0); 2901273d9f13SBarry Smith } 2902273d9f13SBarry Smith 2903f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 29046c0721eeSBarry Smith { 29056c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29066e111a19SKarl Rupp 29076c0721eeSBarry Smith PetscFunctionBegin; 29086c0721eeSBarry Smith *array = a->a; 29096c0721eeSBarry Smith PetscFunctionReturn(0); 29106c0721eeSBarry Smith } 29116c0721eeSBarry Smith 2912f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 29136c0721eeSBarry Smith { 29146c0721eeSBarry Smith PetscFunctionBegin; 2915f38c1e66SStefano Zampini *array = NULL; 29166c0721eeSBarry Smith PetscFunctionReturn(0); 29176c0721eeSBarry Smith } 2918273d9f13SBarry Smith 29198229c054SShri Abhyankar /* 29208229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 29218229c054SShri Abhyankar have different nonzero structure. 29228229c054SShri Abhyankar */ 2923b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 2924ec7775f6SShri Abhyankar { 2925b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 2926ec7775f6SShri Abhyankar 2927ec7775f6SShri Abhyankar PetscFunctionBegin; 2928ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2929ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 2930b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 2931b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 2932b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 29338af7cee1SJed Brown nnz[i] = 0; 29348af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 2935b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 2936b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 29378af7cee1SJed Brown nnz[i]++; 29388af7cee1SJed Brown } 29398af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2940ec7775f6SShri Abhyankar } 2941ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2942ec7775f6SShri Abhyankar } 2943ec7775f6SShri Abhyankar 2944b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2945b264fe52SHong Zhang { 2946b264fe52SHong Zhang PetscInt m = Y->rmap->N; 2947b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2948b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2949b264fe52SHong Zhang PetscErrorCode ierr; 2950b264fe52SHong Zhang 2951b264fe52SHong Zhang PetscFunctionBegin; 2952b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 2953b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 2954b264fe52SHong Zhang PetscFunctionReturn(0); 2955b264fe52SHong Zhang } 2956b264fe52SHong Zhang 2957f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2958ac90fabeSBarry Smith { 2959dfbe8321SBarry Smith PetscErrorCode ierr; 2960ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2961c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2962ac90fabeSBarry Smith 2963ac90fabeSBarry Smith PetscFunctionBegin; 2964c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2965ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2966f4df32b1SMatthew Knepley PetscScalar alpha = a; 29678b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2968acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2969a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 2970e2cf4d64SStefano Zampini /* the MatAXPY_Basic* subroutines calls MatAssembly, so the matrix on the GPU 2971e2cf4d64SStefano Zampini will be updated */ 2972e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2973*c70f7ee4SJunchao Zhang if (Y->offloadmask != PETSC_OFFLOAD_UNALLOCATED) { 2974*c70f7ee4SJunchao Zhang Y->offloadmask = PETSC_OFFLOAD_CPU; 2975e2cf4d64SStefano Zampini } 2976e2cf4d64SStefano Zampini #endif 2977ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2978ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2979ac90fabeSBarry Smith } else { 29808229c054SShri Abhyankar Mat B; 29818229c054SShri Abhyankar PetscInt *nnz; 2982785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 2983ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 2984bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 29854aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 298633d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr); 2987176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 29888229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2989ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2990ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 299128be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 29928229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2993ac90fabeSBarry Smith } 2994ac90fabeSBarry Smith PetscFunctionReturn(0); 2995ac90fabeSBarry Smith } 2996ac90fabeSBarry Smith 29977087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2998354c94deSBarry Smith { 2999354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3000354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3001354c94deSBarry Smith PetscInt i,nz; 3002354c94deSBarry Smith PetscScalar *a; 3003354c94deSBarry Smith 3004354c94deSBarry Smith PetscFunctionBegin; 3005354c94deSBarry Smith nz = aij->nz; 3006354c94deSBarry Smith a = aij->a; 30072205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 3008e2cf4d64SStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 3009*c70f7ee4SJunchao Zhang if (mat->offloadmask != PETSC_OFFLOAD_UNALLOCATED) mat->offloadmask = PETSC_OFFLOAD_CPU; 3010e2cf4d64SStefano Zampini #endif 3011354c94deSBarry Smith #else 3012354c94deSBarry Smith PetscFunctionBegin; 3013354c94deSBarry Smith #endif 3014354c94deSBarry Smith PetscFunctionReturn(0); 3015354c94deSBarry Smith } 3016354c94deSBarry Smith 3017985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3018e34fafa9SBarry Smith { 3019e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3020e34fafa9SBarry Smith PetscErrorCode ierr; 3021d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3022e34fafa9SBarry Smith PetscReal atmp; 3023985db425SBarry Smith PetscScalar *x; 3024e34fafa9SBarry Smith MatScalar *aa; 3025e34fafa9SBarry Smith 3026e34fafa9SBarry Smith PetscFunctionBegin; 3027e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3028e34fafa9SBarry Smith aa = a->a; 3029e34fafa9SBarry Smith ai = a->i; 3030e34fafa9SBarry Smith aj = a->j; 3031e34fafa9SBarry Smith 3032985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3033e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3034e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3035e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3036e34fafa9SBarry Smith for (i=0; i<m; i++) { 3037e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 30389189402eSHong Zhang x[i] = 0.0; 3039e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3040985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3041985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3042985db425SBarry Smith aa++; aj++; 3043985db425SBarry Smith } 3044985db425SBarry Smith } 3045985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3046985db425SBarry Smith PetscFunctionReturn(0); 3047985db425SBarry Smith } 3048985db425SBarry Smith 3049985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3050985db425SBarry Smith { 3051985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3052985db425SBarry Smith PetscErrorCode ierr; 3053d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3054985db425SBarry Smith PetscScalar *x; 3055985db425SBarry Smith MatScalar *aa; 3056985db425SBarry Smith 3057985db425SBarry Smith PetscFunctionBegin; 3058e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3059985db425SBarry Smith aa = a->a; 3060985db425SBarry Smith ai = a->i; 3061985db425SBarry Smith aj = a->j; 3062985db425SBarry Smith 3063985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3064985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3065985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3066e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3067985db425SBarry Smith for (i=0; i<m; i++) { 3068985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3069d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3070985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3071985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3072985db425SBarry Smith x[i] = 0.0; 3073985db425SBarry Smith if (idx) { 3074985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3075985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 3076985db425SBarry Smith if (aj[j] > j) { 3077985db425SBarry Smith idx[i] = j; 3078985db425SBarry Smith break; 3079985db425SBarry Smith } 3080985db425SBarry Smith } 3081985db425SBarry Smith } 3082985db425SBarry Smith } 3083985db425SBarry Smith for (j=0; j<ncols; j++) { 3084985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3085985db425SBarry Smith aa++; aj++; 3086985db425SBarry Smith } 3087985db425SBarry Smith } 3088985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3089985db425SBarry Smith PetscFunctionReturn(0); 3090985db425SBarry Smith } 3091985db425SBarry Smith 3092c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3093c87e5d42SMatthew Knepley { 3094c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3095c87e5d42SMatthew Knepley PetscErrorCode ierr; 3096c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3097c87e5d42SMatthew Knepley PetscReal atmp; 3098c87e5d42SMatthew Knepley PetscScalar *x; 3099c87e5d42SMatthew Knepley MatScalar *aa; 3100c87e5d42SMatthew Knepley 3101c87e5d42SMatthew Knepley PetscFunctionBegin; 3102e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3103c87e5d42SMatthew Knepley aa = a->a; 3104c87e5d42SMatthew Knepley ai = a->i; 3105c87e5d42SMatthew Knepley aj = a->j; 3106c87e5d42SMatthew Knepley 3107c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3108c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3109c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 311060e0710aSBarry Smith if (n != A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %D vs. %D rows", A->rmap->n, n); 3111c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3112c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3113289a08f5SMatthew Knepley if (ncols) { 3114289a08f5SMatthew Knepley /* Get first nonzero */ 3115289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 3116289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 31172205254eSKarl Rupp if (atmp > 1.0e-12) { 31182205254eSKarl Rupp x[i] = atmp; 31192205254eSKarl Rupp if (idx) idx[i] = aj[j]; 31202205254eSKarl Rupp break; 31212205254eSKarl Rupp } 3122289a08f5SMatthew Knepley } 312312431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 3124289a08f5SMatthew Knepley } else { 3125289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 3126289a08f5SMatthew Knepley } 3127c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 3128c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 3129289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3130c87e5d42SMatthew Knepley aa++; aj++; 3131c87e5d42SMatthew Knepley } 3132c87e5d42SMatthew Knepley } 3133c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3134c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3135c87e5d42SMatthew Knepley } 3136c87e5d42SMatthew Knepley 3137985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3138985db425SBarry Smith { 3139985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3140985db425SBarry Smith PetscErrorCode ierr; 3141d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3142d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3143985db425SBarry Smith PetscScalar *x; 3144d9ca1df4SBarry Smith const MatScalar *aa; 3145985db425SBarry Smith 3146985db425SBarry Smith PetscFunctionBegin; 3147e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3148985db425SBarry Smith aa = a->a; 3149985db425SBarry Smith ai = a->i; 3150985db425SBarry Smith aj = a->j; 3151985db425SBarry Smith 3152985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3153985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3154985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3155e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3156985db425SBarry Smith for (i=0; i<m; i++) { 3157985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3158d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3159985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3160985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3161985db425SBarry Smith x[i] = 0.0; 3162985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3163985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3164985db425SBarry Smith for (j=0; j<ncols; j++) { 3165985db425SBarry Smith if (aj[j] > j) { 3166985db425SBarry Smith idx[i] = j; 3167985db425SBarry Smith break; 3168985db425SBarry Smith } 3169985db425SBarry Smith } 3170985db425SBarry Smith } 3171985db425SBarry Smith } 3172985db425SBarry Smith for (j=0; j<ncols; j++) { 3173985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3174985db425SBarry Smith aa++; aj++; 3175e34fafa9SBarry Smith } 3176e34fafa9SBarry Smith } 3177e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3178e34fafa9SBarry Smith PetscFunctionReturn(0); 3179e34fafa9SBarry Smith } 3180bbead8a2SBarry Smith 3181713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3182bbead8a2SBarry Smith { 3183bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3184bbead8a2SBarry Smith PetscErrorCode ierr; 318533d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3186bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 31870da83c2eSBarry Smith const PetscReal shift = 0.0; 31881a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3189bbead8a2SBarry Smith 3190bbead8a2SBarry Smith PetscFunctionBegin; 3191a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 31924a0d0026SBarry Smith if (a->ibdiagvalid) { 31934a0d0026SBarry Smith if (values) *values = a->ibdiag; 31944a0d0026SBarry Smith PetscFunctionReturn(0); 31954a0d0026SBarry Smith } 3196bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3197bbead8a2SBarry Smith if (!a->ibdiag) { 3198785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 31993bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3200bbead8a2SBarry Smith } 3201bbead8a2SBarry Smith diag = a->ibdiag; 3202bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3203bbead8a2SBarry Smith /* factor and invert each block */ 3204bbead8a2SBarry Smith switch (bs) { 3205bbead8a2SBarry Smith case 1: 3206bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3207bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3208ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3209ec1892c8SHong Zhang if (allowzeropivot) { 32107b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 32117b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 32127b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 32137b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 32147b6c816cSBarry 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); 3215ec1892c8SHong Zhang } 3216bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3217bbead8a2SBarry Smith } 3218bbead8a2SBarry Smith break; 3219bbead8a2SBarry Smith case 2: 3220bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3221bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3222bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3223a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32247b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 322596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3226bbead8a2SBarry Smith diag += 4; 3227bbead8a2SBarry Smith } 3228bbead8a2SBarry Smith break; 3229bbead8a2SBarry Smith case 3: 3230bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3231bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3232bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3233a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32347b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 323596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3236bbead8a2SBarry Smith diag += 9; 3237bbead8a2SBarry Smith } 3238bbead8a2SBarry Smith break; 3239bbead8a2SBarry Smith case 4: 3240bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3241bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3242bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3243a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32447b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 324596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3246bbead8a2SBarry Smith diag += 16; 3247bbead8a2SBarry Smith } 3248bbead8a2SBarry Smith break; 3249bbead8a2SBarry Smith case 5: 3250bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3251bbead8a2SBarry 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; 3252bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3253a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32547b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 325596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3256bbead8a2SBarry Smith diag += 25; 3257bbead8a2SBarry Smith } 3258bbead8a2SBarry Smith break; 3259bbead8a2SBarry Smith case 6: 3260bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3261bbead8a2SBarry 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; 3262bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3263a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32647b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 326596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3266bbead8a2SBarry Smith diag += 36; 3267bbead8a2SBarry Smith } 3268bbead8a2SBarry Smith break; 3269bbead8a2SBarry Smith case 7: 3270bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3271bbead8a2SBarry 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; 3272bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3273a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32747b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 327596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3276bbead8a2SBarry Smith diag += 49; 3277bbead8a2SBarry Smith } 3278bbead8a2SBarry Smith break; 3279bbead8a2SBarry Smith default: 3280dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3281bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3282bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3283bbead8a2SBarry Smith IJ[j] = bs*i + j; 3284bbead8a2SBarry Smith } 3285bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 32865f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32877b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 328896b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3289bbead8a2SBarry Smith diag += bs2; 3290bbead8a2SBarry Smith } 3291bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3292bbead8a2SBarry Smith } 3293bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3294bbead8a2SBarry Smith PetscFunctionReturn(0); 3295bbead8a2SBarry Smith } 3296bbead8a2SBarry Smith 329773a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 329873a71a0fSBarry Smith { 329973a71a0fSBarry Smith PetscErrorCode ierr; 330073a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 330173a71a0fSBarry Smith PetscScalar a; 330273a71a0fSBarry Smith PetscInt m,n,i,j,col; 330373a71a0fSBarry Smith 330473a71a0fSBarry Smith PetscFunctionBegin; 330573a71a0fSBarry Smith if (!x->assembled) { 330673a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 330773a71a0fSBarry Smith for (i=0; i<m; i++) { 330873a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 330973a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 331073a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 331173a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 331273a71a0fSBarry Smith } 331373a71a0fSBarry Smith } 3314e2ce353bSJunchao Zhang } else { 3315e2ce353bSJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aij->a+i);CHKERRQ(ierr);} 3316e2ce353bSJunchao Zhang } 331773a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 331873a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 331973a71a0fSBarry Smith PetscFunctionReturn(0); 332073a71a0fSBarry Smith } 332173a71a0fSBarry Smith 3322679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3323679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3324679944adSJunchao Zhang { 3325679944adSJunchao Zhang PetscErrorCode ierr; 3326679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3327679944adSJunchao Zhang PetscScalar a; 3328679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3329679944adSJunchao Zhang 3330679944adSJunchao Zhang PetscFunctionBegin; 3331679944adSJunchao Zhang nskip = high - low; 3332679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3333679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3334679944adSJunchao Zhang for (i=0; i<m; i++) { 3335679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3336679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3337679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3338679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3339679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3340679944adSJunchao Zhang } 3341e2ce353bSJunchao Zhang } 3342679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3343679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3344679944adSJunchao Zhang PetscFunctionReturn(0); 3345679944adSJunchao Zhang } 3346679944adSJunchao Zhang 3347679944adSJunchao Zhang 3348682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 33490a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3350cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3351cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3352cb5b572fSBarry Smith MatMult_SeqAIJ, 335397304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 33547c922b88SBarry Smith MatMultTranspose_SeqAIJ, 33557c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3356db4efbfdSBarry Smith 0, 3357db4efbfdSBarry Smith 0, 3358db4efbfdSBarry Smith 0, 3359db4efbfdSBarry Smith /* 10*/ 0, 3360cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3361cb5b572fSBarry Smith 0, 336241f059aeSBarry Smith MatSOR_SeqAIJ, 336391e9d3e2SHong Zhang MatTranspose_SeqAIJ, 336497304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3365cb5b572fSBarry Smith MatEqual_SeqAIJ, 3366cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3367cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3368cb5b572fSBarry Smith MatNorm_SeqAIJ, 336997304618SKris Buschelman /* 20*/ 0, 3370cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3371cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3372cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3373d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3374db4efbfdSBarry Smith 0, 3375db4efbfdSBarry Smith 0, 3376db4efbfdSBarry Smith 0, 3377db4efbfdSBarry Smith 0, 33784994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3379db4efbfdSBarry Smith 0, 3380db4efbfdSBarry Smith 0, 33818c778c55SBarry Smith 0, 33828c778c55SBarry Smith 0, 3383d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3384cb5b572fSBarry Smith 0, 3385cb5b572fSBarry Smith 0, 3386cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3387cb5b572fSBarry Smith 0, 3388d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 33897dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3390cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3391cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3392cb5b572fSBarry Smith MatCopy_SeqAIJ, 3393d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3394cb5b572fSBarry Smith MatScale_SeqAIJ, 33957d68702bSBarry Smith MatShift_SeqAIJ, 339679299369SBarry Smith MatDiagonalSet_SeqAIJ, 33976e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 339873a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 33993b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 34003b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 34013b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3402a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 340393dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3404b9617806SBarry Smith 0, 34050513a670SBarry Smith 0, 3406cda55fadSBarry Smith MatPermute_SeqAIJ, 3407cda55fadSBarry Smith 0, 3408d519adbfSMatthew Knepley /* 59*/ 0, 3409b9b97703SBarry Smith MatDestroy_SeqAIJ, 3410b9b97703SBarry Smith MatView_SeqAIJ, 3411357abbc8SBarry Smith 0, 3412321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3413321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3414321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3415ee4f033dSBarry Smith 0, 3416ee4f033dSBarry Smith 0, 3417ee4f033dSBarry Smith 0, 3418d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3419c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3420ee4f033dSBarry Smith 0, 3421dcf5cc72SBarry Smith 0, 34222c93a97aSBarry Smith 0, 34232c93a97aSBarry Smith /* 74*/ 0, 34243acb8795SBarry Smith MatFDColoringApply_AIJ, 342597304618SKris Buschelman 0, 342697304618SKris Buschelman 0, 342797304618SKris Buschelman 0, 34286ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 342997304618SKris Buschelman 0, 343097304618SKris Buschelman 0, 343197304618SKris Buschelman 0, 3432bc011b1eSHong Zhang MatLoad_SeqAIJ, 3433d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 34341cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 34356284ec50SHong Zhang 0, 34366284ec50SHong Zhang 0, 3437bc011b1eSHong Zhang 0, 3438d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 343926be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 344026be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 344165e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 34428fa4b5a6SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_SparseAxpy, 34438fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 34446fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 34456fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 34466fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 34472121bac1SHong Zhang 0, 34482121bac1SHong Zhang /* 99*/ 0, 3449609c6c4dSKris Buschelman 0, 3450609c6c4dSKris Buschelman 0, 345187d4246cSBarry Smith MatConjugate_SeqAIJ, 345287d4246cSBarry Smith 0, 3453d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 345499cafbc1SBarry Smith MatRealPart_SeqAIJ, 3455f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3456f5edf698SHong Zhang 0, 34572bebee5dSHong Zhang 0, 3458cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3459985db425SBarry Smith 0, 34602af78befSBarry Smith MatGetRowMin_SeqAIJ, 34612af78befSBarry Smith 0, 3462599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3463d519adbfSMatthew Knepley /*114*/ 0, 3464599ef60dSHong Zhang 0, 34653c2a7987SHong Zhang 0, 3466fe97e370SBarry Smith 0, 3467fbdbba38SShri Abhyankar 0, 3468fbdbba38SShri Abhyankar /*119*/ 0, 3469fbdbba38SShri Abhyankar 0, 3470fbdbba38SShri Abhyankar 0, 347182d44351SHong Zhang 0, 3472b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 34730716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3474bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 347537868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 34760da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 347737868618SMatthew G Knepley 0, 34785df89d91SHong Zhang /*129*/ 0, 347975648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 348075648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 348175648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3482b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3483b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 34842b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 34852b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 34862b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 34873964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 34883964eb88SJed Brown /*139*/0, 3489f9426fe0SMark Adams 0, 34901919a2e2SJed Brown 0, 34913a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 34929c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 34932d033e1fSHong Zhang /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 34942d033e1fSHong Zhang MatDestroySubMatrices_SeqAIJ 34959e29f15eSvictorle }; 349617ab2063SBarry Smith 34977087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3498bef8e0ddSBarry Smith { 3499bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 350097f1f81fSBarry Smith PetscInt i,nz,n; 3501bef8e0ddSBarry Smith 3502bef8e0ddSBarry Smith PetscFunctionBegin; 3503bef8e0ddSBarry Smith nz = aij->maxnz; 3504d0f46423SBarry Smith n = mat->rmap->n; 3505bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3506bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3507bef8e0ddSBarry Smith } 3508bef8e0ddSBarry Smith aij->nz = nz; 3509bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3510bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3511bef8e0ddSBarry Smith } 3512bef8e0ddSBarry Smith PetscFunctionReturn(0); 3513bef8e0ddSBarry Smith } 3514bef8e0ddSBarry Smith 3515a3bb6f32SFande Kong /* 3516e8b528d9SFande Kong * When a sparse matrix has many zero columns, we should compact them out to save the space 3517a3bb6f32SFande Kong * This happens in MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3518a3bb6f32SFande Kong * */ 3519a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3520a3bb6f32SFande Kong { 3521a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3522a3bb6f32SFande Kong PetscTable gid1_lid1; 3523a3bb6f32SFande Kong PetscTablePosition tpos; 3524a3bb6f32SFande Kong PetscInt gid,lid,i,j,ncols,ec; 3525a3bb6f32SFande Kong PetscInt *garray; 3526a3bb6f32SFande Kong PetscErrorCode ierr; 3527a3bb6f32SFande Kong 3528a3bb6f32SFande Kong PetscFunctionBegin; 3529a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3530a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3531a3bb6f32SFande Kong /* use a table */ 3532a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3533a3bb6f32SFande Kong ec = 0; 3534a3bb6f32SFande Kong for (i=0; i<mat->rmap->n; i++) { 3535a3bb6f32SFande Kong ncols = aij->i[i+1] - aij->i[i]; 3536a3bb6f32SFande Kong for (j=0; j<ncols; j++) { 3537a3bb6f32SFande Kong PetscInt data,gid1 = aij->j[aij->i[i] + j] + 1; 3538a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3539a3bb6f32SFande Kong if (!data) { 3540a3bb6f32SFande Kong /* one based table */ 3541a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3542a3bb6f32SFande Kong } 3543a3bb6f32SFande Kong } 3544a3bb6f32SFande Kong } 3545a3bb6f32SFande Kong /* form array of columns we need */ 3546a3bb6f32SFande Kong ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); 3547a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3548a3bb6f32SFande Kong while (tpos) { 3549a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3550a3bb6f32SFande Kong gid--; 3551a3bb6f32SFande Kong lid--; 3552a3bb6f32SFande Kong garray[lid] = gid; 3553a3bb6f32SFande Kong } 3554a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3555a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3556a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3557a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3558a3bb6f32SFande Kong } 3559a3bb6f32SFande Kong /* compact out the extra columns in B */ 3560a3bb6f32SFande Kong for (i=0; i<mat->rmap->n; i++) { 3561a3bb6f32SFande Kong ncols = aij->i[i+1] - aij->i[i]; 3562a3bb6f32SFande Kong for (j=0; j<ncols; j++) { 3563a3bb6f32SFande Kong PetscInt gid1 = aij->j[aij->i[i] + j] + 1; 3564a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3565a3bb6f32SFande Kong lid--; 3566a3bb6f32SFande Kong aij->j[aij->i[i] + j] = lid; 3567a3bb6f32SFande Kong } 3568a3bb6f32SFande Kong } 3569ca5434daSLawrence Mitchell ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 3570ca5434daSLawrence Mitchell ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr); 3571a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 3572a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3573a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3574a3bb6f32SFande Kong PetscFunctionReturn(0); 3575a3bb6f32SFande Kong } 3576a3bb6f32SFande Kong 3577bef8e0ddSBarry Smith /*@ 3578bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3579bef8e0ddSBarry Smith in the matrix. 3580bef8e0ddSBarry Smith 3581bef8e0ddSBarry Smith Input Parameters: 3582bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3583bef8e0ddSBarry Smith - indices - the column indices 3584bef8e0ddSBarry Smith 358515091d37SBarry Smith Level: advanced 358615091d37SBarry Smith 3587bef8e0ddSBarry Smith Notes: 3588bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3589bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3590bef8e0ddSBarry Smith of the MatSetValues() operation. 3591bef8e0ddSBarry Smith 3592bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3593d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3594bef8e0ddSBarry Smith 3595bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3596bef8e0ddSBarry Smith 3597b9617806SBarry Smith The indices should start with zero, not one. 3598b9617806SBarry Smith 3599bef8e0ddSBarry Smith @*/ 36007087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3601bef8e0ddSBarry Smith { 36024ac538c5SBarry Smith PetscErrorCode ierr; 3603bef8e0ddSBarry Smith 3604bef8e0ddSBarry Smith PetscFunctionBegin; 36050700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 36064482741eSBarry Smith PetscValidPointer(indices,2); 36074ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3608bef8e0ddSBarry Smith PetscFunctionReturn(0); 3609bef8e0ddSBarry Smith } 3610bef8e0ddSBarry Smith 3611be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3612be6bf707SBarry Smith 36137087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3614be6bf707SBarry Smith { 3615be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 36166849ba73SBarry Smith PetscErrorCode ierr; 3617d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3618be6bf707SBarry Smith 3619be6bf707SBarry Smith PetscFunctionBegin; 3620169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3621be6bf707SBarry Smith 3622be6bf707SBarry Smith /* allocate space for values if not already there */ 3623be6bf707SBarry Smith if (!aij->saved_values) { 3624854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 36253bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3626be6bf707SBarry Smith } 3627be6bf707SBarry Smith 3628be6bf707SBarry Smith /* copy values over */ 3629580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3630be6bf707SBarry Smith PetscFunctionReturn(0); 3631be6bf707SBarry Smith } 3632be6bf707SBarry Smith 3633be6bf707SBarry Smith /*@ 3634be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3635be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3636be6bf707SBarry Smith nonlinear portion. 3637be6bf707SBarry Smith 3638be6bf707SBarry Smith Collect on Mat 3639be6bf707SBarry Smith 3640be6bf707SBarry Smith Input Parameters: 36410e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3642be6bf707SBarry Smith 364315091d37SBarry Smith Level: advanced 364415091d37SBarry Smith 3645be6bf707SBarry Smith Common Usage, with SNESSolve(): 3646be6bf707SBarry Smith $ Create Jacobian matrix 3647be6bf707SBarry Smith $ Set linear terms into matrix 3648be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3649be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3650be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3651512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3652be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3653be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3654be6bf707SBarry Smith $ In your Jacobian routine 3655be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3656be6bf707SBarry Smith $ Set nonlinear terms in matrix 3657be6bf707SBarry Smith 3658be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3659be6bf707SBarry Smith $ // build linear portion of Jacobian 3660512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3661be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3662be6bf707SBarry Smith $ loop over nonlinear iterations 3663be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3664be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3665be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3666be6bf707SBarry Smith $ Solve linear system with Jacobian 3667be6bf707SBarry Smith $ endloop 3668be6bf707SBarry Smith 3669be6bf707SBarry Smith Notes: 3670be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3671512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3672be6bf707SBarry Smith calling this routine. 3673be6bf707SBarry Smith 36740c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 36750c468ba9SBarry Smith and does not allocated additional space. 36760c468ba9SBarry Smith 3677be6bf707SBarry Smith .seealso: MatRetrieveValues() 3678be6bf707SBarry Smith 3679be6bf707SBarry Smith @*/ 36807087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3681be6bf707SBarry Smith { 36824ac538c5SBarry Smith PetscErrorCode ierr; 3683be6bf707SBarry Smith 3684be6bf707SBarry Smith PetscFunctionBegin; 36850700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3686e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3687e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 36884ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3689be6bf707SBarry Smith PetscFunctionReturn(0); 3690be6bf707SBarry Smith } 3691be6bf707SBarry Smith 36927087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3693be6bf707SBarry Smith { 3694be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 36956849ba73SBarry Smith PetscErrorCode ierr; 3696d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3697be6bf707SBarry Smith 3698be6bf707SBarry Smith PetscFunctionBegin; 3699169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3700f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3701be6bf707SBarry Smith /* copy values over */ 3702580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3703be6bf707SBarry Smith PetscFunctionReturn(0); 3704be6bf707SBarry Smith } 3705be6bf707SBarry Smith 3706be6bf707SBarry Smith /*@ 3707be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3708be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3709be6bf707SBarry Smith nonlinear portion. 3710be6bf707SBarry Smith 3711be6bf707SBarry Smith Collect on Mat 3712be6bf707SBarry Smith 3713be6bf707SBarry Smith Input Parameters: 3714386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3715be6bf707SBarry Smith 371615091d37SBarry Smith Level: advanced 371715091d37SBarry Smith 3718be6bf707SBarry Smith .seealso: MatStoreValues() 3719be6bf707SBarry Smith 3720be6bf707SBarry Smith @*/ 37217087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3722be6bf707SBarry Smith { 37234ac538c5SBarry Smith PetscErrorCode ierr; 3724be6bf707SBarry Smith 3725be6bf707SBarry Smith PetscFunctionBegin; 37260700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3727e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3728e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 37294ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3730be6bf707SBarry Smith PetscFunctionReturn(0); 3731be6bf707SBarry Smith } 3732be6bf707SBarry Smith 3733f83d6046SBarry Smith 3734be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 373517ab2063SBarry Smith /*@C 3736682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 37370d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 37386e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 373951c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 37402bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 374117ab2063SBarry Smith 3742d083f849SBarry Smith Collective 3743db81eaa0SLois Curfman McInnes 374417ab2063SBarry Smith Input Parameters: 3745db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 374617ab2063SBarry Smith . m - number of rows 374717ab2063SBarry Smith . n - number of columns 374817ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 374951c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 37500298fd71SBarry Smith (possibly different for each row) or NULL 375117ab2063SBarry Smith 375217ab2063SBarry Smith Output Parameter: 3753416022c9SBarry Smith . A - the matrix 375417ab2063SBarry Smith 3755175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3756f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3757175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3758175b88e8SBarry Smith 3759b259b22eSLois Curfman McInnes Notes: 376049a6f317SBarry Smith If nnz is given then nz is ignored 376149a6f317SBarry Smith 376217ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 376317ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 37640002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 376544cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 376617ab2063SBarry Smith 376717ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 37680298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 37693d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 37706da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 377117ab2063SBarry Smith 3772682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 37734fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3774682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 37756c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 37766c7ebb05SLois Curfman McInnes 37776c7ebb05SLois Curfman McInnes Options Database Keys: 3778698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 37799db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 378017ab2063SBarry Smith 3781027ccd11SLois Curfman McInnes Level: intermediate 3782027ccd11SLois Curfman McInnes 378369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 378436db0b34SBarry Smith 378517ab2063SBarry Smith @*/ 37867087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 378717ab2063SBarry Smith { 3788dfbe8321SBarry Smith PetscErrorCode ierr; 37896945ee14SBarry Smith 37903a40ed3dSBarry Smith PetscFunctionBegin; 3791f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3792117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3793c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3794d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3795273d9f13SBarry Smith PetscFunctionReturn(0); 3796273d9f13SBarry Smith } 3797273d9f13SBarry Smith 3798273d9f13SBarry Smith /*@C 3799273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3800273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3801273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3802273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3803273d9f13SBarry Smith 3804d083f849SBarry Smith Collective 3805273d9f13SBarry Smith 3806273d9f13SBarry Smith Input Parameters: 38071c4f3114SJed Brown + B - The matrix 3808273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3809273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 38100298fd71SBarry Smith (possibly different for each row) or NULL 3811273d9f13SBarry Smith 3812273d9f13SBarry Smith Notes: 381349a6f317SBarry Smith If nnz is given then nz is ignored 381449a6f317SBarry Smith 3815273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3816273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3817273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3818273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3819273d9f13SBarry Smith 3820273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 38210298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3822273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3823273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3824273d9f13SBarry Smith 3825aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3826aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3827aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3828aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3829aa95bbe8SBarry Smith 3830a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3831a96a251dSBarry Smith entries or columns indices 3832a96a251dSBarry Smith 3833273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3834273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3835273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3836273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3837273d9f13SBarry Smith 3838273d9f13SBarry Smith Options Database Keys: 3839698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 384047b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3841273d9f13SBarry Smith 3842273d9f13SBarry Smith Level: intermediate 3843273d9f13SBarry Smith 384469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3845273d9f13SBarry Smith 3846273d9f13SBarry Smith @*/ 38477087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3848273d9f13SBarry Smith { 38494ac538c5SBarry Smith PetscErrorCode ierr; 3850a23d5eceSKris Buschelman 3851a23d5eceSKris Buschelman PetscFunctionBegin; 38526ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 38536ba663aaSJed Brown PetscValidType(B,1); 38544ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3855a23d5eceSKris Buschelman PetscFunctionReturn(0); 3856a23d5eceSKris Buschelman } 3857a23d5eceSKris Buschelman 38587087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3859a23d5eceSKris Buschelman { 3860273d9f13SBarry Smith Mat_SeqAIJ *b; 38612576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 38626849ba73SBarry Smith PetscErrorCode ierr; 386397f1f81fSBarry Smith PetscInt i; 3864273d9f13SBarry Smith 3865273d9f13SBarry Smith PetscFunctionBegin; 38662576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3867a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3868c461c341SBarry Smith skipallocation = PETSC_TRUE; 3869c461c341SBarry Smith nz = 0; 3870c461c341SBarry Smith } 387126283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 387226283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3873899cda47SBarry Smith 3874435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 387560e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 3876071fcb05SBarry Smith #if defined(PETSC_USE_DEBUG) 3877b73539f3SBarry Smith if (nnz) { 3878d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 387960e0710aSBarry 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]); 388060e0710aSBarry 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); 3881b73539f3SBarry Smith } 3882b73539f3SBarry Smith } 3883071fcb05SBarry Smith #endif 3884b73539f3SBarry Smith 3885273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 38862205254eSKarl Rupp 3887273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3888273d9f13SBarry Smith 3889ab93d7beSBarry Smith if (!skipallocation) { 38902ee49352SLisandro Dalcin if (!b->imax) { 3891071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 3892071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 3893071fcb05SBarry Smith } 3894071fcb05SBarry Smith if (!b->ilen) { 3895071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 3896071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 3897071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 3898071fcb05SBarry Smith } else { 3899071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 39002ee49352SLisandro Dalcin } 3901846b4da1SFande Kong if (!b->ipre) { 3902846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 3903846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 3904846b4da1SFande Kong } 3905273d9f13SBarry Smith if (!nnz) { 3906435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3907c62bd62aSJed Brown else if (nz < 0) nz = 1; 39085d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 3909d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3910d0f46423SBarry Smith nz = nz*B->rmap->n; 3911273d9f13SBarry Smith } else { 3912c73702f5SBarry Smith PetscInt64 nz64 = 0; 3913c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 3914c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 3915273d9f13SBarry Smith } 3916ab93d7beSBarry Smith 3917273d9f13SBarry Smith /* allocate the matrix space */ 391853dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 39192ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3920396832f4SHong Zhang if (B->structure_only) { 39215848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 39225848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 3923396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 3924396832f4SHong Zhang } else { 3925dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 39263bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3927396832f4SHong Zhang } 3928bfeeae90SHong Zhang b->i[0] = 0; 3929d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 39305da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 39315da197adSKris Buschelman } 3932396832f4SHong Zhang if (B->structure_only) { 3933396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 3934396832f4SHong Zhang b->free_a = PETSC_FALSE; 3935396832f4SHong Zhang } else { 3936273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3937e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3938396832f4SHong Zhang } 3939e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3940c461c341SBarry Smith } else { 3941e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3942e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3943c461c341SBarry Smith } 3944273d9f13SBarry Smith 3945846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 3946846b4da1SFande Kong /* reserve user-requested sparsity */ 3947580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 3948846b4da1SFande Kong } 3949846b4da1SFande Kong 3950846b4da1SFande Kong 3951273d9f13SBarry Smith b->nz = 0; 3952273d9f13SBarry Smith b->maxnz = nz; 3953273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 39542205254eSKarl Rupp if (realalloc) { 39552205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 39562205254eSKarl Rupp } 3957cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 3958cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 3959273d9f13SBarry Smith PetscFunctionReturn(0); 3960273d9f13SBarry Smith } 3961273d9f13SBarry Smith 3962846b4da1SFande Kong 3963846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 3964846b4da1SFande Kong { 3965846b4da1SFande Kong Mat_SeqAIJ *a; 3966a5bbaf83SFande Kong PetscInt i; 3967846b4da1SFande Kong PetscErrorCode ierr; 3968846b4da1SFande Kong 3969846b4da1SFande Kong PetscFunctionBegin; 3970846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 397114d0e64fSAlex Lindsay 397214d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 397314d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 397414d0e64fSAlex Lindsay 3975846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 39762c814fdeSFande Kong /* if no saved info, we error out */ 3977fb4dc15dSAlex Lindsay if (!a->ipre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 39782c814fdeSFande Kong 3979fb4dc15dSAlex 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"); 39802c814fdeSFande Kong 3981580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 3982580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 3983846b4da1SFande Kong a->i[0] = 0; 3984846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 3985846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 3986846b4da1SFande Kong } 3987846b4da1SFande Kong A->preallocated = PETSC_TRUE; 3988846b4da1SFande Kong a->nz = 0; 3989846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 3990846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 3991846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 3992846b4da1SFande Kong A->assembled = PETSC_FALSE; 3993846b4da1SFande Kong PetscFunctionReturn(0); 3994846b4da1SFande Kong } 3995846b4da1SFande Kong 399658d36128SBarry Smith /*@ 3997a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3998a1661176SMatthew Knepley 3999a1661176SMatthew Knepley Input Parameters: 4000a1661176SMatthew Knepley + B - the matrix 4001a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4002a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4003a1661176SMatthew Knepley - v - optional values in the matrix 4004a1661176SMatthew Knepley 4005a1661176SMatthew Knepley Level: developer 4006a1661176SMatthew Knepley 400758d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 400858d36128SBarry Smith 4009c1c1d628SHong Zhang .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ 4010a1661176SMatthew Knepley @*/ 4011a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4012a1661176SMatthew Knepley { 4013a1661176SMatthew Knepley PetscErrorCode ierr; 4014a1661176SMatthew Knepley 4015a1661176SMatthew Knepley PetscFunctionBegin; 40160700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 40176ba663aaSJed Brown PetscValidType(B,1); 40184ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 4019a1661176SMatthew Knepley PetscFunctionReturn(0); 4020a1661176SMatthew Knepley } 4021a1661176SMatthew Knepley 40227087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4023a1661176SMatthew Knepley { 4024a1661176SMatthew Knepley PetscInt i; 4025a1661176SMatthew Knepley PetscInt m,n; 4026a1661176SMatthew Knepley PetscInt nz; 4027a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 4028a1661176SMatthew Knepley PetscErrorCode ierr; 4029a1661176SMatthew Knepley 4030a1661176SMatthew Knepley PetscFunctionBegin; 403165e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4032779a8d59SSatish Balay 4033779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4034779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4035779a8d59SSatish Balay 4036779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4037854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 4038a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4039b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 4040a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 404165e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4042a1661176SMatthew Knepley nnz[i] = nz; 4043a1661176SMatthew Knepley } 4044a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4045a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4046a1661176SMatthew Knepley 4047a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4048071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 4049a1661176SMatthew Knepley } 4050a1661176SMatthew Knepley 4051a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4052a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4053a1661176SMatthew Knepley 40547827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4055a1661176SMatthew Knepley PetscFunctionReturn(0); 4056a1661176SMatthew Knepley } 4057a1661176SMatthew Knepley 4058c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4059af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4060170fe5c8SBarry Smith 4061170fe5c8SBarry Smith /* 4062170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4063170fe5c8SBarry Smith 4064170fe5c8SBarry Smith n p p 4065170fe5c8SBarry Smith ( ) ( ) ( ) 4066170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 4067170fe5c8SBarry Smith ( ) ( ) ( ) 4068170fe5c8SBarry Smith 4069170fe5c8SBarry Smith */ 4070170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4071170fe5c8SBarry Smith { 4072170fe5c8SBarry Smith PetscErrorCode ierr; 4073170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4074170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4075170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 40761de00fd4SBarry Smith PetscInt i,n,m,q,p; 4077170fe5c8SBarry Smith const PetscInt *ii,*idx; 4078170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4079170fe5c8SBarry Smith PetscScalar *c,*c_q; 4080170fe5c8SBarry Smith 4081170fe5c8SBarry Smith PetscFunctionBegin; 4082d0f46423SBarry Smith m = A->rmap->n; 4083d0f46423SBarry Smith n = A->cmap->n; 4084d0f46423SBarry Smith p = B->cmap->n; 4085170fe5c8SBarry Smith a = sub_a->v; 4086170fe5c8SBarry Smith b = sub_b->a; 4087170fe5c8SBarry Smith c = sub_c->v; 4088580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 4089170fe5c8SBarry Smith 4090170fe5c8SBarry Smith ii = sub_b->i; 4091170fe5c8SBarry Smith idx = sub_b->j; 4092170fe5c8SBarry Smith for (i=0; i<n; i++) { 4093170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4094170fe5c8SBarry Smith while (q-->0) { 4095170fe5c8SBarry Smith c_q = c + m*(*idx); 4096170fe5c8SBarry Smith a_q = a + m*i; 4097854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4098170fe5c8SBarry Smith idx++; 4099170fe5c8SBarry Smith b++; 4100170fe5c8SBarry Smith } 4101170fe5c8SBarry Smith } 4102170fe5c8SBarry Smith PetscFunctionReturn(0); 4103170fe5c8SBarry Smith } 4104170fe5c8SBarry Smith 4105170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 4106170fe5c8SBarry Smith { 4107170fe5c8SBarry Smith PetscErrorCode ierr; 4108d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 4109170fe5c8SBarry Smith Mat Cmat; 4110170fe5c8SBarry Smith 4111170fe5c8SBarry Smith PetscFunctionBegin; 411260e0710aSBarry 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); 4113ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 4114170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 411533d57670SJed Brown ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr); 4116170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 41170298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 4118d73949e8SHong Zhang 4119d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 41202205254eSKarl Rupp 4121170fe5c8SBarry Smith *C = Cmat; 4122170fe5c8SBarry Smith PetscFunctionReturn(0); 4123170fe5c8SBarry Smith } 4124170fe5c8SBarry Smith 4125170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 4126150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 4127170fe5c8SBarry Smith { 4128170fe5c8SBarry Smith PetscErrorCode ierr; 4129170fe5c8SBarry Smith 4130170fe5c8SBarry Smith PetscFunctionBegin; 4131170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 41323ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 4133170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 41343ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 4135170fe5c8SBarry Smith } 41363ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 4137170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 41383ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 4139170fe5c8SBarry Smith PetscFunctionReturn(0); 4140170fe5c8SBarry Smith } 4141170fe5c8SBarry Smith 4142170fe5c8SBarry Smith 41430bad9183SKris Buschelman /*MC 4144fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 41450bad9183SKris Buschelman based on compressed sparse row format. 41460bad9183SKris Buschelman 41470bad9183SKris Buschelman Options Database Keys: 41480bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 41490bad9183SKris Buschelman 41500bad9183SKris Buschelman Level: beginner 41510bad9183SKris Buschelman 41520cd7f59aSBarry Smith Notes: 41530cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 41540cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 41550cd7f59aSBarry Smith in the matrix 41560cd7f59aSBarry Smith 41570cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 41580cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 41590cd7f59aSBarry Smith 41600cd7f59aSBarry Smith Developer Notes: 41610cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 41620cd7f59aSBarry Smith 4163f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 41640bad9183SKris Buschelman M*/ 41650bad9183SKris Buschelman 4166ccd284c7SBarry Smith /*MC 4167ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4168ccd284c7SBarry Smith 4169ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4170ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 41710cd7f59aSBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation() is supported 4172ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4173ccd284c7SBarry Smith the above preallocation routines for simplicity. 4174ccd284c7SBarry Smith 4175ccd284c7SBarry Smith Options Database Keys: 4176ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4177ccd284c7SBarry Smith 417895452b02SPatrick Sanan Developer Notes: 4179ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4180ccd284c7SBarry Smith enough exist. 4181ccd284c7SBarry Smith 4182ccd284c7SBarry Smith Level: beginner 4183ccd284c7SBarry Smith 4184ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4185ccd284c7SBarry Smith M*/ 4186ccd284c7SBarry Smith 4187ccd284c7SBarry Smith /*MC 4188ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4189ccd284c7SBarry Smith 4190ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4191ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4192ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4193ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4194ccd284c7SBarry Smith the above preallocation routines for simplicity. 4195ccd284c7SBarry Smith 4196ccd284c7SBarry Smith Options Database Keys: 4197ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4198ccd284c7SBarry Smith 4199ccd284c7SBarry Smith Level: beginner 4200ccd284c7SBarry Smith 4201ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4202ccd284c7SBarry Smith M*/ 4203ccd284c7SBarry Smith 42047906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 42057906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 42067906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 42077906f579SHong Zhang #endif 42087906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 42097906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 42107906f579SHong Zhang PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 42117906f579SHong Zhang #endif 42127906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 42137906f579SHong Zhang 4214d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4215c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 421675d48cdbSStefano Zampini PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat,Mat,MatReuse,PetscReal,Mat*); 42177906f579SHong Zhang 42188c778c55SBarry Smith /*@C 42198f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 42208c778c55SBarry Smith 42218c778c55SBarry Smith Not Collective 42228c778c55SBarry Smith 42238c778c55SBarry Smith Input Parameter: 4224579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 42258c778c55SBarry Smith 42268c778c55SBarry Smith Output Parameter: 42278c778c55SBarry Smith . array - pointer to the data 42288c778c55SBarry Smith 42298c778c55SBarry Smith Level: intermediate 42308c778c55SBarry Smith 4231774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 42328c778c55SBarry Smith @*/ 42338c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 42348c778c55SBarry Smith { 42358c778c55SBarry Smith PetscErrorCode ierr; 42368c778c55SBarry Smith 42378c778c55SBarry Smith PetscFunctionBegin; 42388c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 42398c778c55SBarry Smith PetscFunctionReturn(0); 42408c778c55SBarry Smith } 42418c778c55SBarry Smith 424221e72a00SBarry Smith /*@C 42438f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 42448f1ea47aSStefano Zampini 42458f1ea47aSStefano Zampini Not Collective 42468f1ea47aSStefano Zampini 42478f1ea47aSStefano Zampini Input Parameter: 42488f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 42498f1ea47aSStefano Zampini 42508f1ea47aSStefano Zampini Output Parameter: 42518f1ea47aSStefano Zampini . array - pointer to the data 42528f1ea47aSStefano Zampini 42538f1ea47aSStefano Zampini Level: intermediate 42548f1ea47aSStefano Zampini 42558f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 42568f1ea47aSStefano Zampini @*/ 42578f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 42588f1ea47aSStefano Zampini { 42598f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4260*c70f7ee4SJunchao Zhang PetscOffloadMask oval; 42618f1ea47aSStefano Zampini #endif 42628f1ea47aSStefano Zampini PetscErrorCode ierr; 42638f1ea47aSStefano Zampini 42648f1ea47aSStefano Zampini PetscFunctionBegin; 42658f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4266*c70f7ee4SJunchao Zhang oval = A->offloadmask; 42678f1ea47aSStefano Zampini #endif 42688f1ea47aSStefano Zampini ierr = MatSeqAIJGetArray(A,(PetscScalar**)array);CHKERRQ(ierr); 42698f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4270*c70f7ee4SJunchao Zhang if (oval == PETSC_OFFLOAD_GPU || oval == PETSC_OFFLOAD_BOTH) A->offloadmask = PETSC_OFFLOAD_BOTH; 42718f1ea47aSStefano Zampini #endif 42728f1ea47aSStefano Zampini PetscFunctionReturn(0); 42738f1ea47aSStefano Zampini } 42748f1ea47aSStefano Zampini 42758f1ea47aSStefano Zampini /*@C 42768f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 42778f1ea47aSStefano Zampini 42788f1ea47aSStefano Zampini Not Collective 42798f1ea47aSStefano Zampini 42808f1ea47aSStefano Zampini Input Parameter: 42818f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 42828f1ea47aSStefano Zampini 42838f1ea47aSStefano Zampini Output Parameter: 42848f1ea47aSStefano Zampini . array - pointer to the data 42858f1ea47aSStefano Zampini 42868f1ea47aSStefano Zampini Level: intermediate 42878f1ea47aSStefano Zampini 42888f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 42898f1ea47aSStefano Zampini @*/ 42908f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 42918f1ea47aSStefano Zampini { 42928f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4293*c70f7ee4SJunchao Zhang PetscOffloadMask oval; 42948f1ea47aSStefano Zampini #endif 42958f1ea47aSStefano Zampini PetscErrorCode ierr; 42968f1ea47aSStefano Zampini 42978f1ea47aSStefano Zampini PetscFunctionBegin; 42988f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4299*c70f7ee4SJunchao Zhang oval = A->offloadmask; 43008f1ea47aSStefano Zampini #endif 43018f1ea47aSStefano Zampini ierr = MatSeqAIJRestoreArray(A,(PetscScalar**)array);CHKERRQ(ierr); 43028f1ea47aSStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 4303*c70f7ee4SJunchao Zhang A->offloadmask = oval; 43048f1ea47aSStefano Zampini #endif 43058f1ea47aSStefano Zampini PetscFunctionReturn(0); 43068f1ea47aSStefano Zampini } 43078f1ea47aSStefano Zampini 43088f1ea47aSStefano Zampini /*@C 430921e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 431021e72a00SBarry Smith 431121e72a00SBarry Smith Not Collective 431221e72a00SBarry Smith 431321e72a00SBarry Smith Input Parameter: 4314579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 431521e72a00SBarry Smith 431621e72a00SBarry Smith Output Parameter: 431721e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 431821e72a00SBarry Smith 431921e72a00SBarry Smith Level: intermediate 432021e72a00SBarry Smith 432121e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 432221e72a00SBarry Smith @*/ 432321e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 432421e72a00SBarry Smith { 432521e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 432621e72a00SBarry Smith 432721e72a00SBarry Smith PetscFunctionBegin; 432821e72a00SBarry Smith *nz = aij->rmax; 432921e72a00SBarry Smith PetscFunctionReturn(0); 433021e72a00SBarry Smith } 433121e72a00SBarry Smith 43328c778c55SBarry Smith /*@C 4333579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 43348c778c55SBarry Smith 43358c778c55SBarry Smith Not Collective 43368c778c55SBarry Smith 43378c778c55SBarry Smith Input Parameters: 4338a2b725a8SWilliam Gropp + mat - a MATSEQAIJ matrix 4339a2b725a8SWilliam Gropp - array - pointer to the data 43408c778c55SBarry Smith 43418c778c55SBarry Smith Level: intermediate 43428c778c55SBarry Smith 4343774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 43448c778c55SBarry Smith @*/ 43458c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 43468c778c55SBarry Smith { 43478c778c55SBarry Smith PetscErrorCode ierr; 43488c778c55SBarry Smith 43498c778c55SBarry Smith PetscFunctionBegin; 43508c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 43518c778c55SBarry Smith PetscFunctionReturn(0); 43528c778c55SBarry Smith } 43538c778c55SBarry Smith 435434b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 435502fe1965SBarry Smith PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat); 435602fe1965SBarry Smith #endif 435702fe1965SBarry Smith 43588cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4359273d9f13SBarry Smith { 4360273d9f13SBarry Smith Mat_SeqAIJ *b; 4361dfbe8321SBarry Smith PetscErrorCode ierr; 436238baddfdSBarry Smith PetscMPIInt size; 4363273d9f13SBarry Smith 4364273d9f13SBarry Smith PetscFunctionBegin; 4365ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 4366e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4367273d9f13SBarry Smith 4368b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 43692205254eSKarl Rupp 4370b0a32e0cSBarry Smith B->data = (void*)b; 43712205254eSKarl Rupp 4372549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4373071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 43742205254eSKarl Rupp 4375416022c9SBarry Smith b->row = 0; 4376416022c9SBarry Smith b->col = 0; 437782bf6240SBarry Smith b->icol = 0; 4378b810aeb4SBarry Smith b->reallocs = 0; 437936db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4380f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4381416022c9SBarry Smith b->nonew = 0; 4382416022c9SBarry Smith b->diag = 0; 4383416022c9SBarry Smith b->solve_work = 0; 43842a1b7f2aSHong Zhang B->spptr = 0; 4385be6bf707SBarry Smith b->saved_values = 0; 4386d7f994e1SBarry Smith b->idiag = 0; 438771f1c65dSBarry Smith b->mdiag = 0; 438871f1c65dSBarry Smith b->ssor_work = 0; 438971f1c65dSBarry Smith b->omega = 1.0; 439071f1c65dSBarry Smith b->fshift = 0.0; 439171f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4392bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4393a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 439417ab2063SBarry Smith 439535d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4396bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4397bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 43988c778c55SBarry Smith 4399b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4400bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4401bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4402b3866ffcSBarry Smith #endif 440317f1a0eaSHong Zhang 4404bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4405bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4406bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4407bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4408bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4409bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 44104dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 44119779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 44124a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4413191b95cbSRichard Tran Mills #endif 441434b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 441502fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 441602fe1965SBarry Smith #endif 4417bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4418af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4419af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4420af8000cdSHong Zhang #endif 442163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 442263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 44233dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr); 442463c07aadSStefano Zampini #endif 4425b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4426d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4427c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4428bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4429bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4430bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4431846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4432bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4433bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 4434bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 4435bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 4436bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 443775d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_is_seqaij_C",MatPtAP_IS_XAIJ);CHKERRQ(ierr); 44384108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 443917667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 44404099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 44413a40ed3dSBarry Smith PetscFunctionReturn(0); 444217ab2063SBarry Smith } 444317ab2063SBarry Smith 4444b24902e0SBarry Smith /* 4445b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4446b24902e0SBarry Smith */ 4447ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 444817ab2063SBarry Smith { 4449416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 44506849ba73SBarry Smith PetscErrorCode ierr; 4451071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 445217ab2063SBarry Smith 44533a40ed3dSBarry Smith PetscFunctionBegin; 4454273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 4455273d9f13SBarry Smith 4456d5f3da31SBarry Smith C->factortype = A->factortype; 4457416022c9SBarry Smith c->row = 0; 4458416022c9SBarry Smith c->col = 0; 445982bf6240SBarry Smith c->icol = 0; 44606ad4291fSHong Zhang c->reallocs = 0; 446117ab2063SBarry Smith 44626ad4291fSHong Zhang C->assembled = PETSC_TRUE; 446317ab2063SBarry Smith 4464aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4465aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4466eec197d1SBarry Smith 4467071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4468071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4469071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4470071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 44713bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 447217ab2063SBarry Smith 447317ab2063SBarry Smith /* allocate the matrix space */ 4474f77e22a1SHong Zhang if (mallocmatspace) { 4475dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 44763bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 44772205254eSKarl Rupp 4478f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 44792205254eSKarl Rupp 4480580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 448117ab2063SBarry Smith if (m > 0) { 4482580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4483be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 4484580bdb30SBarry Smith ierr = PetscArraycpy(c->a,a->a,a->i[m]);CHKERRQ(ierr); 4485be6bf707SBarry Smith } else { 4486580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 448717ab2063SBarry Smith } 448808480c60SBarry Smith } 4489f77e22a1SHong Zhang } 449017ab2063SBarry Smith 44916ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4492416022c9SBarry Smith c->roworiented = a->roworiented; 4493416022c9SBarry Smith c->nonew = a->nonew; 4494416022c9SBarry Smith if (a->diag) { 4495854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4496071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 44973bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4498071fcb05SBarry Smith } else c->diag = NULL; 44992205254eSKarl Rupp 45006ad4291fSHong Zhang c->solve_work = 0; 45016ad4291fSHong Zhang c->saved_values = 0; 45026ad4291fSHong Zhang c->idiag = 0; 450371f1c65dSBarry Smith c->ssor_work = 0; 4504a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4505e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4506e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 45076ad4291fSHong Zhang 4508893ad86cSHong Zhang c->rmax = a->rmax; 4509416022c9SBarry Smith c->nz = a->nz; 45108ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4511273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4512754ec7b1SSatish Balay 45136ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 45146ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4515cd6b891eSBarry Smith if (a->compressedrow.use) { 45166ad4291fSHong Zhang i = a->compressedrow.nrows; 4517dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4518580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4519580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 452027ea64f8SHong Zhang } else { 452127ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 45220298fd71SBarry Smith c->compressedrow.i = NULL; 45230298fd71SBarry Smith c->compressedrow.rindex = NULL; 45246ad4291fSHong Zhang } 4525ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4526e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 45274846f1f5SKris Buschelman 45282205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4529140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 45303a40ed3dSBarry Smith PetscFunctionReturn(0); 453117ab2063SBarry Smith } 453217ab2063SBarry Smith 4533b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4534b24902e0SBarry Smith { 4535b24902e0SBarry Smith PetscErrorCode ierr; 4536b24902e0SBarry Smith 4537b24902e0SBarry Smith PetscFunctionBegin; 4538ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 45394b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4540cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 454133d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4542cfd3f464SBarry Smith } 4543a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4544f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4545b24902e0SBarry Smith PetscFunctionReturn(0); 4546b24902e0SBarry Smith } 4547b24902e0SBarry Smith 4548112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4549fbdbba38SShri Abhyankar { 455052f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 455152f91c60SVaclav Hapla PetscErrorCode ierr; 455252f91c60SVaclav Hapla 455352f91c60SVaclav Hapla PetscFunctionBegin; 455452f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 455552f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4556c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4557c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 455852f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 455952f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 456052f91c60SVaclav Hapla if (isbinary) { 456152f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 456252f91c60SVaclav Hapla } else if (ishdf5) { 456352f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 456452f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 456552f91c60SVaclav Hapla #else 456652f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 456752f91c60SVaclav Hapla #endif 456852f91c60SVaclav Hapla } else { 456952f91c60SVaclav 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); 457052f91c60SVaclav Hapla } 457152f91c60SVaclav Hapla PetscFunctionReturn(0); 457252f91c60SVaclav Hapla } 457352f91c60SVaclav Hapla 457452f91c60SVaclav Hapla PetscErrorCode MatLoad_SeqAIJ_Binary(Mat newMat, PetscViewer viewer) 457552f91c60SVaclav Hapla { 4576fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4577fbdbba38SShri Abhyankar PetscErrorCode ierr; 4578fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4579fbdbba38SShri Abhyankar int fd; 4580fbdbba38SShri Abhyankar PetscMPIInt size; 4581fbdbba38SShri Abhyankar MPI_Comm comm; 45823059b6faSBarry Smith PetscInt bs = newMat->rmap->bs; 4583fbdbba38SShri Abhyankar 4584fbdbba38SShri Abhyankar PetscFunctionBegin; 4585fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4586fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4587fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4588bbead8a2SBarry Smith 45890298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 45900298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4591bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 45923059b6faSBarry Smith if (bs < 0) bs = 1; 45933059b6faSBarry Smith ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr); 4594bbead8a2SBarry Smith 4595fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 45969860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 4597fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4598fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4599fbdbba38SShri Abhyankar 4600bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4601fbdbba38SShri Abhyankar 4602fbdbba38SShri Abhyankar /* read in row lengths */ 4603785e854fSJed Brown ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr); 46049860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,rowlengths,M,NULL,PETSC_INT);CHKERRQ(ierr); 4605fbdbba38SShri Abhyankar 4606fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4607fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 460860e0710aSBarry Smith if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %dD, sum-row-lengths = %D\n",nz,sum); 4609fbdbba38SShri Abhyankar 4610fbdbba38SShri Abhyankar /* set global size if not set already*/ 4611f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4612fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4613aabbc4fbSShri Abhyankar } else { 46149d36ed5fSBarry Smith /* if sizes and type are already set, check if the matrix global sizes are correct */ 4615fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 46164c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 46174c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 46184c5b953cSHong Zhang } 461960e0710aSBarry 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); 4620aabbc4fbSShri Abhyankar } 4621fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4622fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4623fbdbba38SShri Abhyankar 46249860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 4625fbdbba38SShri Abhyankar 4626fbdbba38SShri Abhyankar /* read in nonzero values */ 46279860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4628fbdbba38SShri Abhyankar 4629fbdbba38SShri Abhyankar /* set matrix "i" values */ 4630fbdbba38SShri Abhyankar a->i[0] = 0; 4631fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4632fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4633fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4634fbdbba38SShri Abhyankar } 4635fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4636fbdbba38SShri Abhyankar 4637fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4638fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4639fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4640fbdbba38SShri Abhyankar } 4641fbdbba38SShri Abhyankar 4642ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 46437264ac53SSatish Balay { 46447264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4645dfbe8321SBarry Smith PetscErrorCode ierr; 4646eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4647eeffb40dSHong Zhang PetscInt k; 4648eeffb40dSHong Zhang #endif 46497264ac53SSatish Balay 46503a40ed3dSBarry Smith PetscFunctionBegin; 4651bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4652d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4653ca44d042SBarry Smith *flg = PETSC_FALSE; 4654ca44d042SBarry Smith PetscFunctionReturn(0); 4655bcd2baecSBarry Smith } 46567264ac53SSatish Balay 46577264ac53SSatish Balay /* if the a->i are the same */ 4658580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4659abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 46607264ac53SSatish Balay 46617264ac53SSatish Balay /* if a->j are the same */ 4662580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 4663abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4664bcd2baecSBarry Smith 4665bcd2baecSBarry Smith /* if a->a are the same */ 4666eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4667eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4668eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4669eeffb40dSHong Zhang *flg = PETSC_FALSE; 46703a40ed3dSBarry Smith PetscFunctionReturn(0); 4671eeffb40dSHong Zhang } 4672eeffb40dSHong Zhang } 4673eeffb40dSHong Zhang #else 4674580bdb30SBarry Smith ierr = PetscArraycmp(a->a,b->a,a->nz,flg);CHKERRQ(ierr); 4675eeffb40dSHong Zhang #endif 4676eeffb40dSHong Zhang PetscFunctionReturn(0); 46777264ac53SSatish Balay } 467836db0b34SBarry Smith 467905869f15SSatish Balay /*@ 468036db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 468136db0b34SBarry Smith provided by the user. 468236db0b34SBarry Smith 4683d083f849SBarry Smith Collective 468436db0b34SBarry Smith 468536db0b34SBarry Smith Input Parameters: 468636db0b34SBarry Smith + comm - must be an MPI communicator of size 1 468736db0b34SBarry Smith . m - number of rows 468836db0b34SBarry Smith . n - number of columns 4689483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 469036db0b34SBarry Smith . j - column indices 469136db0b34SBarry Smith - a - matrix values 469236db0b34SBarry Smith 469336db0b34SBarry Smith Output Parameter: 469436db0b34SBarry Smith . mat - the matrix 469536db0b34SBarry Smith 469636db0b34SBarry Smith Level: intermediate 469736db0b34SBarry Smith 469836db0b34SBarry Smith Notes: 46990551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4700292fb18eSBarry Smith once the matrix is destroyed and not before 470136db0b34SBarry Smith 470236db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 470336db0b34SBarry Smith 4704bfeeae90SHong Zhang The i and j indices are 0 based 470536db0b34SBarry Smith 4706a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4707a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 47088eef79e4SBarry Smith as shown 4709a4552177SSatish Balay 47108eef79e4SBarry Smith $ 1 0 0 47118eef79e4SBarry Smith $ 2 0 3 47128eef79e4SBarry Smith $ 4 5 6 47138eef79e4SBarry Smith $ 47148eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 47158eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 47168eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4717a4552177SSatish Balay 47189985e31cSBarry Smith 471969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 472036db0b34SBarry Smith 472136db0b34SBarry Smith @*/ 4722c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 472336db0b34SBarry Smith { 4724dfbe8321SBarry Smith PetscErrorCode ierr; 4725cbcfb4deSHong Zhang PetscInt ii; 472636db0b34SBarry Smith Mat_SeqAIJ *aij; 4727cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4728cbcfb4deSHong Zhang PetscInt jj; 4729cbcfb4deSHong Zhang #endif 473036db0b34SBarry Smith 473136db0b34SBarry Smith PetscFunctionBegin; 473241096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4733f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4734f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4735a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4736ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4737ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4738ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4739071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 4740071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 4741ab93d7beSBarry Smith 474236db0b34SBarry Smith aij->i = i; 474336db0b34SBarry Smith aij->j = j; 474436db0b34SBarry Smith aij->a = a; 474536db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 474636db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4747e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4748e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 474936db0b34SBarry Smith 475036db0b34SBarry Smith for (ii=0; ii<m; ii++) { 475136db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 47522515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 475360e0710aSBarry 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]); 47549985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4755a061629eSStefano 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); 4756a061629eSStefano 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); 47579985e31cSBarry Smith } 475836db0b34SBarry Smith #endif 475936db0b34SBarry Smith } 47602515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 476136db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 476260e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 476360e0710aSBarry 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]); 476436db0b34SBarry Smith } 476536db0b34SBarry Smith #endif 476636db0b34SBarry Smith 4767b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4768b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 476936db0b34SBarry Smith PetscFunctionReturn(0); 477036db0b34SBarry Smith } 477180ef6e79SMatthew G Knepley /*@C 4772d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 47738a0b0e6bSVictor Minden provided by the user. 47748a0b0e6bSVictor Minden 4775d083f849SBarry Smith Collective 47768a0b0e6bSVictor Minden 47778a0b0e6bSVictor Minden Input Parameters: 47788a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 47798a0b0e6bSVictor Minden . m - number of rows 47808a0b0e6bSVictor Minden . n - number of columns 47818a0b0e6bSVictor Minden . i - row indices 47828a0b0e6bSVictor Minden . j - column indices 47831230e6d1SVictor Minden . a - matrix values 47841230e6d1SVictor Minden . nz - number of nonzeros 47851230e6d1SVictor Minden - idx - 0 or 1 based 47868a0b0e6bSVictor Minden 47878a0b0e6bSVictor Minden Output Parameter: 47888a0b0e6bSVictor Minden . mat - the matrix 47898a0b0e6bSVictor Minden 47908a0b0e6bSVictor Minden Level: intermediate 47918a0b0e6bSVictor Minden 47928a0b0e6bSVictor Minden Notes: 47938a0b0e6bSVictor Minden The i and j indices are 0 based 47948a0b0e6bSVictor Minden 47958a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 47968a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 47978a0b0e6bSVictor Minden as shown: 47988a0b0e6bSVictor Minden 47998a0b0e6bSVictor Minden 1 0 0 48008a0b0e6bSVictor Minden 2 0 3 48018a0b0e6bSVictor Minden 4 5 6 48028a0b0e6bSVictor Minden 48038a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 48048a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 48058a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 48068a0b0e6bSVictor Minden 48078a0b0e6bSVictor Minden 480869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 48098a0b0e6bSVictor Minden 48108a0b0e6bSVictor Minden @*/ 4811c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 48128a0b0e6bSVictor Minden { 48138a0b0e6bSVictor Minden PetscErrorCode ierr; 4814d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 48158a0b0e6bSVictor Minden 48168a0b0e6bSVictor Minden 48178a0b0e6bSVictor Minden PetscFunctionBegin; 48181795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 48191230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4820c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 48211230e6d1SVictor Minden } 48228a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 48238a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 48248a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 48251230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 48261230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 48271230e6d1SVictor Minden if (idx) { 48281230e6d1SVictor Minden row = i[ii] - 1; 48291230e6d1SVictor Minden col = j[ii] - 1; 48301230e6d1SVictor Minden } else { 48311230e6d1SVictor Minden row = i[ii]; 48321230e6d1SVictor Minden col = j[ii]; 48338a0b0e6bSVictor Minden } 48341230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 48358a0b0e6bSVictor Minden } 48368a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 48378a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4838d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 48398a0b0e6bSVictor Minden PetscFunctionReturn(0); 48408a0b0e6bSVictor Minden } 484136db0b34SBarry Smith 4842acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4843acf2f550SJed Brown { 4844acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4845acf2f550SJed Brown PetscErrorCode ierr; 4846acf2f550SJed Brown 4847acf2f550SJed Brown PetscFunctionBegin; 4848acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4849acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 48502205254eSKarl Rupp 4851acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4852acf2f550SJed Brown PetscFunctionReturn(0); 4853acf2f550SJed Brown } 4854acf2f550SJed Brown 48559c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 48569c8f2541SHong Zhang { 48579c8f2541SHong Zhang PetscErrorCode ierr; 48588761c3d6SHong Zhang PetscMPIInt size; 48599c8f2541SHong Zhang 48609c8f2541SHong Zhang PetscFunctionBegin; 48618761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 48627bbdc51dSHong Zhang if (size == 1) { 48637bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 48647bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 48657bbdc51dSHong Zhang } else { 48668761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 48677bbdc51dSHong Zhang } 48688761c3d6SHong Zhang } else { 48699c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 48708761c3d6SHong Zhang } 48719c8f2541SHong Zhang PetscFunctionReturn(0); 48729c8f2541SHong Zhang } 48739c8f2541SHong Zhang 487481824310SBarry Smith /* 487553dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 487653dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 487753dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 487853dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 487953dd7562SDmitry Karpeev */ 488053dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 488153dd7562SDmitry Karpeev { 488253dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 488353dd7562SDmitry Karpeev PetscErrorCode ierr; 488453dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 488553dd7562SDmitry Karpeev PetscBool seqaij; 488653dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 488753dd7562SDmitry Karpeev PetscScalar v; 488853dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 488953dd7562SDmitry Karpeev 489053dd7562SDmitry Karpeev PetscFunctionBegin; 489153dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 489253dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 48934099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 489453dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 489553dd7562SDmitry Karpeev if (rowemb) { 489653dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 489753dd7562SDmitry 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); 489853dd7562SDmitry Karpeev } else { 48996c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 490053dd7562SDmitry Karpeev } 490153dd7562SDmitry Karpeev if (colemb) { 490253dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 490353dd7562SDmitry 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); 490453dd7562SDmitry Karpeev } else { 490553dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 490653dd7562SDmitry Karpeev } 490753dd7562SDmitry Karpeev 490853dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 490953dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 491053dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 491153dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 491253dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 491353dd7562SDmitry Karpeev } 491453dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 491553dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 491653dd7562SDmitry Karpeev } 491753dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 491853dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 491953dd7562SDmitry Karpeev } 492053dd7562SDmitry Karpeev count = 0; 492153dd7562SDmitry Karpeev rowindices = NULL; 492253dd7562SDmitry Karpeev colindices = NULL; 492353dd7562SDmitry Karpeev if (rowemb) { 492453dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 492553dd7562SDmitry Karpeev } 492653dd7562SDmitry Karpeev if (colemb) { 492753dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 492853dd7562SDmitry Karpeev } 492953dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 493053dd7562SDmitry Karpeev PetscInt row; 493153dd7562SDmitry Karpeev row = i; 493253dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 493353dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 493453dd7562SDmitry Karpeev PetscInt col; 493553dd7562SDmitry Karpeev col = Baij->j[count]; 493653dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 493753dd7562SDmitry Karpeev v = Baij->a[count]; 493853dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 493953dd7562SDmitry Karpeev ++count; 494053dd7562SDmitry Karpeev } 494153dd7562SDmitry Karpeev } 494253dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 494353dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 494453dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 494553dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 494653dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 494753dd7562SDmitry Karpeev PetscFunctionReturn(0); 494853dd7562SDmitry Karpeev } 494953dd7562SDmitry Karpeev 49504099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 49514099cc6bSBarry Smith 49524099cc6bSBarry Smith /*@C 49534099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 49544099cc6bSBarry Smith 49554099cc6bSBarry Smith Collective on Mat 49564099cc6bSBarry Smith 49574099cc6bSBarry Smith Input Parameters: 49584099cc6bSBarry Smith + mat - the matrix object 49594099cc6bSBarry Smith - matype - matrix type 49604099cc6bSBarry Smith 49614099cc6bSBarry Smith Options Database Key: 49624099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 49634099cc6bSBarry Smith 49644099cc6bSBarry Smith 49654099cc6bSBarry Smith Level: intermediate 49664099cc6bSBarry Smith 49674099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 49684099cc6bSBarry Smith @*/ 49694099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 49704099cc6bSBarry Smith { 4971fd9d3c67SJed Brown PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*); 49724099cc6bSBarry Smith PetscBool sametype; 49734099cc6bSBarry Smith 49744099cc6bSBarry Smith PetscFunctionBegin; 49754099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 49764099cc6bSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 49774099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 49784099cc6bSBarry Smith 49794099cc6bSBarry Smith ierr = PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr); 49804099cc6bSBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 49814099cc6bSBarry Smith ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 49824099cc6bSBarry Smith PetscFunctionReturn(0); 49834099cc6bSBarry Smith } 49844099cc6bSBarry Smith 49854099cc6bSBarry Smith 49864099cc6bSBarry Smith /*@C 49874099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 49884099cc6bSBarry Smith 49894099cc6bSBarry Smith Not Collective 49904099cc6bSBarry Smith 49914099cc6bSBarry Smith Input Parameters: 49924099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 49934099cc6bSBarry Smith - function - routine to convert to subtype 49944099cc6bSBarry Smith 49954099cc6bSBarry Smith Notes: 49964099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 49974099cc6bSBarry Smith 49984099cc6bSBarry Smith 49994099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 50004099cc6bSBarry Smith $ -mat_seqaij_type my_mat 50014099cc6bSBarry Smith 50024099cc6bSBarry Smith Level: advanced 50034099cc6bSBarry Smith 50044099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 50054099cc6bSBarry Smith 50064099cc6bSBarry Smith 50074099cc6bSBarry Smith Level: advanced 50084099cc6bSBarry Smith @*/ 5009388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 50104099cc6bSBarry Smith { 50114099cc6bSBarry Smith PetscErrorCode ierr; 50124099cc6bSBarry Smith 50134099cc6bSBarry Smith PetscFunctionBegin; 50149cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 50154099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 50164099cc6bSBarry Smith PetscFunctionReturn(0); 50174099cc6bSBarry Smith } 50184099cc6bSBarry Smith 50194099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 50204099cc6bSBarry Smith 50214099cc6bSBarry Smith /*@C 50224099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 50234099cc6bSBarry Smith 50244099cc6bSBarry Smith Not Collective 50254099cc6bSBarry Smith 50264099cc6bSBarry Smith Level: advanced 50274099cc6bSBarry Smith 50284099cc6bSBarry Smith Developers Note: CUSP and CUSPARSE do not yet support the MatConvert_SeqAIJ..() paradigm and thus cannot be registered here 50294099cc6bSBarry Smith 50304099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 50314099cc6bSBarry Smith @*/ 50324099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 50334099cc6bSBarry Smith { 50344099cc6bSBarry Smith PetscErrorCode ierr; 50354099cc6bSBarry Smith 50364099cc6bSBarry Smith PetscFunctionBegin; 50374099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 50384099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 50394099cc6bSBarry Smith 50404099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 50414099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 50424dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 50439779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 50446b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 5045485f9817SRichard Tran Mills #endif 50464099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 50474099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 50484099cc6bSBarry Smith #endif 50494099cc6bSBarry Smith PetscFunctionReturn(0); 50504099cc6bSBarry Smith } 505153dd7562SDmitry Karpeev 505253dd7562SDmitry Karpeev /* 505381824310SBarry Smith Special version for direct calls from Fortran 505481824310SBarry Smith */ 5055af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 505681824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 505781824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 505881824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 505981824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 506081824310SBarry Smith #endif 506181824310SBarry Smith 506281824310SBarry Smith /* Change these macros so can be used in void function */ 506381824310SBarry Smith #undef CHKERRQ 5064ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 506581824310SBarry Smith #undef SETERRQ2 5066e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 50674994cf47SJed Brown #undef SETERRQ3 50684994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 506981824310SBarry Smith 50708cc058d9SJed Brown PETSC_EXTERN void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 507181824310SBarry Smith { 507281824310SBarry Smith Mat A = *AA; 507381824310SBarry Smith PetscInt m = *mm, n = *nn; 507481824310SBarry Smith InsertMode is = *isis; 507581824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 507681824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 507781824310SBarry Smith PetscInt *imax,*ai,*ailen; 507881824310SBarry Smith PetscErrorCode ierr; 507981824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 508054f21887SBarry Smith MatScalar *ap,value,*aa; 5081ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5082ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 508381824310SBarry Smith 508481824310SBarry Smith PetscFunctionBegin; 50854994cf47SJed Brown MatCheckPreallocated(A,1); 508681824310SBarry Smith imax = a->imax; 508781824310SBarry Smith ai = a->i; 508881824310SBarry Smith ailen = a->ilen; 508981824310SBarry Smith aj = a->j; 509081824310SBarry Smith aa = a->a; 509181824310SBarry Smith 509281824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 509381824310SBarry Smith row = im[k]; 509481824310SBarry Smith if (row < 0) continue; 509581824310SBarry Smith #if defined(PETSC_USE_DEBUG) 5096ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 509781824310SBarry Smith #endif 509881824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 509981824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 510081824310SBarry Smith low = 0; 510181824310SBarry Smith high = nrow; 510281824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 510381824310SBarry Smith if (in[l] < 0) continue; 510481824310SBarry Smith #if defined(PETSC_USE_DEBUG) 5105ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 510681824310SBarry Smith #endif 510781824310SBarry Smith col = in[l]; 51082205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 51092205254eSKarl Rupp else value = v[k + l*m]; 51102205254eSKarl Rupp 511181824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 511281824310SBarry Smith 51132205254eSKarl Rupp if (col <= lastcol) low = 0; 51142205254eSKarl Rupp else high = nrow; 511581824310SBarry Smith lastcol = col; 511681824310SBarry Smith while (high-low > 5) { 511781824310SBarry Smith t = (low+high)/2; 511881824310SBarry Smith if (rp[t] > col) high = t; 511981824310SBarry Smith else low = t; 512081824310SBarry Smith } 512181824310SBarry Smith for (i=low; i<high; i++) { 512281824310SBarry Smith if (rp[i] > col) break; 512381824310SBarry Smith if (rp[i] == col) { 512481824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 512581824310SBarry Smith else ap[i] = value; 512681824310SBarry Smith goto noinsert; 512781824310SBarry Smith } 512881824310SBarry Smith } 512981824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 513081824310SBarry Smith if (nonew == 1) goto noinsert; 5131ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5132fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 513381824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 513481824310SBarry Smith /* shift up all the later entries in this row */ 513581824310SBarry Smith for (ii=N; ii>=i; ii--) { 513681824310SBarry Smith rp[ii+1] = rp[ii]; 513781824310SBarry Smith ap[ii+1] = ap[ii]; 513881824310SBarry Smith } 513981824310SBarry Smith rp[i] = col; 514081824310SBarry Smith ap[i] = value; 5141e56f5c9eSBarry Smith A->nonzerostate++; 514281824310SBarry Smith noinsert:; 514381824310SBarry Smith low = i + 1; 514481824310SBarry Smith } 514581824310SBarry Smith ailen[row] = nrow; 514681824310SBarry Smith } 514781824310SBarry Smith PetscFunctionReturnVoid(); 514881824310SBarry Smith } 5149