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 { 2601795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 261854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 262854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&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; 309*071fcb05SBarry Smith PetscInt nz = a->i[m],row,mr,col,tmp; 3107cee066cSHong Zhang PetscInt *cspidx; 311*071fcb05SBarry Smith const PetscInt *jj; 3127cee066cSHong Zhang 3137cee066cSHong Zhang PetscFunctionBegin; 3147cee066cSHong Zhang *nn = n; 3157cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 316625f6d37SHong Zhang 3171795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 318854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 319854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr); 320854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&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++; 335*071fcb05SBarry Smith tmp = cia[col] + collengths[col]++ - oshift; 336*071fcb05SBarry Smith cspidx[tmp] = a->i[row] + i; /* index of a->j */ 337*071fcb05SBarry Smith cja[tmp] = row + oshift; 3387cee066cSHong Zhang } 3397cee066cSHong Zhang } 3407cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 341*071fcb05SBarry Smith *ia = cia; 342*071fcb05SBarry 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); 36587d4246cSBarry Smith PetscFunctionReturn(0); 36687d4246cSBarry Smith } 36787d4246cSBarry Smith 368bd04181cSBarry Smith /* 369bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 370bd04181cSBarry Smith 371bd04181cSBarry Smith - a single row of values is set with each call 372bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 373bd04181cSBarry Smith - the values are always added to the matrix, not set 374bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 375bd04181cSBarry Smith 3761f763a69SBarry Smith This does NOT assume the global column indices are sorted 377bd04181cSBarry Smith 3781f763a69SBarry Smith */ 379bd04181cSBarry Smith 380af0996ceSBarry Smith #include <petsc/private/isimpl.h> 381189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 382189e4007SBarry Smith { 383189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3841f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 3851f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 3861f763a69SBarry Smith PetscInt lastcol = -1; 387189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 388189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 389189e4007SBarry Smith 390f38dd0b8SBarry Smith row = ridx[im[0]]; 3911f763a69SBarry Smith rp = aj + ai[row]; 3921f763a69SBarry Smith ap = aa + ai[row]; 3931f763a69SBarry Smith nrow = ailen[row]; 394189e4007SBarry Smith low = 0; 395189e4007SBarry Smith high = nrow; 396189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 397189e4007SBarry Smith col = cidx[in[l]]; 398f38dd0b8SBarry Smith value = v[l]; 399189e4007SBarry Smith 400189e4007SBarry Smith if (col <= lastcol) low = 0; 401189e4007SBarry Smith else high = nrow; 402189e4007SBarry Smith lastcol = col; 403189e4007SBarry Smith while (high-low > 5) { 404189e4007SBarry Smith t = (low+high)/2; 405189e4007SBarry Smith if (rp[t] > col) high = t; 406189e4007SBarry Smith else low = t; 407189e4007SBarry Smith } 408189e4007SBarry Smith for (i=low; i<high; i++) { 409189e4007SBarry Smith if (rp[i] == col) { 4101f763a69SBarry Smith ap[i] += value; 411189e4007SBarry Smith low = i + 1; 4121f763a69SBarry Smith break; 413189e4007SBarry Smith } 414189e4007SBarry Smith } 415189e4007SBarry Smith } 416f38dd0b8SBarry Smith return 0; 417189e4007SBarry Smith } 418189e4007SBarry Smith 41997f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 42017ab2063SBarry Smith { 421416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 422e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 42397f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 4246849ba73SBarry Smith PetscErrorCode ierr; 425e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 426d8cdefa3SHong Zhang MatScalar *ap=NULL,value=0.0,*aa = a->a; 427ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 428ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 42917ab2063SBarry Smith 4303a40ed3dSBarry Smith PetscFunctionBegin; 43117ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 432416022c9SBarry Smith row = im[k]; 4335ef9f2a5SBarry Smith if (row < 0) continue; 4342515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 435e32f2f54SBarry 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); 4363b2fbd54SBarry Smith #endif 437720833daSHong Zhang rp = aj + ai[row]; 438876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 43917ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 440416022c9SBarry Smith low = 0; 441c71e6ed7SBarry Smith high = nrow; 44217ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4435ef9f2a5SBarry Smith if (in[l] < 0) continue; 4442515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 445e32f2f54SBarry 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); 4463b2fbd54SBarry Smith #endif 447bfeeae90SHong Zhang col = in[l]; 448*071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 449*071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 45036db0b34SBarry Smith 4512205254eSKarl Rupp if (col <= lastcol) low = 0; 4522205254eSKarl Rupp else high = nrow; 453e2ee6c50SBarry Smith lastcol = col; 454416022c9SBarry Smith while (high-low > 5) { 455416022c9SBarry Smith t = (low+high)/2; 456416022c9SBarry Smith if (rp[t] > col) high = t; 457416022c9SBarry Smith else low = t; 45817ab2063SBarry Smith } 459416022c9SBarry Smith for (i=low; i<high; i++) { 46017ab2063SBarry Smith if (rp[i] > col) break; 46117ab2063SBarry Smith if (rp[i] == col) { 462876c6284SHong Zhang if (!A->structure_only) { 4630c0d7e18SFande Kong if (is == ADD_VALUES) { 4640c0d7e18SFande Kong ap[i] += value; 4650c0d7e18SFande Kong (void)PetscLogFlops(1.0); 4660c0d7e18SFande Kong } 46717ab2063SBarry Smith else ap[i] = value; 468720833daSHong Zhang } 469e44c0bd4SBarry Smith low = i + 1; 47017ab2063SBarry Smith goto noinsert; 47117ab2063SBarry Smith } 47217ab2063SBarry Smith } 473dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 474c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 475e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 476720833daSHong Zhang if (A->structure_only) { 477876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 478720833daSHong Zhang } else { 479fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 480720833daSHong Zhang } 481c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 482416022c9SBarry Smith /* shift up all the later entries in this row */ 483580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 48417ab2063SBarry Smith rp[i] = col; 485580bdb30SBarry Smith if (!A->structure_only){ 486580bdb30SBarry Smith ierr = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr); 487580bdb30SBarry Smith ap[i] = value; 488580bdb30SBarry Smith } 489416022c9SBarry Smith low = i + 1; 490e56f5c9eSBarry Smith A->nonzerostate++; 491e44c0bd4SBarry Smith noinsert:; 49217ab2063SBarry Smith } 49317ab2063SBarry Smith ailen[row] = nrow; 49417ab2063SBarry Smith } 4953a40ed3dSBarry Smith PetscFunctionReturn(0); 49617ab2063SBarry Smith } 49717ab2063SBarry Smith 498*071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 499*071fcb05SBarry Smith { 500*071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 501*071fcb05SBarry Smith PetscInt *rp,k,row; 502*071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 503*071fcb05SBarry Smith PetscErrorCode ierr; 504*071fcb05SBarry Smith PetscInt *aj = a->j; 505*071fcb05SBarry Smith MatScalar *aa = a->a,*ap; 506*071fcb05SBarry Smith 507*071fcb05SBarry Smith PetscFunctionBegin; 508*071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 509*071fcb05SBarry Smith row = im[k]; 510*071fcb05SBarry Smith rp = aj + ai[row]; 511*071fcb05SBarry Smith ap = aa + ai[row]; 512*071fcb05SBarry Smith if (!A->was_assembled) { 513*071fcb05SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 514*071fcb05SBarry Smith } 515*071fcb05SBarry Smith if (!A->structure_only) { 516*071fcb05SBarry Smith if (v) { 517*071fcb05SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 518*071fcb05SBarry Smith v += n; 519*071fcb05SBarry Smith } else { 520*071fcb05SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 521*071fcb05SBarry Smith } 522*071fcb05SBarry Smith } 523*071fcb05SBarry Smith ailen[row] = n; 524*071fcb05SBarry Smith a->nz += n; 525*071fcb05SBarry Smith } 526*071fcb05SBarry Smith PetscFunctionReturn(0); 527*071fcb05SBarry Smith } 528*071fcb05SBarry Smith 52981824310SBarry Smith 530a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 5317eb43aa7SLois Curfman McInnes { 5327eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 53397f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 53497f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 53554f21887SBarry Smith MatScalar *ap,*aa = a->a; 5367eb43aa7SLois Curfman McInnes 5373a40ed3dSBarry Smith PetscFunctionBegin; 5387eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 5397eb43aa7SLois Curfman McInnes row = im[k]; 540e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 541e32f2f54SBarry 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); 542bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 5437eb43aa7SLois Curfman McInnes nrow = ailen[row]; 5447eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 545e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 546e32f2f54SBarry 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); 547bfeeae90SHong Zhang col = in[l]; 5487eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 5497eb43aa7SLois Curfman McInnes while (high-low > 5) { 5507eb43aa7SLois Curfman McInnes t = (low+high)/2; 5517eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 5527eb43aa7SLois Curfman McInnes else low = t; 5537eb43aa7SLois Curfman McInnes } 5547eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 5557eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 5567eb43aa7SLois Curfman McInnes if (rp[i] == col) { 557b49de8d1SLois Curfman McInnes *v++ = ap[i]; 5587eb43aa7SLois Curfman McInnes goto finished; 5597eb43aa7SLois Curfman McInnes } 5607eb43aa7SLois Curfman McInnes } 56197e567efSBarry Smith *v++ = 0.0; 5627eb43aa7SLois Curfman McInnes finished:; 5637eb43aa7SLois Curfman McInnes } 5647eb43aa7SLois Curfman McInnes } 5653a40ed3dSBarry Smith PetscFunctionReturn(0); 5667eb43aa7SLois Curfman McInnes } 5677eb43aa7SLois Curfman McInnes 56817ab2063SBarry Smith 569dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 57017ab2063SBarry Smith { 571416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 5726849ba73SBarry Smith PetscErrorCode ierr; 5736f69ff64SBarry Smith PetscInt i,*col_lens; 5746f69ff64SBarry Smith int fd; 575b37d52dbSMark F. Adams FILE *file; 57617ab2063SBarry Smith 5773a40ed3dSBarry Smith PetscFunctionBegin; 578b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 579854ce69bSBarry Smith ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr); 5802205254eSKarl Rupp 5810700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 582d0f46423SBarry Smith col_lens[1] = A->rmap->n; 583d0f46423SBarry Smith col_lens[2] = A->cmap->n; 584416022c9SBarry Smith col_lens[3] = a->nz; 585416022c9SBarry Smith 586416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 587d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 588416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 58917ab2063SBarry Smith } 590d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 591606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 592416022c9SBarry Smith 593416022c9SBarry Smith /* store column indices (zero start index) */ 5946f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 595416022c9SBarry Smith 596416022c9SBarry Smith /* store nonzero values */ 5976f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 598b37d52dbSMark F. Adams 599b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 600b37d52dbSMark F. Adams if (file) { 60133d57670SJed Brown fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs)); 602b37d52dbSMark F. Adams } 6033a40ed3dSBarry Smith PetscFunctionReturn(0); 60417ab2063SBarry Smith } 605416022c9SBarry Smith 6067dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 6077dc0baabSHong Zhang { 6087dc0baabSHong Zhang PetscErrorCode ierr; 6097dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 6107dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 6117dc0baabSHong Zhang 6127dc0baabSHong Zhang PetscFunctionBegin; 6137dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 6147dc0baabSHong Zhang for (i=0; i<m; i++) { 6157dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 6167dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 6177dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 6187dc0baabSHong Zhang } 6197dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 6207dc0baabSHong Zhang } 6217dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6227dc0baabSHong Zhang PetscFunctionReturn(0); 6237dc0baabSHong Zhang } 6247dc0baabSHong Zhang 62509573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 626cd155464SBarry Smith 627dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 628416022c9SBarry Smith { 629416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 630dfbe8321SBarry Smith PetscErrorCode ierr; 63160e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 632e060cb09SBarry Smith const char *name; 633f3ef73ceSBarry Smith PetscViewerFormat format; 63417ab2063SBarry Smith 6353a40ed3dSBarry Smith PetscFunctionBegin; 6367dc0baabSHong Zhang if (A->structure_only) { 6377dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 6387dc0baabSHong Zhang PetscFunctionReturn(0); 6397dc0baabSHong Zhang } 64043e49210SHong Zhang 641b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 64271c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 64397f1f81fSBarry Smith PetscInt nofinalvalue = 0; 64460e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 645c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 646d00d2cf4SBarry Smith nofinalvalue = 1; 647d00d2cf4SBarry Smith } 648d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 649d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 65077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 651fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 652fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 653fbfe6fa7SJed Brown #else 65477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 655fbfe6fa7SJed Brown #endif 656b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 65717ab2063SBarry Smith 65817ab2063SBarry Smith for (i=0; i<m; i++) { 65960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 660aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 661a9bf72d8SJed 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); 66217ab2063SBarry Smith #else 66360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 66417ab2063SBarry Smith #endif 66517ab2063SBarry Smith } 66617ab2063SBarry Smith } 667d00d2cf4SBarry Smith if (nofinalvalue) { 668c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 669c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 670c337ccceSJed Brown #else 671d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 672c337ccceSJed Brown #endif 673d00d2cf4SBarry Smith } 674317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 675fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 676d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 67768369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 678cd155464SBarry Smith PetscFunctionReturn(0); 679fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 680d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 68144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 68277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 68360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 684aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 68536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 68660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 68736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 68860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 68936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 69060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 6916831982aSBarry Smith } 69244cd7ae7SLois Curfman McInnes #else 69360e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 69444cd7ae7SLois Curfman McInnes #endif 69544cd7ae7SLois Curfman McInnes } 696b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 69744cd7ae7SLois Curfman McInnes } 698d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 699fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 70097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 701d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 702854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 703496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 704496be53dSLois Curfman McInnes sptr[i] = nzd+1; 70560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 706496be53dSLois Curfman McInnes if (a->j[j] >= i) { 707aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 70836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 709496be53dSLois Curfman McInnes #else 710496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 711496be53dSLois Curfman McInnes #endif 712496be53dSLois Curfman McInnes } 713496be53dSLois Curfman McInnes } 714496be53dSLois Curfman McInnes } 7152e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 71677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 7172e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 7182205254eSKarl Rupp if (i+4<m) { 7192205254eSKarl 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); 7202205254eSKarl Rupp } else if (i+3<m) { 7212205254eSKarl 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); 7222205254eSKarl Rupp } else if (i+2<m) { 7232205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 7242205254eSKarl Rupp } else if (i+1<m) { 7252205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 7262205254eSKarl Rupp } else if (i<m) { 7272205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 7282205254eSKarl Rupp } else { 7292205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 7302205254eSKarl Rupp } 731496be53dSLois Curfman McInnes } 732b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 733606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 734496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 73560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 73677431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 737496be53dSLois Curfman McInnes } 738b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 739496be53dSLois Curfman McInnes } 740b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 741496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 74260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 743496be53dSLois Curfman McInnes if (a->j[j] >= i) { 744aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 74536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 74660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7476831982aSBarry Smith } 748496be53dSLois Curfman McInnes #else 74960e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 750496be53dSLois Curfman McInnes #endif 751496be53dSLois Curfman McInnes } 752496be53dSLois Curfman McInnes } 753b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 754496be53dSLois Curfman McInnes } 755d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 756fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 75797f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 75887828ca2SBarry Smith PetscScalar value; 75968f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 76068f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 76168f1ed48SBarry Smith 76268f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 76368f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 76468f1ed48SBarry Smith realonly = PETSC_FALSE; 76568f1ed48SBarry Smith break; 76668f1ed48SBarry Smith } 76768f1ed48SBarry Smith } 76868f1ed48SBarry Smith #endif 76902594712SBarry Smith 770d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 77102594712SBarry Smith for (i=0; i<m; i++) { 77202594712SBarry Smith jcnt = 0; 773d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 774e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 77502594712SBarry Smith value = a->a[cnt++]; 776e24b481bSBarry Smith jcnt++; 77702594712SBarry Smith } else { 77802594712SBarry Smith value = 0.0; 77902594712SBarry Smith } 780aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 78168f1ed48SBarry Smith if (realonly) { 78260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 78368f1ed48SBarry Smith } else { 78460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 78568f1ed48SBarry Smith } 78602594712SBarry Smith #else 78760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 78802594712SBarry Smith #endif 78902594712SBarry Smith } 790b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 79102594712SBarry Smith } 792d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7933c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 794150b93efSMatthew G. Knepley PetscInt fshift=1; 795d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7963c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 79719303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 7983c215bfdSMatthew Knepley #else 79919303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 8003c215bfdSMatthew Knepley #endif 801d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 8023c215bfdSMatthew Knepley for (i=0; i<m; i++) { 80360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 8043c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 805a9a0e077SKarl 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); 8063c215bfdSMatthew Knepley #else 807150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 8083c215bfdSMatthew Knepley #endif 8093c215bfdSMatthew Knepley } 8103c215bfdSMatthew Knepley } 811d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 8123a40ed3dSBarry Smith } else { 813d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 814d5f3da31SBarry Smith if (A->factortype) { 81516cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 81616cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 81716cd7e1dSShri Abhyankar /* L part */ 81860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 81916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 82016cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 82160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 82216cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 8236712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 82416cd7e1dSShri Abhyankar } else { 82560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 82616cd7e1dSShri Abhyankar } 82716cd7e1dSShri Abhyankar #else 82860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 82916cd7e1dSShri Abhyankar #endif 83016cd7e1dSShri Abhyankar } 83116cd7e1dSShri Abhyankar /* diagonal */ 83216cd7e1dSShri Abhyankar j = a->diag[i]; 83316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 83416cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 83560e0710aSBarry 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); 83616cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 8376712e2f1SBarry 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); 83816cd7e1dSShri Abhyankar } else { 83960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 84016cd7e1dSShri Abhyankar } 84116cd7e1dSShri Abhyankar #else 84260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 84316cd7e1dSShri Abhyankar #endif 84416cd7e1dSShri Abhyankar 84516cd7e1dSShri Abhyankar /* U part */ 84660e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 84716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 84816cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 84960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 85016cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 85122ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 85216cd7e1dSShri Abhyankar } else { 85360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 85416cd7e1dSShri Abhyankar } 85516cd7e1dSShri Abhyankar #else 85660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 85716cd7e1dSShri Abhyankar #endif 85816cd7e1dSShri Abhyankar } 85916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 86016cd7e1dSShri Abhyankar } 86116cd7e1dSShri Abhyankar } else { 86217ab2063SBarry Smith for (i=0; i<m; i++) { 86377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 86460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 865aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 86636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 86760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 86836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 86960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8703a40ed3dSBarry Smith } else { 87160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 87217ab2063SBarry Smith } 87317ab2063SBarry Smith #else 87460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 87517ab2063SBarry Smith #endif 87617ab2063SBarry Smith } 877b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 87817ab2063SBarry Smith } 87916cd7e1dSShri Abhyankar } 880d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 88117ab2063SBarry Smith } 882b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8833a40ed3dSBarry Smith PetscFunctionReturn(0); 884416022c9SBarry Smith } 885416022c9SBarry Smith 8869804daf3SBarry Smith #include <petscdraw.h> 887dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 888416022c9SBarry Smith { 889480ef9eaSBarry Smith Mat A = (Mat) Aa; 890416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 891dfbe8321SBarry Smith PetscErrorCode ierr; 892383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 893383922c3SLisandro Dalcin int color; 894b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 895b0a32e0cSBarry Smith PetscViewer viewer; 896f3ef73ceSBarry Smith PetscViewerFormat format; 897cddf8d76SBarry Smith 8983a40ed3dSBarry Smith PetscFunctionBegin; 899480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 900b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 901b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 902383922c3SLisandro Dalcin 903416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 9040513a670SBarry Smith 905fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 906383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 9070513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 908b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 909416022c9SBarry Smith for (i=0; i<m; i++) { 910cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 911bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 912bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 91336db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 914b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 915cddf8d76SBarry Smith } 916cddf8d76SBarry Smith } 917b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 918cddf8d76SBarry Smith for (i=0; i<m; i++) { 919cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 920bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 921bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 922cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 923b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 924cddf8d76SBarry Smith } 925cddf8d76SBarry Smith } 926b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 927cddf8d76SBarry Smith for (i=0; i<m; i++) { 928cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 929bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 930bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 93136db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 932b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 933416022c9SBarry Smith } 934416022c9SBarry Smith } 935383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 9360513a670SBarry Smith } else { 9370513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 9380513a670SBarry Smith /* first determine max of all nonzero values */ 939b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 940383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 941b0a32e0cSBarry Smith PetscDraw popup; 9420513a670SBarry Smith 9430513a670SBarry Smith for (i=0; i<nz; i++) { 9440513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 9450513a670SBarry Smith } 946383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 947b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 94845f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 949383922c3SLisandro Dalcin 950383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 9510513a670SBarry Smith for (i=0; i<m; i++) { 952383922c3SLisandro Dalcin y_l = m - i - 1.0; 953383922c3SLisandro Dalcin y_r = y_l + 1.0; 954bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 955383922c3SLisandro Dalcin x_l = a->j[j]; 956383922c3SLisandro Dalcin x_r = x_l + 1.0; 957b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 958b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 9590513a670SBarry Smith count++; 9600513a670SBarry Smith } 9610513a670SBarry Smith } 962383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 9630513a670SBarry Smith } 964480ef9eaSBarry Smith PetscFunctionReturn(0); 965480ef9eaSBarry Smith } 966cddf8d76SBarry Smith 9679804daf3SBarry Smith #include <petscdraw.h> 968dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 969480ef9eaSBarry Smith { 970dfbe8321SBarry Smith PetscErrorCode ierr; 971b0a32e0cSBarry Smith PetscDraw draw; 97236db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 973ace3abfcSBarry Smith PetscBool isnull; 974480ef9eaSBarry Smith 975480ef9eaSBarry Smith PetscFunctionBegin; 976b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 977b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 978480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 979480ef9eaSBarry Smith 980d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 981480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 982b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 983832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 984b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 9850298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 986832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 9873a40ed3dSBarry Smith PetscFunctionReturn(0); 988416022c9SBarry Smith } 989416022c9SBarry Smith 990dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 991416022c9SBarry Smith { 992dfbe8321SBarry Smith PetscErrorCode ierr; 993ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 994416022c9SBarry Smith 9953a40ed3dSBarry Smith PetscFunctionBegin; 996251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 997251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 998251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 999c45a1595SBarry Smith if (iascii) { 10003a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 10010f5bd95cSBarry Smith } else if (isbinary) { 10023a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 10030f5bd95cSBarry Smith } else if (isdraw) { 10043a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 100511aeaf0aSBarry Smith } 10064108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 10073a40ed3dSBarry Smith PetscFunctionReturn(0); 100817ab2063SBarry Smith } 100919bcc07fSBarry Smith 1010dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 101117ab2063SBarry Smith { 1012416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10136849ba73SBarry Smith PetscErrorCode ierr; 1014580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1015d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 101654f21887SBarry Smith MatScalar *aa = a->a,*ap; 10173447b6efSHong Zhang PetscReal ratio = 0.6; 101817ab2063SBarry Smith 10193a40ed3dSBarry Smith PetscFunctionBegin; 10203a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1021*071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1022*071fcb05SBarry Smith if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) PetscFunctionReturn(0); 102317ab2063SBarry Smith 102443ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 102517ab2063SBarry Smith for (i=1; i<m; i++) { 1026416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 102717ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 102894a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 102917ab2063SBarry Smith if (fshift) { 1030bfeeae90SHong Zhang ip = aj + ai[i]; 1031bfeeae90SHong Zhang ap = aa + ai[i]; 103217ab2063SBarry Smith N = ailen[i]; 1033580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1034580bdb30SBarry Smith if (!A->structure_only) { 1035580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 103617ab2063SBarry Smith } 103717ab2063SBarry Smith } 103817ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 103917ab2063SBarry Smith } 104017ab2063SBarry Smith if (m) { 104117ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 104217ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 104317ab2063SBarry Smith } 10447b083b7cSBarry Smith 104517ab2063SBarry Smith /* reset ilen and imax for each row */ 10467b083b7cSBarry Smith a->nonzerorowcnt = 0; 1047396832f4SHong Zhang if (A->structure_only) { 1048*071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1049*071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1050396832f4SHong Zhang } else { /* !A->structure_only */ 105117ab2063SBarry Smith for (i=0; i<m; i++) { 105217ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 10537b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 105417ab2063SBarry Smith } 1055396832f4SHong Zhang } 1056bfeeae90SHong Zhang a->nz = ai[m]; 105765e19b50SBarry 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); 105817ab2063SBarry Smith 105909f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1060d0f46423SBarry 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); 1061ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1062ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 10632205254eSKarl Rupp 10648e58a170SBarry Smith A->info.mallocs += a->reallocs; 1065dd5f02e7SSatish Balay a->reallocs = 0; 10666712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 106736db0b34SBarry Smith a->rmax = rmax; 10684e220ebcSLois Curfman McInnes 1069396832f4SHong Zhang if (!A->structure_only) { 107011e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1071396832f4SHong Zhang } 10724108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 10733a40ed3dSBarry Smith PetscFunctionReturn(0); 107417ab2063SBarry Smith } 107517ab2063SBarry Smith 107699cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 107799cafbc1SBarry Smith { 107899cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 107999cafbc1SBarry Smith PetscInt i,nz = a->nz; 108054f21887SBarry Smith MatScalar *aa = a->a; 1081acf2f550SJed Brown PetscErrorCode ierr; 108299cafbc1SBarry Smith 108399cafbc1SBarry Smith PetscFunctionBegin; 108499cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1085acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 108699cafbc1SBarry Smith PetscFunctionReturn(0); 108799cafbc1SBarry Smith } 108899cafbc1SBarry Smith 108999cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 109099cafbc1SBarry Smith { 109199cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 109299cafbc1SBarry Smith PetscInt i,nz = a->nz; 109354f21887SBarry Smith MatScalar *aa = a->a; 1094acf2f550SJed Brown PetscErrorCode ierr; 109599cafbc1SBarry Smith 109699cafbc1SBarry Smith PetscFunctionBegin; 109799cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1098acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 109999cafbc1SBarry Smith PetscFunctionReturn(0); 110099cafbc1SBarry Smith } 110199cafbc1SBarry Smith 1102dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 110317ab2063SBarry Smith { 1104416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1105dfbe8321SBarry Smith PetscErrorCode ierr; 11063a40ed3dSBarry Smith 11073a40ed3dSBarry Smith PetscFunctionBegin; 1108580bdb30SBarry Smith ierr = PetscArrayzero(a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 1109acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 11103a40ed3dSBarry Smith PetscFunctionReturn(0); 111117ab2063SBarry Smith } 1112416022c9SBarry Smith 1113dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 111417ab2063SBarry Smith { 1115416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1116dfbe8321SBarry Smith PetscErrorCode ierr; 1117d5d45c9bSBarry Smith 11183a40ed3dSBarry Smith PetscFunctionBegin; 1119aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1120d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 112117ab2063SBarry Smith #endif 1122e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 11236bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 11246bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 112505b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1126d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1127*071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1128*071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1129846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 113071f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 113105b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 11326bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 113305b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 11346bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 1135cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 11360b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1137a30b2313SHong Zhang 11384108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1139bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1140901853e0SKris Buschelman 1141dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1142bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1143bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1144bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1145bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1146bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1147bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1148af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1149af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1150af8000cdSHong Zhang #endif 115163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 115263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 11533dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 115463c07aadSStefano Zampini #endif 1155b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1156c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1157c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1158bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1159bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1160846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1161bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1162bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 116375d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatPtAP_is_seqaij_C",NULL);CHKERRQ(ierr); 11643a40ed3dSBarry Smith PetscFunctionReturn(0); 116517ab2063SBarry Smith } 116617ab2063SBarry Smith 1167ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 116817ab2063SBarry Smith { 1169416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11704846f1f5SKris Buschelman PetscErrorCode ierr; 11713a40ed3dSBarry Smith 11723a40ed3dSBarry Smith PetscFunctionBegin; 1173a65d3064SKris Buschelman switch (op) { 1174a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 11754e0d8c25SBarry Smith a->roworiented = flg; 1176a65d3064SKris Buschelman break; 1177a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1178a9817697SBarry Smith a->keepnonzeropattern = flg; 1179a65d3064SKris Buschelman break; 1180512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1181512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1182a65d3064SKris Buschelman break; 1183a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 11844e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1185a65d3064SKris Buschelman break; 1186a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 11874e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1188a65d3064SKris Buschelman break; 118928b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 119028b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 119128b2fa4aSMatthew Knepley break; 1192a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 11934e0d8c25SBarry Smith a->ignorezeroentries = flg; 11940df259c2SBarry Smith break; 11953d472b54SHong Zhang case MAT_SPD: 1196b1646e73SJed Brown case MAT_SYMMETRIC: 1197b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1198b1646e73SJed Brown case MAT_HERMITIAN: 1199b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1200957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 12015021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 12025021d80fSJed Brown break; 12034e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1204a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1205a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1206290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1207a65d3064SKris Buschelman break; 1208b87ac2d8SJed Brown case MAT_USE_INODES: 1209b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1210b87ac2d8SJed Brown break; 1211c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1212c10200c1SHong Zhang A->submat_singleis = flg; 1213c10200c1SHong Zhang break; 1214*071fcb05SBarry Smith case MAT_SORTED_FULL: 1215*071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1216*071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1217*071fcb05SBarry Smith break; 1218a65d3064SKris Buschelman default: 1219e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1220a65d3064SKris Buschelman } 12214108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 12223a40ed3dSBarry Smith PetscFunctionReturn(0); 122317ab2063SBarry Smith } 122417ab2063SBarry Smith 1225dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 122617ab2063SBarry Smith { 1227416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12286849ba73SBarry Smith PetscErrorCode ierr; 1229d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 123035e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 123117ab2063SBarry Smith 12323a40ed3dSBarry Smith PetscFunctionBegin; 1233d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1234e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 123535e7444dSHong Zhang 1236d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1237d3e70bfaSHong Zhang PetscInt *diag=a->diag; 123835e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 12392c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 124035e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 124135e7444dSHong Zhang PetscFunctionReturn(0); 124235e7444dSHong Zhang } 124335e7444dSHong Zhang 12442dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 12451ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 124635e7444dSHong Zhang for (i=0; i<n; i++) { 124735e7444dSHong Zhang nz = ai[i+1] - ai[i]; 12482f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 124935e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 125035e7444dSHong Zhang if (aj[j] == i) { 125135e7444dSHong Zhang x[i] = aa[j]; 125217ab2063SBarry Smith break; 125317ab2063SBarry Smith } 125417ab2063SBarry Smith } 125517ab2063SBarry Smith } 12561ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 12573a40ed3dSBarry Smith PetscFunctionReturn(0); 125817ab2063SBarry Smith } 125917ab2063SBarry Smith 1260c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1261dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 126217ab2063SBarry Smith { 1263416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1264d9ca1df4SBarry Smith PetscScalar *y; 1265d9ca1df4SBarry Smith const PetscScalar *x; 1266dfbe8321SBarry Smith PetscErrorCode ierr; 1267d0f46423SBarry Smith PetscInt m = A->rmap->n; 12685c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1269d9ca1df4SBarry Smith const MatScalar *v; 1270a77337e4SBarry Smith PetscScalar alpha; 1271d9ca1df4SBarry Smith PetscInt n,i,j; 1272d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 12733447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1274ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 12755c897100SBarry Smith #endif 127617ab2063SBarry Smith 12773a40ed3dSBarry Smith PetscFunctionBegin; 12782e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1279d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 12801ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 12815c897100SBarry Smith 12825c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1283bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 12845c897100SBarry Smith #else 12853447b6efSHong Zhang if (usecprow) { 12863447b6efSHong Zhang m = cprow.nrows; 12873447b6efSHong Zhang ii = cprow.i; 12887b2bb3b9SHong Zhang ridx = cprow.rindex; 12893447b6efSHong Zhang } else { 12903447b6efSHong Zhang ii = a->i; 12913447b6efSHong Zhang } 129217ab2063SBarry Smith for (i=0; i<m; i++) { 12933447b6efSHong Zhang idx = a->j + ii[i]; 12943447b6efSHong Zhang v = a->a + ii[i]; 12953447b6efSHong Zhang n = ii[i+1] - ii[i]; 12963447b6efSHong Zhang if (usecprow) { 12977b2bb3b9SHong Zhang alpha = x[ridx[i]]; 12983447b6efSHong Zhang } else { 129917ab2063SBarry Smith alpha = x[i]; 13003447b6efSHong Zhang } 130104fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 130217ab2063SBarry Smith } 13035c897100SBarry Smith #endif 1304dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1305d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 13061ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13073a40ed3dSBarry Smith PetscFunctionReturn(0); 130817ab2063SBarry Smith } 130917ab2063SBarry Smith 1310dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 13115c897100SBarry Smith { 1312dfbe8321SBarry Smith PetscErrorCode ierr; 13135c897100SBarry Smith 13145c897100SBarry Smith PetscFunctionBegin; 1315170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 13165c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 13175c897100SBarry Smith PetscFunctionReturn(0); 13185c897100SBarry Smith } 13195c897100SBarry Smith 1320c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 132178b84d54SShri Abhyankar 1322dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 132317ab2063SBarry Smith { 1324416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1325d9fead3dSBarry Smith PetscScalar *y; 132654f21887SBarry Smith const PetscScalar *x; 132754f21887SBarry Smith const MatScalar *aa; 1328dfbe8321SBarry Smith PetscErrorCode ierr; 1329003131ecSBarry Smith PetscInt m=A->rmap->n; 13300298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 13317b083b7cSBarry Smith PetscInt n,i; 1332362ced78SSatish Balay PetscScalar sum; 1333ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 133417ab2063SBarry Smith 1335b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 133697952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1337fee21e36SBarry Smith #endif 1338fee21e36SBarry Smith 13393a40ed3dSBarry Smith PetscFunctionBegin; 13403649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 13411ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1342416022c9SBarry Smith ii = a->i; 13434eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1344580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 134597952fefSHong Zhang m = a->compressedrow.nrows; 134697952fefSHong Zhang ii = a->compressedrow.i; 134797952fefSHong Zhang ridx = a->compressedrow.rindex; 134897952fefSHong Zhang for (i=0; i<m; i++) { 134997952fefSHong Zhang n = ii[i+1] - ii[i]; 135097952fefSHong Zhang aj = a->j + ii[i]; 135197952fefSHong Zhang aa = a->a + ii[i]; 135297952fefSHong Zhang sum = 0.0; 1353003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1354003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 135597952fefSHong Zhang y[*ridx++] = sum; 135697952fefSHong Zhang } 135797952fefSHong Zhang } else { /* do not use compressed row format */ 1358b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 13593d3eaba7SBarry Smith aj = a->j; 13603d3eaba7SBarry Smith aa = a->a; 1361b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1362b05257ddSBarry Smith #else 136317ab2063SBarry Smith for (i=0; i<m; i++) { 1364003131ecSBarry Smith n = ii[i+1] - ii[i]; 1365003131ecSBarry Smith aj = a->j + ii[i]; 1366003131ecSBarry Smith aa = a->a + ii[i]; 136717ab2063SBarry Smith sum = 0.0; 1368003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 136917ab2063SBarry Smith y[i] = sum; 137017ab2063SBarry Smith } 13718d195f9aSBarry Smith #endif 1372b05257ddSBarry Smith } 13737b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 13743649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 13751ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13763a40ed3dSBarry Smith PetscFunctionReturn(0); 137717ab2063SBarry Smith } 137817ab2063SBarry Smith 1379b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1380b434eb95SMatthew G. Knepley { 1381b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1382b434eb95SMatthew G. Knepley PetscScalar *y; 1383b434eb95SMatthew G. Knepley const PetscScalar *x; 1384b434eb95SMatthew G. Knepley const MatScalar *aa; 1385b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1386b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1387b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1388b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1389b434eb95SMatthew G. Knepley PetscScalar sum; 1390b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1391b434eb95SMatthew G. Knepley 1392b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1393b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1394b434eb95SMatthew G. Knepley #endif 1395b434eb95SMatthew G. Knepley 1396b434eb95SMatthew G. Knepley PetscFunctionBegin; 1397b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1398b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1399b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1400b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1401b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1402b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1403b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1404b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1405b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1406b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1407b434eb95SMatthew G. Knepley sum = 0.0; 1408b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1409b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1410b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1411b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1412b434eb95SMatthew G. Knepley } 1413b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 14143d3eaba7SBarry Smith ii = a->i; 1415b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1416b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1417b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1418b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1419b434eb95SMatthew G. Knepley sum = 0.0; 1420b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1421b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1422b434eb95SMatthew G. Knepley y[i] = sum; 1423b434eb95SMatthew G. Knepley } 1424b434eb95SMatthew G. Knepley } 1425b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1426b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1427b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1428b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1429b434eb95SMatthew G. Knepley } 1430b434eb95SMatthew G. Knepley 1431b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1432b434eb95SMatthew G. Knepley { 1433b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1434b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1435b434eb95SMatthew G. Knepley const PetscScalar *x; 1436b434eb95SMatthew G. Knepley const MatScalar *aa; 1437b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1438b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1439b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1440b434eb95SMatthew G. Knepley PetscScalar sum; 1441b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1442b434eb95SMatthew G. Knepley 1443b434eb95SMatthew G. Knepley PetscFunctionBegin; 1444b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1445d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1446b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1447b434eb95SMatthew G. Knepley if (zz != yy) { 1448580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1449b434eb95SMatthew G. Knepley } 1450b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1451b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1452b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1453b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1454b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1455b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1456b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1457b434eb95SMatthew G. Knepley sum = y[*ridx]; 1458b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1459b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1460b434eb95SMatthew G. Knepley } 1461b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 14623d3eaba7SBarry Smith ii = a->i; 1463b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1464b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1465b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1466b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1467b434eb95SMatthew G. Knepley sum = y[i]; 1468b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1469b434eb95SMatthew G. Knepley z[i] = sum; 1470b434eb95SMatthew G. Knepley } 1471b434eb95SMatthew G. Knepley } 1472b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1473b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1474d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1475b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1476b434eb95SMatthew G. Knepley } 1477b434eb95SMatthew G. Knepley 1478c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1479dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 148017ab2063SBarry Smith { 1481416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1482f15663dcSBarry Smith PetscScalar *y,*z; 1483f15663dcSBarry Smith const PetscScalar *x; 148454f21887SBarry Smith const MatScalar *aa; 1485dfbe8321SBarry Smith PetscErrorCode ierr; 1486d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1487d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1488362ced78SSatish Balay PetscScalar sum; 1489ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 14909ea0dfa2SSatish Balay 14913a40ed3dSBarry Smith PetscFunctionBegin; 1492f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1493d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 14944eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 14954eb6d288SHong Zhang if (zz != yy) { 1496580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 14974eb6d288SHong Zhang } 149897952fefSHong Zhang m = a->compressedrow.nrows; 149997952fefSHong Zhang ii = a->compressedrow.i; 150097952fefSHong Zhang ridx = a->compressedrow.rindex; 150197952fefSHong Zhang for (i=0; i<m; i++) { 150297952fefSHong Zhang n = ii[i+1] - ii[i]; 150397952fefSHong Zhang aj = a->j + ii[i]; 150497952fefSHong Zhang aa = a->a + ii[i]; 150597952fefSHong Zhang sum = y[*ridx]; 1506f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 150797952fefSHong Zhang z[*ridx++] = sum; 150897952fefSHong Zhang } 150997952fefSHong Zhang } else { /* do not use compressed row format */ 15103d3eaba7SBarry Smith ii = a->i; 1511f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 15123d3eaba7SBarry Smith aj = a->j; 15133d3eaba7SBarry Smith aa = a->a; 1514f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1515f15663dcSBarry Smith #else 151617ab2063SBarry Smith for (i=0; i<m; i++) { 1517f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1518f15663dcSBarry Smith aj = a->j + ii[i]; 1519f15663dcSBarry Smith aa = a->a + ii[i]; 152017ab2063SBarry Smith sum = y[i]; 1521f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 152217ab2063SBarry Smith z[i] = sum; 152317ab2063SBarry Smith } 152402ab625aSSatish Balay #endif 1525f15663dcSBarry Smith } 1526dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1527f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1528d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 15293a40ed3dSBarry Smith PetscFunctionReturn(0); 153017ab2063SBarry Smith } 153117ab2063SBarry Smith 153217ab2063SBarry Smith /* 153317ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 153417ab2063SBarry Smith */ 1535dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 153617ab2063SBarry Smith { 1537416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15386849ba73SBarry Smith PetscErrorCode ierr; 1539d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 154017ab2063SBarry Smith 15413a40ed3dSBarry Smith PetscFunctionBegin; 154209f38230SBarry Smith if (!a->diag) { 1543785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 15443bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 154509f38230SBarry Smith } 1546d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 154709f38230SBarry Smith a->diag[i] = a->i[i+1]; 1548bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1549bfeeae90SHong Zhang if (a->j[j] == i) { 155009f38230SBarry Smith a->diag[i] = j; 155117ab2063SBarry Smith break; 155217ab2063SBarry Smith } 155317ab2063SBarry Smith } 155417ab2063SBarry Smith } 15553a40ed3dSBarry Smith PetscFunctionReturn(0); 155617ab2063SBarry Smith } 155717ab2063SBarry Smith 155861ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 155961ecd0c6SBarry Smith { 156061ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 156161ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 156261ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 156361ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 156461ecd0c6SBarry Smith PetscErrorCode ierr; 156561ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 156661ecd0c6SBarry Smith 156761ecd0c6SBarry Smith PetscFunctionBegin; 156861ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 156961ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 157061ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 157161ecd0c6SBarry Smith PetscFunctionReturn(0); 157261ecd0c6SBarry Smith } 157361ecd0c6SBarry Smith 157461ecd0c6SBarry Smith if (a->diagonaldense) { 157561ecd0c6SBarry Smith cnt = 0; 157661ecd0c6SBarry Smith } else { 157761ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 157861ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 157961ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 158061ecd0c6SBarry Smith cnt++; 158161ecd0c6SBarry Smith mdiag[i] = 1; 158261ecd0c6SBarry Smith } 158361ecd0c6SBarry Smith } 158461ecd0c6SBarry Smith } 158561ecd0c6SBarry Smith if (!cnt) { 158661ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 158761ecd0c6SBarry Smith } else { 1588b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1589b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 159061ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 159161ecd0c6SBarry Smith 159261ecd0c6SBarry Smith a->a = NULL; 159361ecd0c6SBarry Smith a->j = NULL; 159461ecd0c6SBarry Smith a->i = NULL; 159561ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 159661ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 159761ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1598447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 159961ecd0c6SBarry Smith } 160061ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 160161ecd0c6SBarry Smith 160261ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 160361ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 160461ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1605447d62f5SStefano Zampini if (i < A->cmap->n) { 160661ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 160761ecd0c6SBarry Smith } 1608447d62f5SStefano Zampini } 160961ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 161061ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 161161ecd0c6SBarry Smith if (singlemalloc) { 161261ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 161361ecd0c6SBarry Smith } else { 161461ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 161561ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 161661ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 161761ecd0c6SBarry Smith } 161861ecd0c6SBarry Smith } 161961ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 162061ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 162161ecd0c6SBarry Smith PetscFunctionReturn(0); 162261ecd0c6SBarry Smith } 162361ecd0c6SBarry Smith 1624be5855fcSBarry Smith /* 1625be5855fcSBarry Smith Checks for missing diagonals 1626be5855fcSBarry Smith */ 1627ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1628be5855fcSBarry Smith { 1629be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 16307734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1631994fe344SLisandro Dalcin PetscErrorCode ierr; 1632be5855fcSBarry Smith 1633be5855fcSBarry Smith PetscFunctionBegin; 163409f38230SBarry Smith *missing = PETSC_FALSE; 16357734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 163609f38230SBarry Smith *missing = PETSC_TRUE; 163709f38230SBarry Smith if (d) *d = 0; 1638994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 163909f38230SBarry Smith } else { 1640f1e2ffcdSBarry Smith diag = a->diag; 1641d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 16427734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 164309f38230SBarry Smith *missing = PETSC_TRUE; 164409f38230SBarry Smith if (d) *d = i; 1645994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1646358d2f5dSShri Abhyankar break; 164709f38230SBarry Smith } 1648be5855fcSBarry Smith } 1649be5855fcSBarry Smith } 1650be5855fcSBarry Smith PetscFunctionReturn(0); 1651be5855fcSBarry Smith } 1652be5855fcSBarry Smith 16530da83c2eSBarry Smith #include <petscblaslapack.h> 16540da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 16550da83c2eSBarry Smith 16560da83c2eSBarry Smith /* 16570da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 16580da83c2eSBarry Smith */ 16590da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 16600da83c2eSBarry Smith { 16610da83c2eSBarry Smith PetscErrorCode ierr; 16620da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 16630da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 16640da83c2eSBarry Smith const PetscReal shift = 0.0; 16650da83c2eSBarry Smith PetscInt ipvt[5]; 16660da83c2eSBarry Smith PetscScalar work[25],*v_work; 16670da83c2eSBarry Smith 16680da83c2eSBarry Smith PetscFunctionBegin; 16690da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 16700da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 16710da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 16720da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 16730da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 16740da83c2eSBarry Smith } 16750da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 16760da83c2eSBarry Smith if (bsizemax > 7) { 16770da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 16780da83c2eSBarry Smith } 16790da83c2eSBarry Smith ncnt = 0; 16800da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 16810da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 16820da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 16830da83c2eSBarry Smith switch (bsizes[i]) { 16840da83c2eSBarry Smith case 1: 16850da83c2eSBarry Smith *diag = 1.0/(*diag); 16860da83c2eSBarry Smith break; 16870da83c2eSBarry Smith case 2: 16880da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 16890da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 16900da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 16910da83c2eSBarry Smith break; 16920da83c2eSBarry Smith case 3: 16930da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 16940da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 16950da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 16960da83c2eSBarry Smith break; 16970da83c2eSBarry Smith case 4: 16980da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 16990da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17000da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 17010da83c2eSBarry Smith break; 17020da83c2eSBarry Smith case 5: 17030da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17040da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17050da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 17060da83c2eSBarry Smith break; 17070da83c2eSBarry Smith case 6: 17080da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17090da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17100da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 17110da83c2eSBarry Smith break; 17120da83c2eSBarry Smith case 7: 17130da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17140da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17150da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 17160da83c2eSBarry Smith break; 17170da83c2eSBarry Smith default: 17180da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 17190da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17200da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 17210da83c2eSBarry Smith } 17220da83c2eSBarry Smith ncnt += bsizes[i]; 17230da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 17240da83c2eSBarry Smith } 17250da83c2eSBarry Smith if (bsizemax > 7) { 17260da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 17270da83c2eSBarry Smith } 17280da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 17290da83c2eSBarry Smith PetscFunctionReturn(0); 17300da83c2eSBarry Smith } 17310da83c2eSBarry Smith 1732422a814eSBarry Smith /* 1733422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1734422a814eSBarry Smith */ 17357087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 173671f1c65dSBarry Smith { 173771f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 173871f1c65dSBarry Smith PetscErrorCode ierr; 1739d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 174054f21887SBarry Smith MatScalar *v = a->a; 174154f21887SBarry Smith PetscScalar *idiag,*mdiag; 174271f1c65dSBarry Smith 174371f1c65dSBarry Smith PetscFunctionBegin; 174471f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 174571f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 174671f1c65dSBarry Smith diag = a->diag; 174771f1c65dSBarry Smith if (!a->idiag) { 1748dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 17493bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 175071f1c65dSBarry Smith v = a->a; 175171f1c65dSBarry Smith } 175271f1c65dSBarry Smith mdiag = a->mdiag; 175371f1c65dSBarry Smith idiag = a->idiag; 175471f1c65dSBarry Smith 1755422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 175671f1c65dSBarry Smith for (i=0; i<m; i++) { 175771f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1758899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1759899639b0SHong Zhang if (PetscRealPart(fshift)) { 1760899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 17617b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 17627b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 17637b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1764a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1765899639b0SHong Zhang } 176671f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 176771f1c65dSBarry Smith } 176871f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 176971f1c65dSBarry Smith } else { 177071f1c65dSBarry Smith for (i=0; i<m; i++) { 177171f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 177271f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 177371f1c65dSBarry Smith } 1774dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 177571f1c65dSBarry Smith } 177671f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 177771f1c65dSBarry Smith PetscFunctionReturn(0); 177871f1c65dSBarry Smith } 177971f1c65dSBarry Smith 1780c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 178141f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 178217ab2063SBarry Smith { 1783416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1784e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 17853d3eaba7SBarry Smith const MatScalar *v,*idiag=0,*mdiag; 178654f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1787dfbe8321SBarry Smith PetscErrorCode ierr; 17883d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 178997f1f81fSBarry Smith const PetscInt *idx,*diag; 179017ab2063SBarry Smith 17913a40ed3dSBarry Smith PetscFunctionBegin; 1792b965ef7fSBarry Smith its = its*lits; 179391723122SBarry Smith 179471f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 179571f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 179671f1c65dSBarry Smith a->fshift = fshift; 179771f1c65dSBarry Smith a->omega = omega; 1798ed480e8bSBarry Smith 179971f1c65dSBarry Smith diag = a->diag; 180071f1c65dSBarry Smith t = a->ssor_work; 1801ed480e8bSBarry Smith idiag = a->idiag; 180271f1c65dSBarry Smith mdiag = a->mdiag; 1803ed480e8bSBarry Smith 18041ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 18053649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1806ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 180717ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 180817ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1809ed480e8bSBarry Smith bs = b; 181017ab2063SBarry Smith for (i=0; i<m; i++) { 181171f1c65dSBarry Smith d = fshift + mdiag[i]; 1812416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1813ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1814ed480e8bSBarry Smith v = a->a + diag[i] + 1; 181517ab2063SBarry Smith sum = b[i]*d/omega; 1816003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 181717ab2063SBarry Smith x[i] = sum; 181817ab2063SBarry Smith } 18191ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 18203649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1821efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 18223a40ed3dSBarry Smith PetscFunctionReturn(0); 182317ab2063SBarry Smith } 1824c783ea89SBarry Smith 18252205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 18262205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 182717ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1828887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 182917ab2063SBarry Smith 183017ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 183117ab2063SBarry Smith 1832887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 183317ab2063SBarry Smith */ 183417ab2063SBarry Smith scale = (2.0/omega) - 1.0; 183517ab2063SBarry Smith 183617ab2063SBarry Smith /* x = (E + U)^{-1} b */ 183717ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1838416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1839ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1840ed480e8bSBarry Smith v = a->a + diag[i] + 1; 184117ab2063SBarry Smith sum = b[i]; 1842e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1843ed480e8bSBarry Smith x[i] = sum*idiag[i]; 184417ab2063SBarry Smith } 184517ab2063SBarry Smith 184617ab2063SBarry Smith /* t = b - (2*E - D)x */ 1847416022c9SBarry Smith v = a->a; 18482205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 184917ab2063SBarry Smith 185017ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1851ed480e8bSBarry Smith ts = t; 1852416022c9SBarry Smith diag = a->diag; 185317ab2063SBarry Smith for (i=0; i<m; i++) { 1854416022c9SBarry Smith n = diag[i] - a->i[i]; 1855ed480e8bSBarry Smith idx = a->j + a->i[i]; 1856ed480e8bSBarry Smith v = a->a + a->i[i]; 185717ab2063SBarry Smith sum = t[i]; 1858003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1859ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1860733d66baSBarry Smith /* x = x + t */ 1861733d66baSBarry Smith x[i] += t[i]; 186217ab2063SBarry Smith } 186317ab2063SBarry Smith 1864dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 18651ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 18663649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 18673a40ed3dSBarry Smith PetscFunctionReturn(0); 186817ab2063SBarry Smith } 186917ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 187017ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 187117ab2063SBarry Smith for (i=0; i<m; i++) { 1872416022c9SBarry Smith n = diag[i] - a->i[i]; 1873ed480e8bSBarry Smith idx = a->j + a->i[i]; 1874ed480e8bSBarry Smith v = a->a + a->i[i]; 187517ab2063SBarry Smith sum = b[i]; 1876e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 18775c99c7daSBarry Smith t[i] = sum; 1878ed480e8bSBarry Smith x[i] = sum*idiag[i]; 187917ab2063SBarry Smith } 18805c99c7daSBarry Smith xb = t; 1881efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 18823a40ed3dSBarry Smith } else xb = b; 188317ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 188417ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1885416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1886ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1887ed480e8bSBarry Smith v = a->a + diag[i] + 1; 188817ab2063SBarry Smith sum = xb[i]; 1889e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 18905c99c7daSBarry Smith if (xb == b) { 1891ed480e8bSBarry Smith x[i] = sum*idiag[i]; 18925c99c7daSBarry Smith } else { 1893b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 189417ab2063SBarry Smith } 18955c99c7daSBarry Smith } 1896b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 189717ab2063SBarry Smith } 189817ab2063SBarry Smith its--; 189917ab2063SBarry Smith } 190017ab2063SBarry Smith while (its--) { 190117ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 190217ab2063SBarry Smith for (i=0; i<m; i++) { 1903b19a5dc2SMark Adams /* lower */ 1904b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1905ed480e8bSBarry Smith idx = a->j + a->i[i]; 1906ed480e8bSBarry Smith v = a->a + a->i[i]; 190717ab2063SBarry Smith sum = b[i]; 1908e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1909b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1910b19a5dc2SMark Adams /* upper */ 1911b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1912b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1913b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1914b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1915b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 191617ab2063SBarry Smith } 1917b19a5dc2SMark Adams xb = t; 19189f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1919b19a5dc2SMark Adams } else xb = b; 192017ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 192117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1922b19a5dc2SMark Adams sum = xb[i]; 1923b19a5dc2SMark Adams if (xb == b) { 1924b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1925416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1926ed480e8bSBarry Smith idx = a->j + a->i[i]; 1927ed480e8bSBarry Smith v = a->a + a->i[i]; 1928e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1929ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1930b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1931b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1932b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1933b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1934b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1935b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 193617ab2063SBarry Smith } 1937b19a5dc2SMark Adams } 1938b19a5dc2SMark Adams if (xb == b) { 19399f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1940b19a5dc2SMark Adams } else { 1941b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1942b19a5dc2SMark Adams } 194317ab2063SBarry Smith } 194417ab2063SBarry Smith } 19451ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 19463649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1947365a8a9eSBarry Smith PetscFunctionReturn(0); 194817ab2063SBarry Smith } 194917ab2063SBarry Smith 19502af78befSBarry Smith 1951dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 195217ab2063SBarry Smith { 1953416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19544e220ebcSLois Curfman McInnes 19553a40ed3dSBarry Smith PetscFunctionBegin; 19564e220ebcSLois Curfman McInnes info->block_size = 1.0; 19574e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 19584e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 19594e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 19604e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 19618e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 19627adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1963d5f3da31SBarry Smith if (A->factortype) { 19644e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 19654e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 19664e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 19674e220ebcSLois Curfman McInnes } else { 19684e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 19694e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 19704e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 19714e220ebcSLois Curfman McInnes } 19723a40ed3dSBarry Smith PetscFunctionReturn(0); 197317ab2063SBarry Smith } 197417ab2063SBarry Smith 19752b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 197617ab2063SBarry Smith { 1977416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1978c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 19796849ba73SBarry Smith PetscErrorCode ierr; 198097b48c8fSBarry Smith const PetscScalar *xx; 198197b48c8fSBarry Smith PetscScalar *bb; 1982c7da8527SEric Chamberland PetscInt d = 0; 198317ab2063SBarry Smith 19843a40ed3dSBarry Smith PetscFunctionBegin; 198597b48c8fSBarry Smith if (x && b) { 198697b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 198797b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 198897b48c8fSBarry Smith for (i=0; i<N; i++) { 198997b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1990447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 199197b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 199297b48c8fSBarry Smith } 199397b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 199497b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 199597b48c8fSBarry Smith } 199697b48c8fSBarry Smith 1997a9817697SBarry Smith if (a->keepnonzeropattern) { 1998f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1999e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2000580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2001f1e2ffcdSBarry Smith } 2002f4df32b1SMatthew Knepley if (diag != 0.0) { 2003c7da8527SEric Chamberland for (i=0; i<N; i++) { 2004c7da8527SEric Chamberland d = rows[i]; 2005447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2006c7da8527SEric 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); 2007c7da8527SEric Chamberland } 2008f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2009447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2010f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 2011f1e2ffcdSBarry Smith } 2012f1e2ffcdSBarry Smith } 2013f1e2ffcdSBarry Smith } else { 2014f4df32b1SMatthew Knepley if (diag != 0.0) { 201517ab2063SBarry Smith for (i=0; i<N; i++) { 2016e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 20177ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2018447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2019447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2020447d62f5SStefano Zampini } else { 2021416022c9SBarry Smith a->ilen[rows[i]] = 1; 2022f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 2023bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2024447d62f5SStefano Zampini } 2025447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2026f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 202717ab2063SBarry Smith } 202817ab2063SBarry Smith } 20293a40ed3dSBarry Smith } else { 203017ab2063SBarry Smith for (i=0; i<N; i++) { 2031e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2032416022c9SBarry Smith a->ilen[rows[i]] = 0; 203317ab2063SBarry Smith } 203417ab2063SBarry Smith } 2035e56f5c9eSBarry Smith A->nonzerostate++; 2036f1e2ffcdSBarry Smith } 20374099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20383a40ed3dSBarry Smith PetscFunctionReturn(0); 203917ab2063SBarry Smith } 204017ab2063SBarry Smith 20416e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 20426e169961SBarry Smith { 20436e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20446e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 20456e169961SBarry Smith PetscErrorCode ierr; 20462b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 20476e169961SBarry Smith const PetscScalar *xx; 20486e169961SBarry Smith PetscScalar *bb; 20496e169961SBarry Smith 20506e169961SBarry Smith PetscFunctionBegin; 20516e169961SBarry Smith if (x && b) { 20526e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 20536e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 20542b40b63fSBarry Smith vecs = PETSC_TRUE; 20556e169961SBarry Smith } 20561795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 20576e169961SBarry Smith for (i=0; i<N; i++) { 20586e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2059580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 20602205254eSKarl Rupp 20616e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 20626e169961SBarry Smith } 20636e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 20646e169961SBarry Smith if (!zeroed[i]) { 20656e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 20664cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 20672b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 20686e169961SBarry Smith a->a[j] = 0.0; 20696e169961SBarry Smith } 20706e169961SBarry Smith } 20714cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 20726e169961SBarry Smith } 20736e169961SBarry Smith if (x && b) { 20746e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 20756e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 20766e169961SBarry Smith } 20776e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 20786e169961SBarry Smith if (diag != 0.0) { 20796e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 20801d5a398dSstefano_zampini if (missing) { 20811d5a398dSstefano_zampini for (i=0; i<N; i++) { 20824cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 20834cf107fdSStefano 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]); 20841d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 20851d5a398dSstefano_zampini } 20861d5a398dSstefano_zampini } else { 20876e169961SBarry Smith for (i=0; i<N; i++) { 20886e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 20896e169961SBarry Smith } 20906e169961SBarry Smith } 20911d5a398dSstefano_zampini } 20924099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20936e169961SBarry Smith PetscFunctionReturn(0); 20946e169961SBarry Smith } 20956e169961SBarry Smith 2096a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 209717ab2063SBarry Smith { 2098416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 209997f1f81fSBarry Smith PetscInt *itmp; 210017ab2063SBarry Smith 21013a40ed3dSBarry Smith PetscFunctionBegin; 2102e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 210317ab2063SBarry Smith 2104416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 2105bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 210617ab2063SBarry Smith if (idx) { 2107bfeeae90SHong Zhang itmp = a->j + a->i[row]; 210826fbe8dcSKarl Rupp if (*nz) *idx = itmp; 210917ab2063SBarry Smith else *idx = 0; 211017ab2063SBarry Smith } 21113a40ed3dSBarry Smith PetscFunctionReturn(0); 211217ab2063SBarry Smith } 211317ab2063SBarry Smith 2114bfeeae90SHong Zhang /* remove this function? */ 2115a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 211617ab2063SBarry Smith { 21173a40ed3dSBarry Smith PetscFunctionBegin; 21183a40ed3dSBarry Smith PetscFunctionReturn(0); 211917ab2063SBarry Smith } 212017ab2063SBarry Smith 2121dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 212217ab2063SBarry Smith { 2123416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 212454f21887SBarry Smith MatScalar *v = a->a; 212536db0b34SBarry Smith PetscReal sum = 0.0; 21266849ba73SBarry Smith PetscErrorCode ierr; 212797f1f81fSBarry Smith PetscInt i,j; 212817ab2063SBarry Smith 21293a40ed3dSBarry Smith PetscFunctionBegin; 213017ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2131570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2132570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 2133570b7f6dSBarry Smith *nrm = BLASnrm2_(&nz,v,&one); 2134570b7f6dSBarry Smith #else 2135416022c9SBarry Smith for (i=0; i<a->nz; i++) { 213636db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 213717ab2063SBarry Smith } 21388f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2139570b7f6dSBarry Smith #endif 214051f70360SJed Brown ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 21413a40ed3dSBarry Smith } else if (type == NORM_1) { 214236db0b34SBarry Smith PetscReal *tmp; 214397f1f81fSBarry Smith PetscInt *jj = a->j; 21441795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2145064f8208SBarry Smith *nrm = 0.0; 2146416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2147bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 214817ab2063SBarry Smith } 2149d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2150064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 215117ab2063SBarry Smith } 2152606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 215351f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 21543a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2155064f8208SBarry Smith *nrm = 0.0; 2156d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 2157bfeeae90SHong Zhang v = a->a + a->i[j]; 215817ab2063SBarry Smith sum = 0.0; 2159416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 2160cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 216117ab2063SBarry Smith } 2162064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 216317ab2063SBarry Smith } 216451f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2165f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 21663a40ed3dSBarry Smith PetscFunctionReturn(0); 216717ab2063SBarry Smith } 216817ab2063SBarry Smith 21694e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 21704e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 21714e938277SHong Zhang { 21724e938277SHong Zhang PetscErrorCode ierr; 21734e938277SHong Zhang PetscInt i,j,anzj; 21744e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 21754e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 21764e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 21774e938277SHong Zhang 21784e938277SHong Zhang PetscFunctionBegin; 21794e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2180854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2181785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2182785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 21834e938277SHong Zhang 21844e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 21854e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 218626fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 21874e938277SHong Zhang /* Form ati for csr format of A^T. */ 218826fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 21894e938277SHong Zhang 21904e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2191580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 21924e938277SHong Zhang 21934e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 21944e938277SHong Zhang for (i=0;i<am;i++) { 21954e938277SHong Zhang anzj = ai[i+1] - ai[i]; 21964e938277SHong Zhang for (j=0;j<anzj;j++) { 21974e938277SHong Zhang atj[atfill[*aj]] = i; 21984e938277SHong Zhang atfill[*aj++] += 1; 21994e938277SHong Zhang } 22004e938277SHong Zhang } 22014e938277SHong Zhang 22024e938277SHong Zhang /* Clean up temporary space and complete requests. */ 22034e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2204ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 220533d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2206a2f3521dSMark F. Adams 22074e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 22084e938277SHong Zhang b->free_a = PETSC_FALSE; 22094e938277SHong Zhang b->free_ij = PETSC_TRUE; 22104e938277SHong Zhang b->nonew = 0; 22114e938277SHong Zhang PetscFunctionReturn(0); 22124e938277SHong Zhang } 22134e938277SHong Zhang 22147087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2215cd0d46ebSvictorle { 22163d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 221754f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 221854f21887SBarry Smith MatScalar *va,*vb; 22196849ba73SBarry Smith PetscErrorCode ierr; 222097f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2221cd0d46ebSvictorle 2222cd0d46ebSvictorle PetscFunctionBegin; 2223cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2224cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 22255485867bSBarry Smith if (ma!=nb || na!=mb) { 22265485867bSBarry Smith *f = PETSC_FALSE; 22275485867bSBarry Smith PetscFunctionReturn(0); 22285485867bSBarry Smith } 2229cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2230cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2231cd0d46ebSvictorle va = aij->a; vb = bij->a; 2232785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2233785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2234cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2235cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2236cd0d46ebSvictorle 2237cd0d46ebSvictorle *f = PETSC_TRUE; 2238cd0d46ebSvictorle for (i=0; i<ma; i++) { 2239cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 224097f1f81fSBarry Smith PetscInt idc,idr; 22415485867bSBarry Smith PetscScalar vc,vr; 2242cd0d46ebSvictorle /* column/row index/value */ 22435485867bSBarry Smith idc = adx[aptr[i]]; 22445485867bSBarry Smith idr = bdx[bptr[idc]]; 22455485867bSBarry Smith vc = va[aptr[i]]; 22465485867bSBarry Smith vr = vb[bptr[idc]]; 22475485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 22485485867bSBarry Smith *f = PETSC_FALSE; 22495485867bSBarry Smith goto done; 2250cd0d46ebSvictorle } else { 22515485867bSBarry Smith aptr[i]++; 22525485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2253cd0d46ebSvictorle } 2254cd0d46ebSvictorle } 2255cd0d46ebSvictorle } 2256cd0d46ebSvictorle done: 2257cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 22583aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2259cd0d46ebSvictorle PetscFunctionReturn(0); 2260cd0d46ebSvictorle } 2261cd0d46ebSvictorle 22627087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 22631cbb95d3SBarry Smith { 22643d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 226554f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 226654f21887SBarry Smith MatScalar *va,*vb; 22671cbb95d3SBarry Smith PetscErrorCode ierr; 22681cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 22691cbb95d3SBarry Smith 22701cbb95d3SBarry Smith PetscFunctionBegin; 22711cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 22721cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 22731cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 22741cbb95d3SBarry Smith *f = PETSC_FALSE; 22751cbb95d3SBarry Smith PetscFunctionReturn(0); 22761cbb95d3SBarry Smith } 22771cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 22781cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 22791cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2280785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2281785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 22821cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 22831cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 22841cbb95d3SBarry Smith 22851cbb95d3SBarry Smith *f = PETSC_TRUE; 22861cbb95d3SBarry Smith for (i=0; i<ma; i++) { 22871cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 22881cbb95d3SBarry Smith PetscInt idc,idr; 22891cbb95d3SBarry Smith PetscScalar vc,vr; 22901cbb95d3SBarry Smith /* column/row index/value */ 22911cbb95d3SBarry Smith idc = adx[aptr[i]]; 22921cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 22931cbb95d3SBarry Smith vc = va[aptr[i]]; 22941cbb95d3SBarry Smith vr = vb[bptr[idc]]; 22951cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 22961cbb95d3SBarry Smith *f = PETSC_FALSE; 22971cbb95d3SBarry Smith goto done; 22981cbb95d3SBarry Smith } else { 22991cbb95d3SBarry Smith aptr[i]++; 23001cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 23011cbb95d3SBarry Smith } 23021cbb95d3SBarry Smith } 23031cbb95d3SBarry Smith } 23041cbb95d3SBarry Smith done: 23051cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 23061cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 23071cbb95d3SBarry Smith PetscFunctionReturn(0); 23081cbb95d3SBarry Smith } 23091cbb95d3SBarry Smith 2310ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 23119e29f15eSvictorle { 2312dfbe8321SBarry Smith PetscErrorCode ierr; 23136e111a19SKarl Rupp 23149e29f15eSvictorle PetscFunctionBegin; 23155485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 23169e29f15eSvictorle PetscFunctionReturn(0); 23179e29f15eSvictorle } 23189e29f15eSvictorle 2319ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 23201cbb95d3SBarry Smith { 23211cbb95d3SBarry Smith PetscErrorCode ierr; 23226e111a19SKarl Rupp 23231cbb95d3SBarry Smith PetscFunctionBegin; 23241cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 23251cbb95d3SBarry Smith PetscFunctionReturn(0); 23261cbb95d3SBarry Smith } 23271cbb95d3SBarry Smith 2328dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 232917ab2063SBarry Smith { 2330416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2331fff8e43fSBarry Smith const PetscScalar *l,*r; 2332fff8e43fSBarry Smith PetscScalar x; 233354f21887SBarry Smith MatScalar *v; 2334dfbe8321SBarry Smith PetscErrorCode ierr; 2335fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2336fff8e43fSBarry Smith const PetscInt *jj; 233717ab2063SBarry Smith 23383a40ed3dSBarry Smith PetscFunctionBegin; 233917ab2063SBarry Smith if (ll) { 23403ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 23413ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2342e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2343e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2344fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 2345416022c9SBarry Smith v = a->a; 234617ab2063SBarry Smith for (i=0; i<m; i++) { 234717ab2063SBarry Smith x = l[i]; 2348416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 23492205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 235017ab2063SBarry Smith } 2351fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2352efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 235317ab2063SBarry Smith } 235417ab2063SBarry Smith if (rr) { 2355e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2356e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2357fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 2358416022c9SBarry Smith v = a->a; jj = a->j; 23592205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 2360fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2361efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 236217ab2063SBarry Smith } 2363acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 23643a40ed3dSBarry Smith PetscFunctionReturn(0); 236517ab2063SBarry Smith } 236617ab2063SBarry Smith 23677dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 236817ab2063SBarry Smith { 2369db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 23706849ba73SBarry Smith PetscErrorCode ierr; 2371d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 237297f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 23735d0c19d7SBarry Smith const PetscInt *irow,*icol; 23745d0c19d7SBarry Smith PetscInt nrows,ncols; 237597f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 237654f21887SBarry Smith MatScalar *a_new,*mat_a; 2377416022c9SBarry Smith Mat C; 2378cdc6f3adSToby Isaac PetscBool stride; 237917ab2063SBarry Smith 23803a40ed3dSBarry Smith PetscFunctionBegin; 238199141d43SSatish Balay 238217ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2383b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2384b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 238517ab2063SBarry Smith 2386251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2387ff718158SBarry Smith if (stride) { 2388ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2389ff718158SBarry Smith } else { 2390ff718158SBarry Smith first = 0; 2391ff718158SBarry Smith step = 0; 2392ff718158SBarry Smith } 2393fee21e36SBarry Smith if (stride && step == 1) { 239402834360SBarry Smith /* special case of contiguous rows */ 2395dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 239602834360SBarry Smith /* loop over new rows determining lens and starting points */ 239702834360SBarry Smith for (i=0; i<nrows; i++) { 2398bfeeae90SHong Zhang kstart = ai[irow[i]]; 2399a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2400a91a9bebSLisandro Dalcin starts[i] = kstart; 240102834360SBarry Smith for (k=kstart; k<kend; k++) { 2402bfeeae90SHong Zhang if (aj[k] >= first) { 240302834360SBarry Smith starts[i] = k; 240402834360SBarry Smith break; 240502834360SBarry Smith } 240602834360SBarry Smith } 2407a2744918SBarry Smith sum = 0; 240802834360SBarry Smith while (k < kend) { 2409bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2410a2744918SBarry Smith sum++; 241102834360SBarry Smith } 2412a2744918SBarry Smith lens[i] = sum; 241302834360SBarry Smith } 241402834360SBarry Smith /* create submatrix */ 2415cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 241697f1f81fSBarry Smith PetscInt n_cols,n_rows; 241708480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2418e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2419d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 242008480c60SBarry Smith C = *B; 24213a40ed3dSBarry Smith } else { 24223bef6203SJed Brown PetscInt rbs,cbs; 2423ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2424f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 24253bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 24263bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 24273bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 24287adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2429ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 243008480c60SBarry Smith } 2431db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2432db02288aSLois Curfman McInnes 243302834360SBarry Smith /* loop over rows inserting into submatrix */ 2434db02288aSLois Curfman McInnes a_new = c->a; 2435db02288aSLois Curfman McInnes j_new = c->j; 2436db02288aSLois Curfman McInnes i_new = c->i; 2437bfeeae90SHong Zhang 243802834360SBarry Smith for (i=0; i<nrows; i++) { 2439a2744918SBarry Smith ii = starts[i]; 2440a2744918SBarry Smith lensi = lens[i]; 2441a2744918SBarry Smith for (k=0; k<lensi; k++) { 2442a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 244302834360SBarry Smith } 2444580bdb30SBarry Smith ierr = PetscArraycpy(a_new,a->a + starts[i],lensi);CHKERRQ(ierr); 2445a2744918SBarry Smith a_new += lensi; 2446a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2447a2744918SBarry Smith c->ilen[i] = lensi; 244802834360SBarry Smith } 24490e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 24503a40ed3dSBarry Smith } else { 245102834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 24521795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2453854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 24544dcab191SBarry Smith for (i=0; i<ncols; i++) { 24554dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 24564dcab191SBarry 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); 24574dcab191SBarry Smith #endif 24584dcab191SBarry Smith smap[icol[i]] = i+1; 24594dcab191SBarry Smith } 24604dcab191SBarry Smith 246102834360SBarry Smith /* determine lens of each row */ 246202834360SBarry Smith for (i=0; i<nrows; i++) { 2463bfeeae90SHong Zhang kstart = ai[irow[i]]; 246402834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 246502834360SBarry Smith lens[i] = 0; 246602834360SBarry Smith for (k=kstart; k<kend; k++) { 2467bfeeae90SHong Zhang if (smap[aj[k]]) { 246802834360SBarry Smith lens[i]++; 246902834360SBarry Smith } 247002834360SBarry Smith } 247102834360SBarry Smith } 247217ab2063SBarry Smith /* Create and fill new matrix */ 2473a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2474ace3abfcSBarry Smith PetscBool equal; 24750f5bd95cSBarry Smith 247699141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2477e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2478580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2479f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2480580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 248108480c60SBarry Smith C = *B; 24823a40ed3dSBarry Smith } else { 24833bef6203SJed Brown PetscInt rbs,cbs; 2484ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2485f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 24863bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 24873bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 24883bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 24897adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2490ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 249108480c60SBarry Smith } 249299141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 249317ab2063SBarry Smith for (i=0; i<nrows; i++) { 249499141d43SSatish Balay row = irow[i]; 2495bfeeae90SHong Zhang kstart = ai[row]; 249699141d43SSatish Balay kend = kstart + a->ilen[row]; 2497bfeeae90SHong Zhang mat_i = c->i[i]; 249899141d43SSatish Balay mat_j = c->j + mat_i; 249999141d43SSatish Balay mat_a = c->a + mat_i; 250099141d43SSatish Balay mat_ilen = c->ilen + i; 250117ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2502bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2503ed480e8bSBarry Smith *mat_j++ = tcol - 1; 250499141d43SSatish Balay *mat_a++ = a->a[k]; 250599141d43SSatish Balay (*mat_ilen)++; 250699141d43SSatish Balay 250717ab2063SBarry Smith } 250817ab2063SBarry Smith } 250917ab2063SBarry Smith } 251002834360SBarry Smith /* Free work space */ 251102834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2512606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2513606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2514cdc6f3adSToby Isaac /* sort */ 2515cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2516cdc6f3adSToby Isaac PetscInt ilen; 2517cdc6f3adSToby Isaac 2518cdc6f3adSToby Isaac mat_i = c->i[i]; 2519cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2520cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2521cdc6f3adSToby Isaac ilen = c->ilen[i]; 2522390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2523cdc6f3adSToby Isaac } 252402834360SBarry Smith } 25256d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 25266d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 252717ab2063SBarry Smith 252817ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2529416022c9SBarry Smith *B = C; 25303a40ed3dSBarry Smith PetscFunctionReturn(0); 253117ab2063SBarry Smith } 253217ab2063SBarry Smith 2533fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 253482d44351SHong Zhang { 253582d44351SHong Zhang PetscErrorCode ierr; 253682d44351SHong Zhang Mat B; 253782d44351SHong Zhang 253882d44351SHong Zhang PetscFunctionBegin; 2539c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 254082d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 254182d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 254233d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 254382d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 254482d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 254582d44351SHong Zhang *subMat = B; 2546c2d650bdSHong Zhang } else { 2547c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2548c2d650bdSHong Zhang } 254982d44351SHong Zhang PetscFunctionReturn(0); 255082d44351SHong Zhang } 255182d44351SHong Zhang 25529a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2553a871dcd8SBarry Smith { 255463b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2555dfbe8321SBarry Smith PetscErrorCode ierr; 255663b91edcSBarry Smith Mat outA; 2557ace3abfcSBarry Smith PetscBool row_identity,col_identity; 255863b91edcSBarry Smith 25593a40ed3dSBarry Smith PetscFunctionBegin; 2560e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 25611df811f5SHong Zhang 2562b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2563b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2564a871dcd8SBarry Smith 256563b91edcSBarry Smith outA = inA; 2566d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2567f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2568f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 25692205254eSKarl Rupp 2570c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 25716bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 25722205254eSKarl Rupp 2573c3122656SLisandro Dalcin a->row = row; 25742205254eSKarl Rupp 2575c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 25766bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 25772205254eSKarl Rupp 2578c3122656SLisandro Dalcin a->col = col; 257963b91edcSBarry Smith 258036db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 25816bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 25824c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 25833bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2584f0ec6fceSSatish Balay 258594a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2586854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 25873bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 258894a9d846SBarry Smith } 258963b91edcSBarry Smith 2590f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2591137fb511SHong Zhang if (row_identity && col_identity) { 2592ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2593137fb511SHong Zhang } else { 2594719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2595137fb511SHong Zhang } 25963a40ed3dSBarry Smith PetscFunctionReturn(0); 2597a871dcd8SBarry Smith } 2598a871dcd8SBarry Smith 2599f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2600f0b747eeSBarry Smith { 2601f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2602f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2603efee365bSSatish Balay PetscErrorCode ierr; 2604c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 26053a40ed3dSBarry Smith 26063a40ed3dSBarry Smith PetscFunctionBegin; 2607c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 26088b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2609efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2610acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 26113a40ed3dSBarry Smith PetscFunctionReturn(0); 2612f0b747eeSBarry Smith } 2613f0b747eeSBarry Smith 2614f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 261516b64355SHong Zhang { 261616b64355SHong Zhang PetscErrorCode ierr; 261716b64355SHong Zhang PetscInt i; 261816b64355SHong Zhang 261916b64355SHong Zhang PetscFunctionBegin; 262016b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 262116b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 262216b64355SHong Zhang 262316b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 262416b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 262516b64355SHong Zhang } 262616b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 262716b64355SHong Zhang 262816b64355SHong Zhang if (submatj->rbuf1) { 262916b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 263016b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 263116b64355SHong Zhang } 263216b64355SHong Zhang 263316b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 263416b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 263516b64355SHong Zhang } 263616b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 263716b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 263816b64355SHong Zhang } 263916b64355SHong Zhang 264016b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 264116b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 264216b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 264316b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 264416b64355SHong Zhang #else 264516b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 264616b64355SHong Zhang #endif 264716b64355SHong Zhang 264816b64355SHong Zhang if (!submatj->allcolumns) { 264916b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 265016b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 265116b64355SHong Zhang #else 265216b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 265316b64355SHong Zhang #endif 265416b64355SHong Zhang } 265516b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 265616b64355SHong Zhang 265716b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 265816b64355SHong Zhang PetscFunctionReturn(0); 265916b64355SHong Zhang } 266016b64355SHong Zhang 26610fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 266216b64355SHong Zhang { 266316b64355SHong Zhang PetscErrorCode ierr; 266416b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 26655c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 266616b64355SHong Zhang 266716b64355SHong Zhang PetscFunctionBegin; 266834136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2669f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 267016b64355SHong Zhang PetscFunctionReturn(0); 267116b64355SHong Zhang } 267216b64355SHong Zhang 26732d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 26742d033e1fSHong Zhang { 26752d033e1fSHong Zhang PetscErrorCode ierr; 26762d033e1fSHong Zhang PetscInt i; 26770fb991dcSHong Zhang Mat C; 26780fb991dcSHong Zhang Mat_SeqAIJ *c; 26790fb991dcSHong Zhang Mat_SubSppt *submatj; 26802d033e1fSHong Zhang 26812d033e1fSHong Zhang PetscFunctionBegin; 26822d033e1fSHong Zhang for (i=0; i<n; i++) { 26830fb991dcSHong Zhang C = (*mat)[i]; 26840fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 26850fb991dcSHong Zhang submatj = c->submatis1; 26862d033e1fSHong Zhang if (submatj) { 2687682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 268834136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2689f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 269034136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 26912d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 26922d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 26932d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2694682e4c99SStefano Zampini } 26952d033e1fSHong Zhang } else { 26962d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 26972d033e1fSHong Zhang } 26982d033e1fSHong Zhang } 269986e85357SHong Zhang 270063a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 270163a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 270263a75b2aSHong Zhang 27032d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 27042d033e1fSHong Zhang PetscFunctionReturn(0); 27052d033e1fSHong Zhang } 27062d033e1fSHong Zhang 27077dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2708cddf8d76SBarry Smith { 2709dfbe8321SBarry Smith PetscErrorCode ierr; 271097f1f81fSBarry Smith PetscInt i; 2711cddf8d76SBarry Smith 27123a40ed3dSBarry Smith PetscFunctionBegin; 2713cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2714df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2715cddf8d76SBarry Smith } 2716cddf8d76SBarry Smith 2717cddf8d76SBarry Smith for (i=0; i<n; i++) { 27187dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2719cddf8d76SBarry Smith } 27203a40ed3dSBarry Smith PetscFunctionReturn(0); 2721cddf8d76SBarry Smith } 2722cddf8d76SBarry Smith 272397f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 27244dcbc457SBarry Smith { 2725e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 27266849ba73SBarry Smith PetscErrorCode ierr; 27275d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 27285d0c19d7SBarry Smith const PetscInt *idx; 272997f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2730f1af5d2fSBarry Smith PetscBT table; 2731bbd702dbSSatish Balay 27323a40ed3dSBarry Smith PetscFunctionBegin; 2733d0f46423SBarry Smith m = A->rmap->n; 2734e4d965acSSatish Balay ai = a->i; 2735bfeeae90SHong Zhang aj = a->j; 27368a047759SSatish Balay 2737e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 273806763907SSatish Balay 2739854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 274053b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 274106763907SSatish Balay 2742e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2743b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2744e4d965acSSatish Balay isz = 0; 27456831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2746e4d965acSSatish Balay 2747e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 27484dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2749b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2750e4d965acSSatish Balay 2751dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2752e4d965acSSatish Balay for (j=0; j<n; ++j) { 27532205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 27544dcbc457SBarry Smith } 275506763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 27566bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2757e4d965acSSatish Balay 275804a348a9SBarry Smith k = 0; 275904a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 276004a348a9SBarry Smith n = isz; 276106763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2762e4d965acSSatish Balay row = nidx[k]; 2763e4d965acSSatish Balay start = ai[row]; 2764e4d965acSSatish Balay end = ai[row+1]; 276504a348a9SBarry Smith for (l = start; l<end; l++) { 2766efb16452SHong Zhang val = aj[l]; 27672205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2768e4d965acSSatish Balay } 2769e4d965acSSatish Balay } 2770e4d965acSSatish Balay } 277170b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2772e4d965acSSatish Balay } 277394bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2774606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 27753a40ed3dSBarry Smith PetscFunctionReturn(0); 27764dcbc457SBarry Smith } 277717ab2063SBarry Smith 27780513a670SBarry Smith /* -------------------------------------------------------------- */ 2779dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 27800513a670SBarry Smith { 27810513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 27826849ba73SBarry Smith PetscErrorCode ierr; 27833b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 27845d0c19d7SBarry Smith const PetscInt *row,*col; 27855d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 278656cd22aeSBarry Smith IS icolp,irowp; 27870298fd71SBarry Smith PetscInt *cwork = NULL; 27880298fd71SBarry Smith PetscScalar *vwork = NULL; 27890513a670SBarry Smith 27903a40ed3dSBarry Smith PetscFunctionBegin; 27914c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 279256cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 27934c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 279456cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 27950513a670SBarry Smith 27960513a670SBarry Smith /* determine lengths of permuted rows */ 2797854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 27982205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2799ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2800f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 280133d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 28027adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2803ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2804606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 28050513a670SBarry Smith 2806785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 28070513a670SBarry Smith for (i=0; i<m; i++) { 280832ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 28092205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2810cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 281132ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 28120513a670SBarry Smith } 2813606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 28142205254eSKarl Rupp 28153c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 28162205254eSKarl Rupp 28170513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28180513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 281956cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 282056cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 28216bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 28226bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 28233a40ed3dSBarry Smith PetscFunctionReturn(0); 28240513a670SBarry Smith } 28250513a670SBarry Smith 2826dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2827cb5b572fSBarry Smith { 2828dfbe8321SBarry Smith PetscErrorCode ierr; 2829cb5b572fSBarry Smith 2830cb5b572fSBarry Smith PetscFunctionBegin; 283133f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 283233f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2833be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2834be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2835be6bf707SBarry Smith 2836700c5bfcSBarry 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"); 2837580bdb30SBarry Smith ierr = PetscArraycpy(b->a,a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 2838cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 2839cb5b572fSBarry Smith } else { 2840cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2841cb5b572fSBarry Smith } 2842cb5b572fSBarry Smith PetscFunctionReturn(0); 2843cb5b572fSBarry Smith } 2844cb5b572fSBarry Smith 28454994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2846273d9f13SBarry Smith { 2847dfbe8321SBarry Smith PetscErrorCode ierr; 2848273d9f13SBarry Smith 2849273d9f13SBarry Smith PetscFunctionBegin; 2850ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2851273d9f13SBarry Smith PetscFunctionReturn(0); 2852273d9f13SBarry Smith } 2853273d9f13SBarry Smith 28548c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 28556c0721eeSBarry Smith { 28566c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 28576e111a19SKarl Rupp 28586c0721eeSBarry Smith PetscFunctionBegin; 28596c0721eeSBarry Smith *array = a->a; 28606c0721eeSBarry Smith PetscFunctionReturn(0); 28616c0721eeSBarry Smith } 28626c0721eeSBarry Smith 28638c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 28646c0721eeSBarry Smith { 28656c0721eeSBarry Smith PetscFunctionBegin; 28666c0721eeSBarry Smith PetscFunctionReturn(0); 28676c0721eeSBarry Smith } 2868273d9f13SBarry Smith 28698229c054SShri Abhyankar /* 28708229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 28718229c054SShri Abhyankar have different nonzero structure. 28728229c054SShri Abhyankar */ 2873b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 2874ec7775f6SShri Abhyankar { 2875b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 2876ec7775f6SShri Abhyankar 2877ec7775f6SShri Abhyankar PetscFunctionBegin; 2878ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2879ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 2880b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 2881b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 2882b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 28838af7cee1SJed Brown nnz[i] = 0; 28848af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 2885b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 2886b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 28878af7cee1SJed Brown nnz[i]++; 28888af7cee1SJed Brown } 28898af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2890ec7775f6SShri Abhyankar } 2891ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2892ec7775f6SShri Abhyankar } 2893ec7775f6SShri Abhyankar 2894b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2895b264fe52SHong Zhang { 2896b264fe52SHong Zhang PetscInt m = Y->rmap->N; 2897b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2898b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2899b264fe52SHong Zhang PetscErrorCode ierr; 2900b264fe52SHong Zhang 2901b264fe52SHong Zhang PetscFunctionBegin; 2902b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 2903b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 2904b264fe52SHong Zhang PetscFunctionReturn(0); 2905b264fe52SHong Zhang } 2906b264fe52SHong Zhang 2907f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2908ac90fabeSBarry Smith { 2909dfbe8321SBarry Smith PetscErrorCode ierr; 2910ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2911c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2912ac90fabeSBarry Smith 2913ac90fabeSBarry Smith PetscFunctionBegin; 2914c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2915ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2916f4df32b1SMatthew Knepley PetscScalar alpha = a; 29178b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2918acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2919a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 2920ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2921ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2922ac90fabeSBarry Smith } else { 29238229c054SShri Abhyankar Mat B; 29248229c054SShri Abhyankar PetscInt *nnz; 2925785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 2926ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 2927bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 29284aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 292933d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr); 2930176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 29318229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2932ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2933ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 293428be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 29358229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2936ac90fabeSBarry Smith } 2937ac90fabeSBarry Smith PetscFunctionReturn(0); 2938ac90fabeSBarry Smith } 2939ac90fabeSBarry Smith 29407087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2941354c94deSBarry Smith { 2942354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2943354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 2944354c94deSBarry Smith PetscInt i,nz; 2945354c94deSBarry Smith PetscScalar *a; 2946354c94deSBarry Smith 2947354c94deSBarry Smith PetscFunctionBegin; 2948354c94deSBarry Smith nz = aij->nz; 2949354c94deSBarry Smith a = aij->a; 29502205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 2951354c94deSBarry Smith #else 2952354c94deSBarry Smith PetscFunctionBegin; 2953354c94deSBarry Smith #endif 2954354c94deSBarry Smith PetscFunctionReturn(0); 2955354c94deSBarry Smith } 2956354c94deSBarry Smith 2957985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2958e34fafa9SBarry Smith { 2959e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2960e34fafa9SBarry Smith PetscErrorCode ierr; 2961d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2962e34fafa9SBarry Smith PetscReal atmp; 2963985db425SBarry Smith PetscScalar *x; 2964e34fafa9SBarry Smith MatScalar *aa; 2965e34fafa9SBarry Smith 2966e34fafa9SBarry Smith PetscFunctionBegin; 2967e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2968e34fafa9SBarry Smith aa = a->a; 2969e34fafa9SBarry Smith ai = a->i; 2970e34fafa9SBarry Smith aj = a->j; 2971e34fafa9SBarry Smith 2972985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2973e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2974e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2975e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2976e34fafa9SBarry Smith for (i=0; i<m; i++) { 2977e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 29789189402eSHong Zhang x[i] = 0.0; 2979e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 2980985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2981985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2982985db425SBarry Smith aa++; aj++; 2983985db425SBarry Smith } 2984985db425SBarry Smith } 2985985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2986985db425SBarry Smith PetscFunctionReturn(0); 2987985db425SBarry Smith } 2988985db425SBarry Smith 2989985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2990985db425SBarry Smith { 2991985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2992985db425SBarry Smith PetscErrorCode ierr; 2993d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2994985db425SBarry Smith PetscScalar *x; 2995985db425SBarry Smith MatScalar *aa; 2996985db425SBarry Smith 2997985db425SBarry Smith PetscFunctionBegin; 2998e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2999985db425SBarry Smith aa = a->a; 3000985db425SBarry Smith ai = a->i; 3001985db425SBarry Smith aj = a->j; 3002985db425SBarry Smith 3003985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3004985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3005985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3006e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3007985db425SBarry Smith for (i=0; i<m; i++) { 3008985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3009d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3010985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3011985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3012985db425SBarry Smith x[i] = 0.0; 3013985db425SBarry Smith if (idx) { 3014985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3015985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 3016985db425SBarry Smith if (aj[j] > j) { 3017985db425SBarry Smith idx[i] = j; 3018985db425SBarry Smith break; 3019985db425SBarry Smith } 3020985db425SBarry Smith } 3021985db425SBarry Smith } 3022985db425SBarry Smith } 3023985db425SBarry Smith for (j=0; j<ncols; j++) { 3024985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3025985db425SBarry Smith aa++; aj++; 3026985db425SBarry Smith } 3027985db425SBarry Smith } 3028985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3029985db425SBarry Smith PetscFunctionReturn(0); 3030985db425SBarry Smith } 3031985db425SBarry Smith 3032c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3033c87e5d42SMatthew Knepley { 3034c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3035c87e5d42SMatthew Knepley PetscErrorCode ierr; 3036c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3037c87e5d42SMatthew Knepley PetscReal atmp; 3038c87e5d42SMatthew Knepley PetscScalar *x; 3039c87e5d42SMatthew Knepley MatScalar *aa; 3040c87e5d42SMatthew Knepley 3041c87e5d42SMatthew Knepley PetscFunctionBegin; 3042e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3043c87e5d42SMatthew Knepley aa = a->a; 3044c87e5d42SMatthew Knepley ai = a->i; 3045c87e5d42SMatthew Knepley aj = a->j; 3046c87e5d42SMatthew Knepley 3047c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3048c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3049c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 305060e0710aSBarry 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); 3051c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3052c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3053289a08f5SMatthew Knepley if (ncols) { 3054289a08f5SMatthew Knepley /* Get first nonzero */ 3055289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 3056289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 30572205254eSKarl Rupp if (atmp > 1.0e-12) { 30582205254eSKarl Rupp x[i] = atmp; 30592205254eSKarl Rupp if (idx) idx[i] = aj[j]; 30602205254eSKarl Rupp break; 30612205254eSKarl Rupp } 3062289a08f5SMatthew Knepley } 306312431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 3064289a08f5SMatthew Knepley } else { 3065289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 3066289a08f5SMatthew Knepley } 3067c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 3068c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 3069289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3070c87e5d42SMatthew Knepley aa++; aj++; 3071c87e5d42SMatthew Knepley } 3072c87e5d42SMatthew Knepley } 3073c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3074c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3075c87e5d42SMatthew Knepley } 3076c87e5d42SMatthew Knepley 3077985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3078985db425SBarry Smith { 3079985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3080985db425SBarry Smith PetscErrorCode ierr; 3081d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3082d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3083985db425SBarry Smith PetscScalar *x; 3084d9ca1df4SBarry Smith const MatScalar *aa; 3085985db425SBarry Smith 3086985db425SBarry Smith PetscFunctionBegin; 3087e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3088985db425SBarry Smith aa = a->a; 3089985db425SBarry Smith ai = a->i; 3090985db425SBarry Smith aj = a->j; 3091985db425SBarry Smith 3092985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3093985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3094985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3095e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3096985db425SBarry Smith for (i=0; i<m; i++) { 3097985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3098d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3099985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3100985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3101985db425SBarry Smith x[i] = 0.0; 3102985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3103985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3104985db425SBarry Smith for (j=0; j<ncols; j++) { 3105985db425SBarry Smith if (aj[j] > j) { 3106985db425SBarry Smith idx[i] = j; 3107985db425SBarry Smith break; 3108985db425SBarry Smith } 3109985db425SBarry Smith } 3110985db425SBarry Smith } 3111985db425SBarry Smith } 3112985db425SBarry Smith for (j=0; j<ncols; j++) { 3113985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3114985db425SBarry Smith aa++; aj++; 3115e34fafa9SBarry Smith } 3116e34fafa9SBarry Smith } 3117e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3118e34fafa9SBarry Smith PetscFunctionReturn(0); 3119e34fafa9SBarry Smith } 3120bbead8a2SBarry Smith 3121713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3122bbead8a2SBarry Smith { 3123bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3124bbead8a2SBarry Smith PetscErrorCode ierr; 312533d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3126bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 31270da83c2eSBarry Smith const PetscReal shift = 0.0; 31281a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3129bbead8a2SBarry Smith 3130bbead8a2SBarry Smith PetscFunctionBegin; 3131a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 31324a0d0026SBarry Smith if (a->ibdiagvalid) { 31334a0d0026SBarry Smith if (values) *values = a->ibdiag; 31344a0d0026SBarry Smith PetscFunctionReturn(0); 31354a0d0026SBarry Smith } 3136bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3137bbead8a2SBarry Smith if (!a->ibdiag) { 3138785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 31393bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3140bbead8a2SBarry Smith } 3141bbead8a2SBarry Smith diag = a->ibdiag; 3142bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3143bbead8a2SBarry Smith /* factor and invert each block */ 3144bbead8a2SBarry Smith switch (bs) { 3145bbead8a2SBarry Smith case 1: 3146bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3147bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3148ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3149ec1892c8SHong Zhang if (allowzeropivot) { 31507b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 31517b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 31527b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 31537b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 31547b6c816cSBarry 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); 3155ec1892c8SHong Zhang } 3156bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3157bbead8a2SBarry Smith } 3158bbead8a2SBarry Smith break; 3159bbead8a2SBarry Smith case 2: 3160bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3161bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3162bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3163a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 31647b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 316596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3166bbead8a2SBarry Smith diag += 4; 3167bbead8a2SBarry Smith } 3168bbead8a2SBarry Smith break; 3169bbead8a2SBarry Smith case 3: 3170bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3171bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3172bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3173a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 31747b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 317596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3176bbead8a2SBarry Smith diag += 9; 3177bbead8a2SBarry Smith } 3178bbead8a2SBarry Smith break; 3179bbead8a2SBarry Smith case 4: 3180bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3181bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3182bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3183a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 31847b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 318596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3186bbead8a2SBarry Smith diag += 16; 3187bbead8a2SBarry Smith } 3188bbead8a2SBarry Smith break; 3189bbead8a2SBarry Smith case 5: 3190bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3191bbead8a2SBarry 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; 3192bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3193a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 31947b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 319596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3196bbead8a2SBarry Smith diag += 25; 3197bbead8a2SBarry Smith } 3198bbead8a2SBarry Smith break; 3199bbead8a2SBarry Smith case 6: 3200bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3201bbead8a2SBarry 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; 3202bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3203a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32047b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 320596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3206bbead8a2SBarry Smith diag += 36; 3207bbead8a2SBarry Smith } 3208bbead8a2SBarry Smith break; 3209bbead8a2SBarry Smith case 7: 3210bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3211bbead8a2SBarry 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; 3212bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3213a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32147b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 321596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3216bbead8a2SBarry Smith diag += 49; 3217bbead8a2SBarry Smith } 3218bbead8a2SBarry Smith break; 3219bbead8a2SBarry Smith default: 3220dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3221bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3222bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3223bbead8a2SBarry Smith IJ[j] = bs*i + j; 3224bbead8a2SBarry Smith } 3225bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 32265f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 32277b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 322896b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3229bbead8a2SBarry Smith diag += bs2; 3230bbead8a2SBarry Smith } 3231bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3232bbead8a2SBarry Smith } 3233bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3234bbead8a2SBarry Smith PetscFunctionReturn(0); 3235bbead8a2SBarry Smith } 3236bbead8a2SBarry Smith 323773a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 323873a71a0fSBarry Smith { 323973a71a0fSBarry Smith PetscErrorCode ierr; 324073a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 324173a71a0fSBarry Smith PetscScalar a; 324273a71a0fSBarry Smith PetscInt m,n,i,j,col; 324373a71a0fSBarry Smith 324473a71a0fSBarry Smith PetscFunctionBegin; 324573a71a0fSBarry Smith if (!x->assembled) { 324673a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 324773a71a0fSBarry Smith for (i=0; i<m; i++) { 324873a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 324973a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 325073a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 325173a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 325273a71a0fSBarry Smith } 325373a71a0fSBarry Smith } 3254e2ce353bSJunchao Zhang } else { 3255e2ce353bSJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aij->a+i);CHKERRQ(ierr);} 3256e2ce353bSJunchao Zhang } 325773a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 325873a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 325973a71a0fSBarry Smith PetscFunctionReturn(0); 326073a71a0fSBarry Smith } 326173a71a0fSBarry Smith 3262679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3263679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3264679944adSJunchao Zhang { 3265679944adSJunchao Zhang PetscErrorCode ierr; 3266679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3267679944adSJunchao Zhang PetscScalar a; 3268679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3269679944adSJunchao Zhang 3270679944adSJunchao Zhang PetscFunctionBegin; 3271679944adSJunchao Zhang nskip = high - low; 3272679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3273679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3274679944adSJunchao Zhang for (i=0; i<m; i++) { 3275679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3276679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3277679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3278679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3279679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3280679944adSJunchao Zhang } 3281e2ce353bSJunchao Zhang } 3282679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3283679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3284679944adSJunchao Zhang PetscFunctionReturn(0); 3285679944adSJunchao Zhang } 3286679944adSJunchao Zhang 3287679944adSJunchao Zhang 3288682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 32890a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3290cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3291cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3292cb5b572fSBarry Smith MatMult_SeqAIJ, 329397304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 32947c922b88SBarry Smith MatMultTranspose_SeqAIJ, 32957c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3296db4efbfdSBarry Smith 0, 3297db4efbfdSBarry Smith 0, 3298db4efbfdSBarry Smith 0, 3299db4efbfdSBarry Smith /* 10*/ 0, 3300cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3301cb5b572fSBarry Smith 0, 330241f059aeSBarry Smith MatSOR_SeqAIJ, 330391e9d3e2SHong Zhang MatTranspose_SeqAIJ, 330497304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3305cb5b572fSBarry Smith MatEqual_SeqAIJ, 3306cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3307cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3308cb5b572fSBarry Smith MatNorm_SeqAIJ, 330997304618SKris Buschelman /* 20*/ 0, 3310cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3311cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3312cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3313d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3314db4efbfdSBarry Smith 0, 3315db4efbfdSBarry Smith 0, 3316db4efbfdSBarry Smith 0, 3317db4efbfdSBarry Smith 0, 33184994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3319db4efbfdSBarry Smith 0, 3320db4efbfdSBarry Smith 0, 33218c778c55SBarry Smith 0, 33228c778c55SBarry Smith 0, 3323d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3324cb5b572fSBarry Smith 0, 3325cb5b572fSBarry Smith 0, 3326cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3327cb5b572fSBarry Smith 0, 3328d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 33297dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3330cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3331cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3332cb5b572fSBarry Smith MatCopy_SeqAIJ, 3333d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3334cb5b572fSBarry Smith MatScale_SeqAIJ, 33357d68702bSBarry Smith MatShift_SeqAIJ, 333679299369SBarry Smith MatDiagonalSet_SeqAIJ, 33376e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 333873a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 33393b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 33403b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 33413b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3342a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 334393dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3344b9617806SBarry Smith 0, 33450513a670SBarry Smith 0, 3346cda55fadSBarry Smith MatPermute_SeqAIJ, 3347cda55fadSBarry Smith 0, 3348d519adbfSMatthew Knepley /* 59*/ 0, 3349b9b97703SBarry Smith MatDestroy_SeqAIJ, 3350b9b97703SBarry Smith MatView_SeqAIJ, 3351357abbc8SBarry Smith 0, 3352321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3353321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3354321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3355ee4f033dSBarry Smith 0, 3356ee4f033dSBarry Smith 0, 3357ee4f033dSBarry Smith 0, 3358d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3359c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3360ee4f033dSBarry Smith 0, 3361dcf5cc72SBarry Smith 0, 33622c93a97aSBarry Smith 0, 33632c93a97aSBarry Smith /* 74*/ 0, 33643acb8795SBarry Smith MatFDColoringApply_AIJ, 336597304618SKris Buschelman 0, 336697304618SKris Buschelman 0, 336797304618SKris Buschelman 0, 33686ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 336997304618SKris Buschelman 0, 337097304618SKris Buschelman 0, 337197304618SKris Buschelman 0, 3372bc011b1eSHong Zhang MatLoad_SeqAIJ, 3373d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 33741cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 33756284ec50SHong Zhang 0, 33766284ec50SHong Zhang 0, 3377bc011b1eSHong Zhang 0, 3378d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 337926be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 338026be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 338165e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 33828fa4b5a6SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_SparseAxpy, 33838fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 33846fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 33856fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 33866fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 33872121bac1SHong Zhang 0, 33882121bac1SHong Zhang /* 99*/ 0, 3389609c6c4dSKris Buschelman 0, 3390609c6c4dSKris Buschelman 0, 339187d4246cSBarry Smith MatConjugate_SeqAIJ, 339287d4246cSBarry Smith 0, 3393d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 339499cafbc1SBarry Smith MatRealPart_SeqAIJ, 3395f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3396f5edf698SHong Zhang 0, 33972bebee5dSHong Zhang 0, 3398cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3399985db425SBarry Smith 0, 34002af78befSBarry Smith MatGetRowMin_SeqAIJ, 34012af78befSBarry Smith 0, 3402599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3403d519adbfSMatthew Knepley /*114*/ 0, 3404599ef60dSHong Zhang 0, 34053c2a7987SHong Zhang 0, 3406fe97e370SBarry Smith 0, 3407fbdbba38SShri Abhyankar 0, 3408fbdbba38SShri Abhyankar /*119*/ 0, 3409fbdbba38SShri Abhyankar 0, 3410fbdbba38SShri Abhyankar 0, 341182d44351SHong Zhang 0, 3412b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 34130716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3414bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 341537868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 34160da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 341737868618SMatthew G Knepley 0, 34185df89d91SHong Zhang /*129*/ 0, 341975648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 342075648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 342175648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3422b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3423b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 34242b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 34252b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 34262b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 34273964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 34283964eb88SJed Brown /*139*/0, 3429f9426fe0SMark Adams 0, 34301919a2e2SJed Brown 0, 34313a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 34329c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 34332d033e1fSHong Zhang /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 34342d033e1fSHong Zhang MatDestroySubMatrices_SeqAIJ 34359e29f15eSvictorle }; 343617ab2063SBarry Smith 34377087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3438bef8e0ddSBarry Smith { 3439bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 344097f1f81fSBarry Smith PetscInt i,nz,n; 3441bef8e0ddSBarry Smith 3442bef8e0ddSBarry Smith PetscFunctionBegin; 3443bef8e0ddSBarry Smith nz = aij->maxnz; 3444d0f46423SBarry Smith n = mat->rmap->n; 3445bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3446bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3447bef8e0ddSBarry Smith } 3448bef8e0ddSBarry Smith aij->nz = nz; 3449bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3450bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3451bef8e0ddSBarry Smith } 3452bef8e0ddSBarry Smith PetscFunctionReturn(0); 3453bef8e0ddSBarry Smith } 3454bef8e0ddSBarry Smith 3455a3bb6f32SFande Kong /* 3456e8b528d9SFande Kong * When a sparse matrix has many zero columns, we should compact them out to save the space 3457a3bb6f32SFande Kong * This happens in MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3458a3bb6f32SFande Kong * */ 3459a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3460a3bb6f32SFande Kong { 3461a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3462a3bb6f32SFande Kong PetscTable gid1_lid1; 3463a3bb6f32SFande Kong PetscTablePosition tpos; 3464a3bb6f32SFande Kong PetscInt gid,lid,i,j,ncols,ec; 3465a3bb6f32SFande Kong PetscInt *garray; 3466a3bb6f32SFande Kong PetscErrorCode ierr; 3467a3bb6f32SFande Kong 3468a3bb6f32SFande Kong PetscFunctionBegin; 3469a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3470a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3471a3bb6f32SFande Kong /* use a table */ 3472a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3473a3bb6f32SFande Kong ec = 0; 3474a3bb6f32SFande Kong for (i=0; i<mat->rmap->n; i++) { 3475a3bb6f32SFande Kong ncols = aij->i[i+1] - aij->i[i]; 3476a3bb6f32SFande Kong for (j=0; j<ncols; j++) { 3477a3bb6f32SFande Kong PetscInt data,gid1 = aij->j[aij->i[i] + j] + 1; 3478a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3479a3bb6f32SFande Kong if (!data) { 3480a3bb6f32SFande Kong /* one based table */ 3481a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3482a3bb6f32SFande Kong } 3483a3bb6f32SFande Kong } 3484a3bb6f32SFande Kong } 3485a3bb6f32SFande Kong /* form array of columns we need */ 3486a3bb6f32SFande Kong ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); 3487a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3488a3bb6f32SFande Kong while (tpos) { 3489a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3490a3bb6f32SFande Kong gid--; 3491a3bb6f32SFande Kong lid--; 3492a3bb6f32SFande Kong garray[lid] = gid; 3493a3bb6f32SFande Kong } 3494a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3495a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3496a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3497a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3498a3bb6f32SFande Kong } 3499a3bb6f32SFande Kong /* compact out the extra columns in B */ 3500a3bb6f32SFande Kong for (i=0; i<mat->rmap->n; i++) { 3501a3bb6f32SFande Kong ncols = aij->i[i+1] - aij->i[i]; 3502a3bb6f32SFande Kong for (j=0; j<ncols; j++) { 3503a3bb6f32SFande Kong PetscInt gid1 = aij->j[aij->i[i] + j] + 1; 3504a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3505a3bb6f32SFande Kong lid--; 3506a3bb6f32SFande Kong aij->j[aij->i[i] + j] = lid; 3507a3bb6f32SFande Kong } 3508a3bb6f32SFande Kong } 3509a3bb6f32SFande Kong mat->cmap->n = mat->cmap->N = ec; 3510a3bb6f32SFande Kong mat->cmap->bs = 1; 3511a3bb6f32SFande Kong 3512a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 3513a3bb6f32SFande Kong ierr = PetscLayoutSetUp((mat->cmap));CHKERRQ(ierr); 3514a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3515a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3516a3bb6f32SFande Kong PetscFunctionReturn(0); 3517a3bb6f32SFande Kong } 3518a3bb6f32SFande Kong 3519bef8e0ddSBarry Smith /*@ 3520bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3521bef8e0ddSBarry Smith in the matrix. 3522bef8e0ddSBarry Smith 3523bef8e0ddSBarry Smith Input Parameters: 3524bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3525bef8e0ddSBarry Smith - indices - the column indices 3526bef8e0ddSBarry Smith 352715091d37SBarry Smith Level: advanced 352815091d37SBarry Smith 3529bef8e0ddSBarry Smith Notes: 3530bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3531bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3532bef8e0ddSBarry Smith of the MatSetValues() operation. 3533bef8e0ddSBarry Smith 3534bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3535d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3536bef8e0ddSBarry Smith 3537bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3538bef8e0ddSBarry Smith 3539b9617806SBarry Smith The indices should start with zero, not one. 3540b9617806SBarry Smith 3541bef8e0ddSBarry Smith @*/ 35427087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3543bef8e0ddSBarry Smith { 35444ac538c5SBarry Smith PetscErrorCode ierr; 3545bef8e0ddSBarry Smith 3546bef8e0ddSBarry Smith PetscFunctionBegin; 35470700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 35484482741eSBarry Smith PetscValidPointer(indices,2); 35494ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3550bef8e0ddSBarry Smith PetscFunctionReturn(0); 3551bef8e0ddSBarry Smith } 3552bef8e0ddSBarry Smith 3553be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3554be6bf707SBarry Smith 35557087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3556be6bf707SBarry Smith { 3557be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 35586849ba73SBarry Smith PetscErrorCode ierr; 3559d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3560be6bf707SBarry Smith 3561be6bf707SBarry Smith PetscFunctionBegin; 3562169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3563be6bf707SBarry Smith 3564be6bf707SBarry Smith /* allocate space for values if not already there */ 3565be6bf707SBarry Smith if (!aij->saved_values) { 3566854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 35673bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3568be6bf707SBarry Smith } 3569be6bf707SBarry Smith 3570be6bf707SBarry Smith /* copy values over */ 3571580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3572be6bf707SBarry Smith PetscFunctionReturn(0); 3573be6bf707SBarry Smith } 3574be6bf707SBarry Smith 3575be6bf707SBarry Smith /*@ 3576be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3577be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3578be6bf707SBarry Smith nonlinear portion. 3579be6bf707SBarry Smith 3580be6bf707SBarry Smith Collect on Mat 3581be6bf707SBarry Smith 3582be6bf707SBarry Smith Input Parameters: 35830e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3584be6bf707SBarry Smith 358515091d37SBarry Smith Level: advanced 358615091d37SBarry Smith 3587be6bf707SBarry Smith Common Usage, with SNESSolve(): 3588be6bf707SBarry Smith $ Create Jacobian matrix 3589be6bf707SBarry Smith $ Set linear terms into matrix 3590be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3591be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3592be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3593512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3594be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3595be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3596be6bf707SBarry Smith $ In your Jacobian routine 3597be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3598be6bf707SBarry Smith $ Set nonlinear terms in matrix 3599be6bf707SBarry Smith 3600be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3601be6bf707SBarry Smith $ // build linear portion of Jacobian 3602512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3603be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3604be6bf707SBarry Smith $ loop over nonlinear iterations 3605be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3606be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3607be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3608be6bf707SBarry Smith $ Solve linear system with Jacobian 3609be6bf707SBarry Smith $ endloop 3610be6bf707SBarry Smith 3611be6bf707SBarry Smith Notes: 3612be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3613512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3614be6bf707SBarry Smith calling this routine. 3615be6bf707SBarry Smith 36160c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 36170c468ba9SBarry Smith and does not allocated additional space. 36180c468ba9SBarry Smith 3619be6bf707SBarry Smith .seealso: MatRetrieveValues() 3620be6bf707SBarry Smith 3621be6bf707SBarry Smith @*/ 36227087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3623be6bf707SBarry Smith { 36244ac538c5SBarry Smith PetscErrorCode ierr; 3625be6bf707SBarry Smith 3626be6bf707SBarry Smith PetscFunctionBegin; 36270700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3628e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3629e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 36304ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3631be6bf707SBarry Smith PetscFunctionReturn(0); 3632be6bf707SBarry Smith } 3633be6bf707SBarry Smith 36347087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3635be6bf707SBarry Smith { 3636be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 36376849ba73SBarry Smith PetscErrorCode ierr; 3638d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3639be6bf707SBarry Smith 3640be6bf707SBarry Smith PetscFunctionBegin; 3641169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3642f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3643be6bf707SBarry Smith /* copy values over */ 3644580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3645be6bf707SBarry Smith PetscFunctionReturn(0); 3646be6bf707SBarry Smith } 3647be6bf707SBarry Smith 3648be6bf707SBarry Smith /*@ 3649be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3650be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3651be6bf707SBarry Smith nonlinear portion. 3652be6bf707SBarry Smith 3653be6bf707SBarry Smith Collect on Mat 3654be6bf707SBarry Smith 3655be6bf707SBarry Smith Input Parameters: 3656386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3657be6bf707SBarry Smith 365815091d37SBarry Smith Level: advanced 365915091d37SBarry Smith 3660be6bf707SBarry Smith .seealso: MatStoreValues() 3661be6bf707SBarry Smith 3662be6bf707SBarry Smith @*/ 36637087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3664be6bf707SBarry Smith { 36654ac538c5SBarry Smith PetscErrorCode ierr; 3666be6bf707SBarry Smith 3667be6bf707SBarry Smith PetscFunctionBegin; 36680700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3669e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3670e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 36714ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3672be6bf707SBarry Smith PetscFunctionReturn(0); 3673be6bf707SBarry Smith } 3674be6bf707SBarry Smith 3675f83d6046SBarry Smith 3676be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 367717ab2063SBarry Smith /*@C 3678682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 36790d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 36806e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 368151c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 36822bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 368317ab2063SBarry Smith 3684d083f849SBarry Smith Collective 3685db81eaa0SLois Curfman McInnes 368617ab2063SBarry Smith Input Parameters: 3687db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 368817ab2063SBarry Smith . m - number of rows 368917ab2063SBarry Smith . n - number of columns 369017ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 369151c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 36920298fd71SBarry Smith (possibly different for each row) or NULL 369317ab2063SBarry Smith 369417ab2063SBarry Smith Output Parameter: 3695416022c9SBarry Smith . A - the matrix 369617ab2063SBarry Smith 3697175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3698f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3699175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3700175b88e8SBarry Smith 3701b259b22eSLois Curfman McInnes Notes: 370249a6f317SBarry Smith If nnz is given then nz is ignored 370349a6f317SBarry Smith 370417ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 370517ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 37060002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 370744cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 370817ab2063SBarry Smith 370917ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 37100298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 37113d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 37126da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 371317ab2063SBarry Smith 3714682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 37154fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3716682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 37176c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 37186c7ebb05SLois Curfman McInnes 37196c7ebb05SLois Curfman McInnes Options Database Keys: 3720698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 37219db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 372217ab2063SBarry Smith 3723027ccd11SLois Curfman McInnes Level: intermediate 3724027ccd11SLois Curfman McInnes 372569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 372636db0b34SBarry Smith 372717ab2063SBarry Smith @*/ 37287087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 372917ab2063SBarry Smith { 3730dfbe8321SBarry Smith PetscErrorCode ierr; 37316945ee14SBarry Smith 37323a40ed3dSBarry Smith PetscFunctionBegin; 3733f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3734117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3735c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3736d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3737273d9f13SBarry Smith PetscFunctionReturn(0); 3738273d9f13SBarry Smith } 3739273d9f13SBarry Smith 3740273d9f13SBarry Smith /*@C 3741273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3742273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3743273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3744273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3745273d9f13SBarry Smith 3746d083f849SBarry Smith Collective 3747273d9f13SBarry Smith 3748273d9f13SBarry Smith Input Parameters: 37491c4f3114SJed Brown + B - The matrix 3750273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3751273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 37520298fd71SBarry Smith (possibly different for each row) or NULL 3753273d9f13SBarry Smith 3754273d9f13SBarry Smith Notes: 375549a6f317SBarry Smith If nnz is given then nz is ignored 375649a6f317SBarry Smith 3757273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3758273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3759273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3760273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3761273d9f13SBarry Smith 3762273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 37630298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3764273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3765273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3766273d9f13SBarry Smith 3767aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3768aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3769aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3770aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3771aa95bbe8SBarry Smith 3772a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3773a96a251dSBarry Smith entries or columns indices 3774a96a251dSBarry Smith 3775273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3776273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3777273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3778273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3779273d9f13SBarry Smith 3780273d9f13SBarry Smith Options Database Keys: 3781698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 378247b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3783273d9f13SBarry Smith 3784273d9f13SBarry Smith Level: intermediate 3785273d9f13SBarry Smith 378669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3787273d9f13SBarry Smith 3788273d9f13SBarry Smith @*/ 37897087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3790273d9f13SBarry Smith { 37914ac538c5SBarry Smith PetscErrorCode ierr; 3792a23d5eceSKris Buschelman 3793a23d5eceSKris Buschelman PetscFunctionBegin; 37946ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 37956ba663aaSJed Brown PetscValidType(B,1); 37964ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3797a23d5eceSKris Buschelman PetscFunctionReturn(0); 3798a23d5eceSKris Buschelman } 3799a23d5eceSKris Buschelman 38007087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3801a23d5eceSKris Buschelman { 3802273d9f13SBarry Smith Mat_SeqAIJ *b; 38032576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 38046849ba73SBarry Smith PetscErrorCode ierr; 380597f1f81fSBarry Smith PetscInt i; 3806273d9f13SBarry Smith 3807273d9f13SBarry Smith PetscFunctionBegin; 38082576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3809a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3810c461c341SBarry Smith skipallocation = PETSC_TRUE; 3811c461c341SBarry Smith nz = 0; 3812c461c341SBarry Smith } 381326283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 381426283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3815899cda47SBarry Smith 3816435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 381760e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 3818*071fcb05SBarry Smith #if defined(PETSC_USE_DEBUG) 3819b73539f3SBarry Smith if (nnz) { 3820d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 382160e0710aSBarry 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]); 382260e0710aSBarry 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); 3823b73539f3SBarry Smith } 3824b73539f3SBarry Smith } 3825*071fcb05SBarry Smith #endif 3826b73539f3SBarry Smith 3827273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 38282205254eSKarl Rupp 3829273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3830273d9f13SBarry Smith 3831ab93d7beSBarry Smith if (!skipallocation) { 38322ee49352SLisandro Dalcin if (!b->imax) { 3833*071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 3834*071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 3835*071fcb05SBarry Smith } 3836*071fcb05SBarry Smith if (!b->ilen) { 3837*071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 3838*071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 3839*071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 3840*071fcb05SBarry Smith } else { 3841*071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 38422ee49352SLisandro Dalcin } 3843846b4da1SFande Kong if (!b->ipre) { 3844846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 3845846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 3846846b4da1SFande Kong } 3847273d9f13SBarry Smith if (!nnz) { 3848435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3849c62bd62aSJed Brown else if (nz < 0) nz = 1; 38505d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 3851d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3852d0f46423SBarry Smith nz = nz*B->rmap->n; 3853273d9f13SBarry Smith } else { 3854273d9f13SBarry Smith nz = 0; 3855d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3856273d9f13SBarry Smith } 3857ab93d7beSBarry Smith 3858273d9f13SBarry Smith /* allocate the matrix space */ 385953dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 38602ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3861396832f4SHong Zhang if (B->structure_only) { 38625848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 38635848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 3864396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 3865396832f4SHong Zhang } else { 3866dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 38673bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3868396832f4SHong Zhang } 3869bfeeae90SHong Zhang b->i[0] = 0; 3870d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 38715da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 38725da197adSKris Buschelman } 3873396832f4SHong Zhang if (B->structure_only) { 3874396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 3875396832f4SHong Zhang b->free_a = PETSC_FALSE; 3876396832f4SHong Zhang } else { 3877273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3878e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3879396832f4SHong Zhang } 3880e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3881c461c341SBarry Smith } else { 3882e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3883e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3884c461c341SBarry Smith } 3885273d9f13SBarry Smith 3886846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 3887846b4da1SFande Kong /* reserve user-requested sparsity */ 3888580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 3889846b4da1SFande Kong } 3890846b4da1SFande Kong 3891846b4da1SFande Kong 3892273d9f13SBarry Smith b->nz = 0; 3893273d9f13SBarry Smith b->maxnz = nz; 3894273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 38952205254eSKarl Rupp if (realalloc) { 38962205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 38972205254eSKarl Rupp } 3898cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 3899cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 3900273d9f13SBarry Smith PetscFunctionReturn(0); 3901273d9f13SBarry Smith } 3902273d9f13SBarry Smith 3903846b4da1SFande Kong 3904846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 3905846b4da1SFande Kong { 3906846b4da1SFande Kong Mat_SeqAIJ *a; 3907a5bbaf83SFande Kong PetscInt i; 3908846b4da1SFande Kong PetscErrorCode ierr; 3909846b4da1SFande Kong 3910846b4da1SFande Kong PetscFunctionBegin; 3911846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3912846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 39132c814fdeSFande Kong /* if no saved info, we error out */ 39142c814fdeSFande Kong if (!a->ipre) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 39152c814fdeSFande Kong 39162c814fdeSFande Kong if (!a->i || !a->j || !a->a || !a->imax || !a->ilen) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_NULL,"Memory info is incomplete, and can not reset preallocation \n"); 39172c814fdeSFande Kong 3918580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 3919580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 3920846b4da1SFande Kong a->i[0] = 0; 3921846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 3922846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 3923846b4da1SFande Kong } 3924846b4da1SFande Kong A->preallocated = PETSC_TRUE; 3925846b4da1SFande Kong a->nz = 0; 3926846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 3927846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 3928846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 3929846b4da1SFande Kong A->assembled = PETSC_FALSE; 3930846b4da1SFande Kong PetscFunctionReturn(0); 3931846b4da1SFande Kong } 3932846b4da1SFande Kong 393358d36128SBarry Smith /*@ 3934a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3935a1661176SMatthew Knepley 3936a1661176SMatthew Knepley Input Parameters: 3937a1661176SMatthew Knepley + B - the matrix 3938a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3939a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3940a1661176SMatthew Knepley - v - optional values in the matrix 3941a1661176SMatthew Knepley 3942a1661176SMatthew Knepley Level: developer 3943a1661176SMatthew Knepley 394458d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 394558d36128SBarry Smith 3946c1c1d628SHong Zhang .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ 3947a1661176SMatthew Knepley @*/ 3948a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3949a1661176SMatthew Knepley { 3950a1661176SMatthew Knepley PetscErrorCode ierr; 3951a1661176SMatthew Knepley 3952a1661176SMatthew Knepley PetscFunctionBegin; 39530700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 39546ba663aaSJed Brown PetscValidType(B,1); 39554ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3956a1661176SMatthew Knepley PetscFunctionReturn(0); 3957a1661176SMatthew Knepley } 3958a1661176SMatthew Knepley 39597087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3960a1661176SMatthew Knepley { 3961a1661176SMatthew Knepley PetscInt i; 3962a1661176SMatthew Knepley PetscInt m,n; 3963a1661176SMatthew Knepley PetscInt nz; 3964a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3965a1661176SMatthew Knepley PetscErrorCode ierr; 3966a1661176SMatthew Knepley 3967a1661176SMatthew Knepley PetscFunctionBegin; 396865e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3969779a8d59SSatish Balay 3970779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3971779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3972779a8d59SSatish Balay 3973779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3974854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 3975a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3976b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3977a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 397865e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3979a1661176SMatthew Knepley nnz[i] = nz; 3980a1661176SMatthew Knepley } 3981a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3982a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3983a1661176SMatthew Knepley 3984a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3985*071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 3986a1661176SMatthew Knepley } 3987a1661176SMatthew Knepley 3988a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3989a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3990a1661176SMatthew Knepley 39917827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3992a1661176SMatthew Knepley PetscFunctionReturn(0); 3993a1661176SMatthew Knepley } 3994a1661176SMatthew Knepley 3995c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 3996af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 3997170fe5c8SBarry Smith 3998170fe5c8SBarry Smith /* 3999170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4000170fe5c8SBarry Smith 4001170fe5c8SBarry Smith n p p 4002170fe5c8SBarry Smith ( ) ( ) ( ) 4003170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 4004170fe5c8SBarry Smith ( ) ( ) ( ) 4005170fe5c8SBarry Smith 4006170fe5c8SBarry Smith */ 4007170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4008170fe5c8SBarry Smith { 4009170fe5c8SBarry Smith PetscErrorCode ierr; 4010170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4011170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4012170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 40131de00fd4SBarry Smith PetscInt i,n,m,q,p; 4014170fe5c8SBarry Smith const PetscInt *ii,*idx; 4015170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4016170fe5c8SBarry Smith PetscScalar *c,*c_q; 4017170fe5c8SBarry Smith 4018170fe5c8SBarry Smith PetscFunctionBegin; 4019d0f46423SBarry Smith m = A->rmap->n; 4020d0f46423SBarry Smith n = A->cmap->n; 4021d0f46423SBarry Smith p = B->cmap->n; 4022170fe5c8SBarry Smith a = sub_a->v; 4023170fe5c8SBarry Smith b = sub_b->a; 4024170fe5c8SBarry Smith c = sub_c->v; 4025580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 4026170fe5c8SBarry Smith 4027170fe5c8SBarry Smith ii = sub_b->i; 4028170fe5c8SBarry Smith idx = sub_b->j; 4029170fe5c8SBarry Smith for (i=0; i<n; i++) { 4030170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4031170fe5c8SBarry Smith while (q-->0) { 4032170fe5c8SBarry Smith c_q = c + m*(*idx); 4033170fe5c8SBarry Smith a_q = a + m*i; 4034854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4035170fe5c8SBarry Smith idx++; 4036170fe5c8SBarry Smith b++; 4037170fe5c8SBarry Smith } 4038170fe5c8SBarry Smith } 4039170fe5c8SBarry Smith PetscFunctionReturn(0); 4040170fe5c8SBarry Smith } 4041170fe5c8SBarry Smith 4042170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 4043170fe5c8SBarry Smith { 4044170fe5c8SBarry Smith PetscErrorCode ierr; 4045d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 4046170fe5c8SBarry Smith Mat Cmat; 4047170fe5c8SBarry Smith 4048170fe5c8SBarry Smith PetscFunctionBegin; 404960e0710aSBarry 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); 4050ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 4051170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 405233d57670SJed Brown ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr); 4053170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 40540298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 4055d73949e8SHong Zhang 4056d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 40572205254eSKarl Rupp 4058170fe5c8SBarry Smith *C = Cmat; 4059170fe5c8SBarry Smith PetscFunctionReturn(0); 4060170fe5c8SBarry Smith } 4061170fe5c8SBarry Smith 4062170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 4063150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 4064170fe5c8SBarry Smith { 4065170fe5c8SBarry Smith PetscErrorCode ierr; 4066170fe5c8SBarry Smith 4067170fe5c8SBarry Smith PetscFunctionBegin; 4068170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 40693ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 4070170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 40713ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 4072170fe5c8SBarry Smith } 40733ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 4074170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 40753ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 4076170fe5c8SBarry Smith PetscFunctionReturn(0); 4077170fe5c8SBarry Smith } 4078170fe5c8SBarry Smith 4079170fe5c8SBarry Smith 40800bad9183SKris Buschelman /*MC 4081fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 40820bad9183SKris Buschelman based on compressed sparse row format. 40830bad9183SKris Buschelman 40840bad9183SKris Buschelman Options Database Keys: 40850bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 40860bad9183SKris Buschelman 40870bad9183SKris Buschelman Level: beginner 40880bad9183SKris Buschelman 4089f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 40900bad9183SKris Buschelman M*/ 40910bad9183SKris Buschelman 4092ccd284c7SBarry Smith /*MC 4093ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4094ccd284c7SBarry Smith 4095ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4096ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 4097ccd284c7SBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported 4098ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4099ccd284c7SBarry Smith the above preallocation routines for simplicity. 4100ccd284c7SBarry Smith 4101ccd284c7SBarry Smith Options Database Keys: 4102ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4103ccd284c7SBarry Smith 410495452b02SPatrick Sanan Developer Notes: 4105ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4106ccd284c7SBarry Smith enough exist. 4107ccd284c7SBarry Smith 4108ccd284c7SBarry Smith Level: beginner 4109ccd284c7SBarry Smith 4110ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4111ccd284c7SBarry Smith M*/ 4112ccd284c7SBarry Smith 4113ccd284c7SBarry Smith /*MC 4114ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4115ccd284c7SBarry Smith 4116ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4117ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4118ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4119ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4120ccd284c7SBarry Smith the above preallocation routines for simplicity. 4121ccd284c7SBarry Smith 4122ccd284c7SBarry Smith Options Database Keys: 4123ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4124ccd284c7SBarry Smith 4125ccd284c7SBarry Smith Level: beginner 4126ccd284c7SBarry Smith 4127ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4128ccd284c7SBarry Smith M*/ 4129ccd284c7SBarry Smith 41307906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 41317906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 41327906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 41337906f579SHong Zhang #endif 41347906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 41357906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 41367906f579SHong Zhang PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 41377906f579SHong Zhang #endif 41387906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 41397906f579SHong Zhang 4140d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4141c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 414275d48cdbSStefano Zampini PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat,Mat,MatReuse,PetscReal,Mat*); 41437906f579SHong Zhang 41448c778c55SBarry Smith /*@C 41458397e458SBarry Smith MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored 41468c778c55SBarry Smith 41478c778c55SBarry Smith Not Collective 41488c778c55SBarry Smith 41498c778c55SBarry Smith Input Parameter: 4150579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 41518c778c55SBarry Smith 41528c778c55SBarry Smith Output Parameter: 41538c778c55SBarry Smith . array - pointer to the data 41548c778c55SBarry Smith 41558c778c55SBarry Smith Level: intermediate 41568c778c55SBarry Smith 4157774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 41588c778c55SBarry Smith @*/ 41598c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 41608c778c55SBarry Smith { 41618c778c55SBarry Smith PetscErrorCode ierr; 41628c778c55SBarry Smith 41638c778c55SBarry Smith PetscFunctionBegin; 41648c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 41658c778c55SBarry Smith PetscFunctionReturn(0); 41668c778c55SBarry Smith } 41678c778c55SBarry Smith 416821e72a00SBarry Smith /*@C 416921e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 417021e72a00SBarry Smith 417121e72a00SBarry Smith Not Collective 417221e72a00SBarry Smith 417321e72a00SBarry Smith Input Parameter: 4174579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 417521e72a00SBarry Smith 417621e72a00SBarry Smith Output Parameter: 417721e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 417821e72a00SBarry Smith 417921e72a00SBarry Smith Level: intermediate 418021e72a00SBarry Smith 418121e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 418221e72a00SBarry Smith @*/ 418321e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 418421e72a00SBarry Smith { 418521e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 418621e72a00SBarry Smith 418721e72a00SBarry Smith PetscFunctionBegin; 418821e72a00SBarry Smith *nz = aij->rmax; 418921e72a00SBarry Smith PetscFunctionReturn(0); 419021e72a00SBarry Smith } 419121e72a00SBarry Smith 41928c778c55SBarry Smith /*@C 4193579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 41948c778c55SBarry Smith 41958c778c55SBarry Smith Not Collective 41968c778c55SBarry Smith 41978c778c55SBarry Smith Input Parameters: 4198579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 41998c778c55SBarry Smith . array - pointer to the data 42008c778c55SBarry Smith 42018c778c55SBarry Smith Level: intermediate 42028c778c55SBarry Smith 4203774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 42048c778c55SBarry Smith @*/ 42058c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 42068c778c55SBarry Smith { 42078c778c55SBarry Smith PetscErrorCode ierr; 42088c778c55SBarry Smith 42098c778c55SBarry Smith PetscFunctionBegin; 42108c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 42118c778c55SBarry Smith PetscFunctionReturn(0); 42128c778c55SBarry Smith } 42138c778c55SBarry Smith 421434b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 421502fe1965SBarry Smith PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat); 421602fe1965SBarry Smith #endif 421702fe1965SBarry Smith 42188cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4219273d9f13SBarry Smith { 4220273d9f13SBarry Smith Mat_SeqAIJ *b; 4221dfbe8321SBarry Smith PetscErrorCode ierr; 422238baddfdSBarry Smith PetscMPIInt size; 4223273d9f13SBarry Smith 4224273d9f13SBarry Smith PetscFunctionBegin; 4225ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 4226e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4227273d9f13SBarry Smith 4228b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 42292205254eSKarl Rupp 4230b0a32e0cSBarry Smith B->data = (void*)b; 42312205254eSKarl Rupp 4232549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4233*071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 42342205254eSKarl Rupp 4235416022c9SBarry Smith b->row = 0; 4236416022c9SBarry Smith b->col = 0; 423782bf6240SBarry Smith b->icol = 0; 4238b810aeb4SBarry Smith b->reallocs = 0; 423936db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4240f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4241416022c9SBarry Smith b->nonew = 0; 4242416022c9SBarry Smith b->diag = 0; 4243416022c9SBarry Smith b->solve_work = 0; 42442a1b7f2aSHong Zhang B->spptr = 0; 4245be6bf707SBarry Smith b->saved_values = 0; 4246d7f994e1SBarry Smith b->idiag = 0; 424771f1c65dSBarry Smith b->mdiag = 0; 424871f1c65dSBarry Smith b->ssor_work = 0; 424971f1c65dSBarry Smith b->omega = 1.0; 425071f1c65dSBarry Smith b->fshift = 0.0; 425171f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4252bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4253a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 425417ab2063SBarry Smith 425535d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4256bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4257bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 42588c778c55SBarry Smith 4259b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4260bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4261bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4262b3866ffcSBarry Smith #endif 426317f1a0eaSHong Zhang 4264bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4265bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4266bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4267bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4268bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4269bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 42704dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 42719779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 42724a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4273191b95cbSRichard Tran Mills #endif 427434b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 427502fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 427602fe1965SBarry Smith #endif 4277bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4278af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4279af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4280af8000cdSHong Zhang #endif 428163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 428263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 42833dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr); 428463c07aadSStefano Zampini #endif 4285b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4286d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4287c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4288bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4289bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4290bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4291846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4292bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4293bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 4294bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 4295bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 4296bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 429775d48cdbSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_is_seqaij_C",MatPtAP_IS_XAIJ);CHKERRQ(ierr); 42984108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 429917667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 43004099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 43013a40ed3dSBarry Smith PetscFunctionReturn(0); 430217ab2063SBarry Smith } 430317ab2063SBarry Smith 4304b24902e0SBarry Smith /* 4305b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4306b24902e0SBarry Smith */ 4307ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 430817ab2063SBarry Smith { 4309416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 43106849ba73SBarry Smith PetscErrorCode ierr; 4311*071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 431217ab2063SBarry Smith 43133a40ed3dSBarry Smith PetscFunctionBegin; 4314273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 4315273d9f13SBarry Smith 4316d5f3da31SBarry Smith C->factortype = A->factortype; 4317416022c9SBarry Smith c->row = 0; 4318416022c9SBarry Smith c->col = 0; 431982bf6240SBarry Smith c->icol = 0; 43206ad4291fSHong Zhang c->reallocs = 0; 432117ab2063SBarry Smith 43226ad4291fSHong Zhang C->assembled = PETSC_TRUE; 432317ab2063SBarry Smith 4324aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4325aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4326eec197d1SBarry Smith 4327*071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4328*071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4329*071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4330*071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 43313bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 433217ab2063SBarry Smith 433317ab2063SBarry Smith /* allocate the matrix space */ 4334f77e22a1SHong Zhang if (mallocmatspace) { 4335dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 43363bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 43372205254eSKarl Rupp 4338f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 43392205254eSKarl Rupp 4340580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 434117ab2063SBarry Smith if (m > 0) { 4342580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4343be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 4344580bdb30SBarry Smith ierr = PetscArraycpy(c->a,a->a,a->i[m]);CHKERRQ(ierr); 4345be6bf707SBarry Smith } else { 4346580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 434717ab2063SBarry Smith } 434808480c60SBarry Smith } 4349f77e22a1SHong Zhang } 435017ab2063SBarry Smith 43516ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4352416022c9SBarry Smith c->roworiented = a->roworiented; 4353416022c9SBarry Smith c->nonew = a->nonew; 4354416022c9SBarry Smith if (a->diag) { 4355854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4356*071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 43573bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4358*071fcb05SBarry Smith } else c->diag = NULL; 43592205254eSKarl Rupp 43606ad4291fSHong Zhang c->solve_work = 0; 43616ad4291fSHong Zhang c->saved_values = 0; 43626ad4291fSHong Zhang c->idiag = 0; 436371f1c65dSBarry Smith c->ssor_work = 0; 4364a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4365e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4366e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 43676ad4291fSHong Zhang 4368893ad86cSHong Zhang c->rmax = a->rmax; 4369416022c9SBarry Smith c->nz = a->nz; 43708ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4371273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4372754ec7b1SSatish Balay 43736ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 43746ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4375cd6b891eSBarry Smith if (a->compressedrow.use) { 43766ad4291fSHong Zhang i = a->compressedrow.nrows; 4377dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4378580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4379580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 438027ea64f8SHong Zhang } else { 438127ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 43820298fd71SBarry Smith c->compressedrow.i = NULL; 43830298fd71SBarry Smith c->compressedrow.rindex = NULL; 43846ad4291fSHong Zhang } 4385ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4386e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 43874846f1f5SKris Buschelman 43882205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4389140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 43903a40ed3dSBarry Smith PetscFunctionReturn(0); 439117ab2063SBarry Smith } 439217ab2063SBarry Smith 4393b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4394b24902e0SBarry Smith { 4395b24902e0SBarry Smith PetscErrorCode ierr; 4396b24902e0SBarry Smith 4397b24902e0SBarry Smith PetscFunctionBegin; 4398ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 43994b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4400cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 440133d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4402cfd3f464SBarry Smith } 4403a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4404f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4405b24902e0SBarry Smith PetscFunctionReturn(0); 4406b24902e0SBarry Smith } 4407b24902e0SBarry Smith 4408112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4409fbdbba38SShri Abhyankar { 441052f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 441152f91c60SVaclav Hapla PetscErrorCode ierr; 441252f91c60SVaclav Hapla 441352f91c60SVaclav Hapla PetscFunctionBegin; 441452f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 441552f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4416c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4417c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 441852f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 441952f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 442052f91c60SVaclav Hapla if (isbinary) { 442152f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 442252f91c60SVaclav Hapla } else if (ishdf5) { 442352f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 442452f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 442552f91c60SVaclav Hapla #else 442652f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 442752f91c60SVaclav Hapla #endif 442852f91c60SVaclav Hapla } else { 442952f91c60SVaclav 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); 443052f91c60SVaclav Hapla } 443152f91c60SVaclav Hapla PetscFunctionReturn(0); 443252f91c60SVaclav Hapla } 443352f91c60SVaclav Hapla 443452f91c60SVaclav Hapla PetscErrorCode MatLoad_SeqAIJ_Binary(Mat newMat, PetscViewer viewer) 443552f91c60SVaclav Hapla { 4436fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4437fbdbba38SShri Abhyankar PetscErrorCode ierr; 4438fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4439fbdbba38SShri Abhyankar int fd; 4440fbdbba38SShri Abhyankar PetscMPIInt size; 4441fbdbba38SShri Abhyankar MPI_Comm comm; 44423059b6faSBarry Smith PetscInt bs = newMat->rmap->bs; 4443fbdbba38SShri Abhyankar 4444fbdbba38SShri Abhyankar PetscFunctionBegin; 4445fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4446fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4447fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4448bbead8a2SBarry Smith 44490298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 44500298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4451bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 44523059b6faSBarry Smith if (bs < 0) bs = 1; 44533059b6faSBarry Smith ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr); 4454bbead8a2SBarry Smith 4455fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 44569860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 4457fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4458fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4459fbdbba38SShri Abhyankar 4460bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4461fbdbba38SShri Abhyankar 4462fbdbba38SShri Abhyankar /* read in row lengths */ 4463785e854fSJed Brown ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr); 44649860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,rowlengths,M,NULL,PETSC_INT);CHKERRQ(ierr); 4465fbdbba38SShri Abhyankar 4466fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4467fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 446860e0710aSBarry 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); 4469fbdbba38SShri Abhyankar 4470fbdbba38SShri Abhyankar /* set global size if not set already*/ 4471f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4472fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4473aabbc4fbSShri Abhyankar } else { 44749d36ed5fSBarry Smith /* if sizes and type are already set, check if the matrix global sizes are correct */ 4475fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 44764c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 44774c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 44784c5b953cSHong Zhang } 447960e0710aSBarry 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); 4480aabbc4fbSShri Abhyankar } 4481fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4482fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4483fbdbba38SShri Abhyankar 44849860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 4485fbdbba38SShri Abhyankar 4486fbdbba38SShri Abhyankar /* read in nonzero values */ 44879860990eSLisandro Dalcin ierr = PetscBinaryRead(fd,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4488fbdbba38SShri Abhyankar 4489fbdbba38SShri Abhyankar /* set matrix "i" values */ 4490fbdbba38SShri Abhyankar a->i[0] = 0; 4491fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4492fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4493fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4494fbdbba38SShri Abhyankar } 4495fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4496fbdbba38SShri Abhyankar 4497fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4498fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4499fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4500fbdbba38SShri Abhyankar } 4501fbdbba38SShri Abhyankar 4502ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 45037264ac53SSatish Balay { 45047264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4505dfbe8321SBarry Smith PetscErrorCode ierr; 4506eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4507eeffb40dSHong Zhang PetscInt k; 4508eeffb40dSHong Zhang #endif 45097264ac53SSatish Balay 45103a40ed3dSBarry Smith PetscFunctionBegin; 4511bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4512d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4513ca44d042SBarry Smith *flg = PETSC_FALSE; 4514ca44d042SBarry Smith PetscFunctionReturn(0); 4515bcd2baecSBarry Smith } 45167264ac53SSatish Balay 45177264ac53SSatish Balay /* if the a->i are the same */ 4518580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4519abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 45207264ac53SSatish Balay 45217264ac53SSatish Balay /* if a->j are the same */ 4522580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 4523abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4524bcd2baecSBarry Smith 4525bcd2baecSBarry Smith /* if a->a are the same */ 4526eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4527eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4528eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4529eeffb40dSHong Zhang *flg = PETSC_FALSE; 45303a40ed3dSBarry Smith PetscFunctionReturn(0); 4531eeffb40dSHong Zhang } 4532eeffb40dSHong Zhang } 4533eeffb40dSHong Zhang #else 4534580bdb30SBarry Smith ierr = PetscArraycmp(a->a,b->a,a->nz,flg);CHKERRQ(ierr); 4535eeffb40dSHong Zhang #endif 4536eeffb40dSHong Zhang PetscFunctionReturn(0); 45377264ac53SSatish Balay } 453836db0b34SBarry Smith 453905869f15SSatish Balay /*@ 454036db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 454136db0b34SBarry Smith provided by the user. 454236db0b34SBarry Smith 4543d083f849SBarry Smith Collective 454436db0b34SBarry Smith 454536db0b34SBarry Smith Input Parameters: 454636db0b34SBarry Smith + comm - must be an MPI communicator of size 1 454736db0b34SBarry Smith . m - number of rows 454836db0b34SBarry Smith . n - number of columns 4549483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 455036db0b34SBarry Smith . j - column indices 455136db0b34SBarry Smith - a - matrix values 455236db0b34SBarry Smith 455336db0b34SBarry Smith Output Parameter: 455436db0b34SBarry Smith . mat - the matrix 455536db0b34SBarry Smith 455636db0b34SBarry Smith Level: intermediate 455736db0b34SBarry Smith 455836db0b34SBarry Smith Notes: 45590551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4560292fb18eSBarry Smith once the matrix is destroyed and not before 456136db0b34SBarry Smith 456236db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 456336db0b34SBarry Smith 4564bfeeae90SHong Zhang The i and j indices are 0 based 456536db0b34SBarry Smith 4566a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4567a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 45688eef79e4SBarry Smith as shown 4569a4552177SSatish Balay 45708eef79e4SBarry Smith $ 1 0 0 45718eef79e4SBarry Smith $ 2 0 3 45728eef79e4SBarry Smith $ 4 5 6 45738eef79e4SBarry Smith $ 45748eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 45758eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 45768eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4577a4552177SSatish Balay 45789985e31cSBarry Smith 457969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 458036db0b34SBarry Smith 458136db0b34SBarry Smith @*/ 4582c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 458336db0b34SBarry Smith { 4584dfbe8321SBarry Smith PetscErrorCode ierr; 4585cbcfb4deSHong Zhang PetscInt ii; 458636db0b34SBarry Smith Mat_SeqAIJ *aij; 4587cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4588cbcfb4deSHong Zhang PetscInt jj; 4589cbcfb4deSHong Zhang #endif 459036db0b34SBarry Smith 459136db0b34SBarry Smith PetscFunctionBegin; 459241096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4593f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4594f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4595a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4596ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4597ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4598ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4599*071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 4600*071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 4601ab93d7beSBarry Smith 460236db0b34SBarry Smith aij->i = i; 460336db0b34SBarry Smith aij->j = j; 460436db0b34SBarry Smith aij->a = a; 460536db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 460636db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4607e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4608e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 460936db0b34SBarry Smith 461036db0b34SBarry Smith for (ii=0; ii<m; ii++) { 461136db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 46122515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 461360e0710aSBarry 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]); 46149985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4615a061629eSStefano 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); 4616a061629eSStefano 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); 46179985e31cSBarry Smith } 461836db0b34SBarry Smith #endif 461936db0b34SBarry Smith } 46202515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 462136db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 462260e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 462360e0710aSBarry 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]); 462436db0b34SBarry Smith } 462536db0b34SBarry Smith #endif 462636db0b34SBarry Smith 4627b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4628b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 462936db0b34SBarry Smith PetscFunctionReturn(0); 463036db0b34SBarry Smith } 463180ef6e79SMatthew G Knepley /*@C 4632d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 46338a0b0e6bSVictor Minden provided by the user. 46348a0b0e6bSVictor Minden 4635d083f849SBarry Smith Collective 46368a0b0e6bSVictor Minden 46378a0b0e6bSVictor Minden Input Parameters: 46388a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 46398a0b0e6bSVictor Minden . m - number of rows 46408a0b0e6bSVictor Minden . n - number of columns 46418a0b0e6bSVictor Minden . i - row indices 46428a0b0e6bSVictor Minden . j - column indices 46431230e6d1SVictor Minden . a - matrix values 46441230e6d1SVictor Minden . nz - number of nonzeros 46451230e6d1SVictor Minden - idx - 0 or 1 based 46468a0b0e6bSVictor Minden 46478a0b0e6bSVictor Minden Output Parameter: 46488a0b0e6bSVictor Minden . mat - the matrix 46498a0b0e6bSVictor Minden 46508a0b0e6bSVictor Minden Level: intermediate 46518a0b0e6bSVictor Minden 46528a0b0e6bSVictor Minden Notes: 46538a0b0e6bSVictor Minden The i and j indices are 0 based 46548a0b0e6bSVictor Minden 46558a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 46568a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 46578a0b0e6bSVictor Minden as shown: 46588a0b0e6bSVictor Minden 46598a0b0e6bSVictor Minden 1 0 0 46608a0b0e6bSVictor Minden 2 0 3 46618a0b0e6bSVictor Minden 4 5 6 46628a0b0e6bSVictor Minden 46638a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 46648a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 46658a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 46668a0b0e6bSVictor Minden 46678a0b0e6bSVictor Minden 466869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 46698a0b0e6bSVictor Minden 46708a0b0e6bSVictor Minden @*/ 4671c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 46728a0b0e6bSVictor Minden { 46738a0b0e6bSVictor Minden PetscErrorCode ierr; 4674d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 46758a0b0e6bSVictor Minden 46768a0b0e6bSVictor Minden 46778a0b0e6bSVictor Minden PetscFunctionBegin; 46781795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 46791230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4680c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 46811230e6d1SVictor Minden } 46828a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 46838a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 46848a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 46851230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 46861230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 46871230e6d1SVictor Minden if (idx) { 46881230e6d1SVictor Minden row = i[ii] - 1; 46891230e6d1SVictor Minden col = j[ii] - 1; 46901230e6d1SVictor Minden } else { 46911230e6d1SVictor Minden row = i[ii]; 46921230e6d1SVictor Minden col = j[ii]; 46938a0b0e6bSVictor Minden } 46941230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 46958a0b0e6bSVictor Minden } 46968a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46978a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4698d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 46998a0b0e6bSVictor Minden PetscFunctionReturn(0); 47008a0b0e6bSVictor Minden } 470136db0b34SBarry Smith 4702acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4703acf2f550SJed Brown { 4704acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4705acf2f550SJed Brown PetscErrorCode ierr; 4706acf2f550SJed Brown 4707acf2f550SJed Brown PetscFunctionBegin; 4708acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4709acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 47102205254eSKarl Rupp 4711acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4712acf2f550SJed Brown PetscFunctionReturn(0); 4713acf2f550SJed Brown } 4714acf2f550SJed Brown 47159c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 47169c8f2541SHong Zhang { 47179c8f2541SHong Zhang PetscErrorCode ierr; 47188761c3d6SHong Zhang PetscMPIInt size; 47199c8f2541SHong Zhang 47209c8f2541SHong Zhang PetscFunctionBegin; 47218761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 47227bbdc51dSHong Zhang if (size == 1) { 47237bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 47247bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 47257bbdc51dSHong Zhang } else { 47268761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 47277bbdc51dSHong Zhang } 47288761c3d6SHong Zhang } else { 47299c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 47308761c3d6SHong Zhang } 47319c8f2541SHong Zhang PetscFunctionReturn(0); 47329c8f2541SHong Zhang } 47339c8f2541SHong Zhang 473481824310SBarry Smith /* 473553dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 473653dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 473753dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 473853dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 473953dd7562SDmitry Karpeev */ 474053dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 474153dd7562SDmitry Karpeev { 474253dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 474353dd7562SDmitry Karpeev PetscErrorCode ierr; 474453dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 474553dd7562SDmitry Karpeev PetscBool seqaij; 474653dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 474753dd7562SDmitry Karpeev PetscScalar v; 474853dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 474953dd7562SDmitry Karpeev 475053dd7562SDmitry Karpeev PetscFunctionBegin; 475153dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 475253dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 47534099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 475453dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 475553dd7562SDmitry Karpeev if (rowemb) { 475653dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 475753dd7562SDmitry 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); 475853dd7562SDmitry Karpeev } else { 47596c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 476053dd7562SDmitry Karpeev } 476153dd7562SDmitry Karpeev if (colemb) { 476253dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 476353dd7562SDmitry 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); 476453dd7562SDmitry Karpeev } else { 476553dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 476653dd7562SDmitry Karpeev } 476753dd7562SDmitry Karpeev 476853dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 476953dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 477053dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 477153dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 477253dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 477353dd7562SDmitry Karpeev } 477453dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 477553dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 477653dd7562SDmitry Karpeev } 477753dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 477853dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 477953dd7562SDmitry Karpeev } 478053dd7562SDmitry Karpeev count = 0; 478153dd7562SDmitry Karpeev rowindices = NULL; 478253dd7562SDmitry Karpeev colindices = NULL; 478353dd7562SDmitry Karpeev if (rowemb) { 478453dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 478553dd7562SDmitry Karpeev } 478653dd7562SDmitry Karpeev if (colemb) { 478753dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 478853dd7562SDmitry Karpeev } 478953dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 479053dd7562SDmitry Karpeev PetscInt row; 479153dd7562SDmitry Karpeev row = i; 479253dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 479353dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 479453dd7562SDmitry Karpeev PetscInt col; 479553dd7562SDmitry Karpeev col = Baij->j[count]; 479653dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 479753dd7562SDmitry Karpeev v = Baij->a[count]; 479853dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 479953dd7562SDmitry Karpeev ++count; 480053dd7562SDmitry Karpeev } 480153dd7562SDmitry Karpeev } 480253dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 480353dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 480453dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 480553dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 480653dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 480753dd7562SDmitry Karpeev PetscFunctionReturn(0); 480853dd7562SDmitry Karpeev } 480953dd7562SDmitry Karpeev 48104099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 48114099cc6bSBarry Smith 48124099cc6bSBarry Smith /*@C 48134099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 48144099cc6bSBarry Smith 48154099cc6bSBarry Smith Collective on Mat 48164099cc6bSBarry Smith 48174099cc6bSBarry Smith Input Parameters: 48184099cc6bSBarry Smith + mat - the matrix object 48194099cc6bSBarry Smith - matype - matrix type 48204099cc6bSBarry Smith 48214099cc6bSBarry Smith Options Database Key: 48224099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 48234099cc6bSBarry Smith 48244099cc6bSBarry Smith 48254099cc6bSBarry Smith Level: intermediate 48264099cc6bSBarry Smith 48274099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 48284099cc6bSBarry Smith @*/ 48294099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 48304099cc6bSBarry Smith { 4831fd9d3c67SJed Brown PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*); 48324099cc6bSBarry Smith PetscBool sametype; 48334099cc6bSBarry Smith 48344099cc6bSBarry Smith PetscFunctionBegin; 48354099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 48364099cc6bSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 48374099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 48384099cc6bSBarry Smith 48394099cc6bSBarry Smith ierr = PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr); 48404099cc6bSBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 48414099cc6bSBarry Smith ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 48424099cc6bSBarry Smith PetscFunctionReturn(0); 48434099cc6bSBarry Smith } 48444099cc6bSBarry Smith 48454099cc6bSBarry Smith 48464099cc6bSBarry Smith /*@C 48474099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 48484099cc6bSBarry Smith 48494099cc6bSBarry Smith Not Collective 48504099cc6bSBarry Smith 48514099cc6bSBarry Smith Input Parameters: 48524099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 48534099cc6bSBarry Smith - function - routine to convert to subtype 48544099cc6bSBarry Smith 48554099cc6bSBarry Smith Notes: 48564099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 48574099cc6bSBarry Smith 48584099cc6bSBarry Smith 48594099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 48604099cc6bSBarry Smith $ -mat_seqaij_type my_mat 48614099cc6bSBarry Smith 48624099cc6bSBarry Smith Level: advanced 48634099cc6bSBarry Smith 48644099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 48654099cc6bSBarry Smith 48664099cc6bSBarry Smith 48674099cc6bSBarry Smith Level: advanced 48684099cc6bSBarry Smith @*/ 4869388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 48704099cc6bSBarry Smith { 48714099cc6bSBarry Smith PetscErrorCode ierr; 48724099cc6bSBarry Smith 48734099cc6bSBarry Smith PetscFunctionBegin; 48749cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 48754099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 48764099cc6bSBarry Smith PetscFunctionReturn(0); 48774099cc6bSBarry Smith } 48784099cc6bSBarry Smith 48794099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 48804099cc6bSBarry Smith 48814099cc6bSBarry Smith /*@C 48824099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 48834099cc6bSBarry Smith 48844099cc6bSBarry Smith Not Collective 48854099cc6bSBarry Smith 48864099cc6bSBarry Smith Level: advanced 48874099cc6bSBarry Smith 48884099cc6bSBarry Smith Developers Note: CUSP and CUSPARSE do not yet support the MatConvert_SeqAIJ..() paradigm and thus cannot be registered here 48894099cc6bSBarry Smith 48904099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 48914099cc6bSBarry Smith @*/ 48924099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 48934099cc6bSBarry Smith { 48944099cc6bSBarry Smith PetscErrorCode ierr; 48954099cc6bSBarry Smith 48964099cc6bSBarry Smith PetscFunctionBegin; 48974099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 48984099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 48994099cc6bSBarry Smith 49004099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 49014099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 49024dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 49039779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 49046b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4905485f9817SRichard Tran Mills #endif 49064099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 49074099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 49084099cc6bSBarry Smith #endif 49094099cc6bSBarry Smith PetscFunctionReturn(0); 49104099cc6bSBarry Smith } 491153dd7562SDmitry Karpeev 491253dd7562SDmitry Karpeev /* 491381824310SBarry Smith Special version for direct calls from Fortran 491481824310SBarry Smith */ 4915af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 491681824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 491781824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 491881824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 491981824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 492081824310SBarry Smith #endif 492181824310SBarry Smith 492281824310SBarry Smith /* Change these macros so can be used in void function */ 492381824310SBarry Smith #undef CHKERRQ 4924ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 492581824310SBarry Smith #undef SETERRQ2 4926e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 49274994cf47SJed Brown #undef SETERRQ3 49284994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 492981824310SBarry Smith 49308cc058d9SJed 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) 493181824310SBarry Smith { 493281824310SBarry Smith Mat A = *AA; 493381824310SBarry Smith PetscInt m = *mm, n = *nn; 493481824310SBarry Smith InsertMode is = *isis; 493581824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 493681824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 493781824310SBarry Smith PetscInt *imax,*ai,*ailen; 493881824310SBarry Smith PetscErrorCode ierr; 493981824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 494054f21887SBarry Smith MatScalar *ap,value,*aa; 4941ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4942ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 494381824310SBarry Smith 494481824310SBarry Smith PetscFunctionBegin; 49454994cf47SJed Brown MatCheckPreallocated(A,1); 494681824310SBarry Smith imax = a->imax; 494781824310SBarry Smith ai = a->i; 494881824310SBarry Smith ailen = a->ilen; 494981824310SBarry Smith aj = a->j; 495081824310SBarry Smith aa = a->a; 495181824310SBarry Smith 495281824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 495381824310SBarry Smith row = im[k]; 495481824310SBarry Smith if (row < 0) continue; 495581824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4956ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 495781824310SBarry Smith #endif 495881824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 495981824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 496081824310SBarry Smith low = 0; 496181824310SBarry Smith high = nrow; 496281824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 496381824310SBarry Smith if (in[l] < 0) continue; 496481824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4965ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 496681824310SBarry Smith #endif 496781824310SBarry Smith col = in[l]; 49682205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 49692205254eSKarl Rupp else value = v[k + l*m]; 49702205254eSKarl Rupp 497181824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 497281824310SBarry Smith 49732205254eSKarl Rupp if (col <= lastcol) low = 0; 49742205254eSKarl Rupp else high = nrow; 497581824310SBarry Smith lastcol = col; 497681824310SBarry Smith while (high-low > 5) { 497781824310SBarry Smith t = (low+high)/2; 497881824310SBarry Smith if (rp[t] > col) high = t; 497981824310SBarry Smith else low = t; 498081824310SBarry Smith } 498181824310SBarry Smith for (i=low; i<high; i++) { 498281824310SBarry Smith if (rp[i] > col) break; 498381824310SBarry Smith if (rp[i] == col) { 498481824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 498581824310SBarry Smith else ap[i] = value; 498681824310SBarry Smith goto noinsert; 498781824310SBarry Smith } 498881824310SBarry Smith } 498981824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 499081824310SBarry Smith if (nonew == 1) goto noinsert; 4991ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4992fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 499381824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 499481824310SBarry Smith /* shift up all the later entries in this row */ 499581824310SBarry Smith for (ii=N; ii>=i; ii--) { 499681824310SBarry Smith rp[ii+1] = rp[ii]; 499781824310SBarry Smith ap[ii+1] = ap[ii]; 499881824310SBarry Smith } 499981824310SBarry Smith rp[i] = col; 500081824310SBarry Smith ap[i] = value; 5001e56f5c9eSBarry Smith A->nonzerostate++; 500281824310SBarry Smith noinsert:; 500381824310SBarry Smith low = i + 1; 500481824310SBarry Smith } 500581824310SBarry Smith ailen[row] = nrow; 500681824310SBarry Smith } 500781824310SBarry Smith PetscFunctionReturnVoid(); 500881824310SBarry Smith } 5009