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 130716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms) 140716a85fSBarry Smith { 150716a85fSBarry Smith PetscErrorCode ierr; 160716a85fSBarry Smith PetscInt i,m,n; 170716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 180716a85fSBarry Smith 190716a85fSBarry Smith PetscFunctionBegin; 200716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 210716a85fSBarry Smith ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr); 220716a85fSBarry Smith if (type == NORM_2) { 230716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 240716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 250716a85fSBarry Smith } 260716a85fSBarry Smith } else if (type == NORM_1) { 270716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 280716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]); 290716a85fSBarry Smith } 300716a85fSBarry Smith } else if (type == NORM_INFINITY) { 310716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 320716a85fSBarry Smith norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]); 330716a85fSBarry Smith } 340716a85fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType"); 350716a85fSBarry Smith 360716a85fSBarry Smith if (type == NORM_2) { 378f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 380716a85fSBarry Smith } 390716a85fSBarry Smith PetscFunctionReturn(0); 400716a85fSBarry Smith } 410716a85fSBarry Smith 423a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 433a062f41SBarry Smith { 443a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 453a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 463a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 473a062f41SBarry Smith PetscInt *rows; 483a062f41SBarry Smith PetscErrorCode ierr; 493a062f41SBarry Smith 503a062f41SBarry Smith PetscFunctionBegin; 513a062f41SBarry Smith for (i=0; i<m; i++) { 523a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 533a062f41SBarry Smith cnt++; 543a062f41SBarry Smith } 553a062f41SBarry Smith } 563a062f41SBarry Smith ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 573a062f41SBarry Smith cnt = 0; 583a062f41SBarry Smith for (i=0; i<m; i++) { 593a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 603a062f41SBarry Smith rows[cnt] = i; 613a062f41SBarry Smith cnt++; 623a062f41SBarry Smith } 633a062f41SBarry Smith } 643a062f41SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr); 653a062f41SBarry Smith PetscFunctionReturn(0); 663a062f41SBarry Smith } 673a062f41SBarry Smith 68f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 696ce1633cSBarry Smith { 706ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 716ce1633cSBarry Smith const MatScalar *aa = a->a; 726ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 73b2db7409Sstefano_zampini const PetscInt *ii = a->i,*jj = a->j,*diag; 746ce1633cSBarry Smith PetscInt *rows; 756ce1633cSBarry Smith PetscErrorCode ierr; 766ce1633cSBarry Smith 776ce1633cSBarry Smith PetscFunctionBegin; 786ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 796ce1633cSBarry Smith diag = a->diag; 806ce1633cSBarry Smith for (i=0; i<m; i++) { 81b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 826ce1633cSBarry Smith cnt++; 836ce1633cSBarry Smith } 846ce1633cSBarry Smith } 85785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 866ce1633cSBarry Smith cnt = 0; 876ce1633cSBarry Smith for (i=0; i<m; i++) { 88b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 896ce1633cSBarry Smith rows[cnt++] = i; 906ce1633cSBarry Smith } 916ce1633cSBarry Smith } 92f1f41ecbSJed Brown *nrows = cnt; 93f1f41ecbSJed Brown *zrows = rows; 94f1f41ecbSJed Brown PetscFunctionReturn(0); 95f1f41ecbSJed Brown } 96f1f41ecbSJed Brown 97f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 98f1f41ecbSJed Brown { 99f1f41ecbSJed Brown PetscInt nrows,*rows; 100f1f41ecbSJed Brown PetscErrorCode ierr; 101f1f41ecbSJed Brown 102f1f41ecbSJed Brown PetscFunctionBegin; 1030298fd71SBarry Smith *zrows = NULL; 104f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 105ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1066ce1633cSBarry Smith PetscFunctionReturn(0); 1076ce1633cSBarry Smith } 1086ce1633cSBarry Smith 109b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 110b3a44c85SBarry Smith { 111b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 112b3a44c85SBarry Smith const MatScalar *aa; 113b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 114b3a44c85SBarry Smith const PetscInt *ii; 115b3a44c85SBarry Smith PetscInt n,i,j,*rows; 116b3a44c85SBarry Smith PetscErrorCode ierr; 117b3a44c85SBarry Smith 118b3a44c85SBarry Smith PetscFunctionBegin; 119b3a44c85SBarry Smith *keptrows = 0; 120b3a44c85SBarry Smith ii = a->i; 121b3a44c85SBarry Smith for (i=0; i<m; i++) { 122b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 123b3a44c85SBarry Smith if (!n) { 124b3a44c85SBarry Smith cnt++; 125b3a44c85SBarry Smith goto ok1; 126b3a44c85SBarry Smith } 127b3a44c85SBarry Smith aa = a->a + ii[i]; 128b3a44c85SBarry Smith for (j=0; j<n; j++) { 129b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 130b3a44c85SBarry Smith } 131b3a44c85SBarry Smith cnt++; 132b3a44c85SBarry Smith ok1:; 133b3a44c85SBarry Smith } 134b3a44c85SBarry Smith if (!cnt) PetscFunctionReturn(0); 135854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr); 136b3a44c85SBarry Smith cnt = 0; 137b3a44c85SBarry Smith for (i=0; i<m; i++) { 138b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 139b3a44c85SBarry Smith if (!n) continue; 140b3a44c85SBarry Smith aa = a->a + ii[i]; 141b3a44c85SBarry Smith for (j=0; j<n; j++) { 142b3a44c85SBarry Smith if (aa[j] != 0.0) { 143b3a44c85SBarry Smith rows[cnt++] = i; 144b3a44c85SBarry Smith break; 145b3a44c85SBarry Smith } 146b3a44c85SBarry Smith } 147b3a44c85SBarry Smith } 148b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 149b3a44c85SBarry Smith PetscFunctionReturn(0); 150b3a44c85SBarry Smith } 151b3a44c85SBarry Smith 1527087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 15379299369SBarry Smith { 15479299369SBarry Smith PetscErrorCode ierr; 15579299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 15699e65526SBarry Smith PetscInt i,m = Y->rmap->n; 15799e65526SBarry Smith const PetscInt *diag; 15854f21887SBarry Smith MatScalar *aa = aij->a; 15999e65526SBarry Smith const PetscScalar *v; 160ace3abfcSBarry Smith PetscBool missing; 16179299369SBarry Smith 16279299369SBarry Smith PetscFunctionBegin; 16309f38230SBarry Smith if (Y->assembled) { 1640298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 16509f38230SBarry Smith if (!missing) { 16679299369SBarry Smith diag = aij->diag; 16799e65526SBarry Smith ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr); 16879299369SBarry Smith if (is == INSERT_VALUES) { 16979299369SBarry Smith for (i=0; i<m; i++) { 17079299369SBarry Smith aa[diag[i]] = v[i]; 17179299369SBarry Smith } 17279299369SBarry Smith } else { 17379299369SBarry Smith for (i=0; i<m; i++) { 17479299369SBarry Smith aa[diag[i]] += v[i]; 17579299369SBarry Smith } 17679299369SBarry Smith } 17799e65526SBarry Smith ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr); 17879299369SBarry Smith PetscFunctionReturn(0); 17979299369SBarry Smith } 180acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 18109f38230SBarry Smith } 18209f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 18309f38230SBarry Smith PetscFunctionReturn(0); 18409f38230SBarry Smith } 18579299369SBarry Smith 1861a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 18717ab2063SBarry Smith { 188416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 189dfbe8321SBarry Smith PetscErrorCode ierr; 19097f1f81fSBarry Smith PetscInt i,ishift; 19117ab2063SBarry Smith 1923a40ed3dSBarry Smith PetscFunctionBegin; 193d0f46423SBarry Smith *m = A->rmap->n; 1943a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 195bfeeae90SHong Zhang ishift = 0; 19653e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 1972462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 198bfeeae90SHong Zhang } else if (oshift == 1) { 1991a83f524SJed Brown PetscInt *tia; 200d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2013b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 202854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr); 2031a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2041a83f524SJed Brown *ia = tia; 205ecc77c7aSBarry Smith if (ja) { 2061a83f524SJed Brown PetscInt *tja; 207854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr); 2081a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2091a83f524SJed Brown *ja = tja; 210ecc77c7aSBarry Smith } 2116945ee14SBarry Smith } else { 212ecc77c7aSBarry Smith *ia = a->i; 213ecc77c7aSBarry Smith if (ja) *ja = a->j; 214a2ce50c7SBarry Smith } 2153a40ed3dSBarry Smith PetscFunctionReturn(0); 216a2744918SBarry Smith } 217a2744918SBarry Smith 2181a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2196945ee14SBarry Smith { 220dfbe8321SBarry Smith PetscErrorCode ierr; 2216945ee14SBarry Smith 2223a40ed3dSBarry Smith PetscFunctionBegin; 2233a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 224bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 225606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 226ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 227bcd2baecSBarry Smith } 2283a40ed3dSBarry Smith PetscFunctionReturn(0); 22917ab2063SBarry Smith } 23017ab2063SBarry Smith 2311a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2323b2fbd54SBarry Smith { 2333b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 234dfbe8321SBarry Smith PetscErrorCode ierr; 235d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 23697f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2373b2fbd54SBarry Smith 2383a40ed3dSBarry Smith PetscFunctionBegin; 239899cda47SBarry Smith *nn = n; 2403a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2413b2fbd54SBarry Smith if (symmetric) { 2422462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2433b2fbd54SBarry Smith } else { 2441795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 245854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 246854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr); 2473b2fbd54SBarry Smith jj = a->j; 2483b2fbd54SBarry Smith for (i=0; i<nz; i++) { 249bfeeae90SHong Zhang collengths[jj[i]]++; 2503b2fbd54SBarry Smith } 2513b2fbd54SBarry Smith cia[0] = oshift; 2523b2fbd54SBarry Smith for (i=0; i<n; i++) { 2533b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2543b2fbd54SBarry Smith } 25597f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 2563b2fbd54SBarry Smith jj = a->j; 257a93ec695SBarry Smith for (row=0; row<m; row++) { 258a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 259a93ec695SBarry Smith for (i=0; i<mr; i++) { 260bfeeae90SHong Zhang col = *jj++; 2612205254eSKarl Rupp 2623b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2633b2fbd54SBarry Smith } 2643b2fbd54SBarry Smith } 265606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2663b2fbd54SBarry Smith *ia = cia; *ja = cja; 2673b2fbd54SBarry Smith } 2683a40ed3dSBarry Smith PetscFunctionReturn(0); 2693b2fbd54SBarry Smith } 2703b2fbd54SBarry Smith 2711a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2723b2fbd54SBarry Smith { 273dfbe8321SBarry Smith PetscErrorCode ierr; 274606d414cSSatish Balay 2753a40ed3dSBarry Smith PetscFunctionBegin; 2763a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2773b2fbd54SBarry Smith 278606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 279606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 2803a40ed3dSBarry Smith PetscFunctionReturn(0); 2813b2fbd54SBarry Smith } 2823b2fbd54SBarry Smith 2837cee066cSHong Zhang /* 2847cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 2857cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 286040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 2877cee066cSHong Zhang */ 2887cee066cSHong 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) 2897cee066cSHong Zhang { 2907cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2917cee066cSHong Zhang PetscErrorCode ierr; 2927cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 2937cee066cSHong Zhang PetscInt nz = a->i[m],row,*jj,mr,col; 2947cee066cSHong Zhang PetscInt *cspidx; 2957cee066cSHong Zhang 2967cee066cSHong Zhang PetscFunctionBegin; 2977cee066cSHong Zhang *nn = n; 2987cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 299625f6d37SHong Zhang 3001795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 301854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 302854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr); 303854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&cspidx);CHKERRQ(ierr); 3047cee066cSHong Zhang jj = a->j; 3057cee066cSHong Zhang for (i=0; i<nz; i++) { 3067cee066cSHong Zhang collengths[jj[i]]++; 3077cee066cSHong Zhang } 3087cee066cSHong Zhang cia[0] = oshift; 3097cee066cSHong Zhang for (i=0; i<n; i++) { 3107cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3117cee066cSHong Zhang } 3127cee066cSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 3137cee066cSHong Zhang jj = a->j; 3147cee066cSHong Zhang for (row=0; row<m; row++) { 3157cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3167cee066cSHong Zhang for (i=0; i<mr; i++) { 3177cee066cSHong Zhang col = *jj++; 3187cee066cSHong Zhang cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */ 3197cee066cSHong Zhang cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 3207cee066cSHong Zhang } 3217cee066cSHong Zhang } 3227cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 3237cee066cSHong Zhang *ia = cia; *ja = cja; 3247cee066cSHong Zhang *spidx = cspidx; 3257cee066cSHong Zhang PetscFunctionReturn(0); 3267cee066cSHong Zhang } 3277cee066cSHong Zhang 3287cee066cSHong 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) 3297cee066cSHong Zhang { 3307cee066cSHong Zhang PetscErrorCode ierr; 3317cee066cSHong Zhang 3327cee066cSHong Zhang PetscFunctionBegin; 3335243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3347cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3357cee066cSHong Zhang PetscFunctionReturn(0); 3367cee066cSHong Zhang } 3377cee066cSHong Zhang 33887d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 33987d4246cSBarry Smith { 34087d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 34187d4246cSBarry Smith PetscInt *ai = a->i; 34287d4246cSBarry Smith PetscErrorCode ierr; 34387d4246cSBarry Smith 34487d4246cSBarry Smith PetscFunctionBegin; 34587d4246cSBarry Smith ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr); 34687d4246cSBarry Smith PetscFunctionReturn(0); 34787d4246cSBarry Smith } 34887d4246cSBarry Smith 349bd04181cSBarry Smith /* 350bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 351bd04181cSBarry Smith 352bd04181cSBarry Smith - a single row of values is set with each call 353bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 354bd04181cSBarry Smith - the values are always added to the matrix, not set 355bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 356bd04181cSBarry Smith 3571f763a69SBarry Smith This does NOT assume the global column indices are sorted 358bd04181cSBarry Smith 3591f763a69SBarry Smith */ 360bd04181cSBarry Smith 361af0996ceSBarry Smith #include <petsc/private/isimpl.h> 362189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 363189e4007SBarry Smith { 364189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3651f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 3661f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 3671f763a69SBarry Smith PetscInt lastcol = -1; 368189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 369189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 370189e4007SBarry Smith 371f38dd0b8SBarry Smith row = ridx[im[0]]; 3721f763a69SBarry Smith rp = aj + ai[row]; 3731f763a69SBarry Smith ap = aa + ai[row]; 3741f763a69SBarry Smith nrow = ailen[row]; 375189e4007SBarry Smith low = 0; 376189e4007SBarry Smith high = nrow; 377189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 378189e4007SBarry Smith col = cidx[in[l]]; 379f38dd0b8SBarry Smith value = v[l]; 380189e4007SBarry Smith 381189e4007SBarry Smith if (col <= lastcol) low = 0; 382189e4007SBarry Smith else high = nrow; 383189e4007SBarry Smith lastcol = col; 384189e4007SBarry Smith while (high-low > 5) { 385189e4007SBarry Smith t = (low+high)/2; 386189e4007SBarry Smith if (rp[t] > col) high = t; 387189e4007SBarry Smith else low = t; 388189e4007SBarry Smith } 389189e4007SBarry Smith for (i=low; i<high; i++) { 390189e4007SBarry Smith if (rp[i] == col) { 3911f763a69SBarry Smith ap[i] += value; 392189e4007SBarry Smith low = i + 1; 3931f763a69SBarry Smith break; 394189e4007SBarry Smith } 395189e4007SBarry Smith } 396189e4007SBarry Smith } 397f38dd0b8SBarry Smith return 0; 398189e4007SBarry Smith } 399189e4007SBarry Smith 40097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 40117ab2063SBarry Smith { 402416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 403e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 40497f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 4056849ba73SBarry Smith PetscErrorCode ierr; 406e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 407*d8cdefa3SHong Zhang MatScalar *ap=NULL,value=0.0,*aa = a->a; 408ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 409ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 41017ab2063SBarry Smith 4113a40ed3dSBarry Smith PetscFunctionBegin; 41217ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 413416022c9SBarry Smith row = im[k]; 4145ef9f2a5SBarry Smith if (row < 0) continue; 4152515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 416e32f2f54SBarry 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); 4173b2fbd54SBarry Smith #endif 418720833daSHong Zhang rp = aj + ai[row]; 419876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 42017ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 421416022c9SBarry Smith low = 0; 422c71e6ed7SBarry Smith high = nrow; 42317ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4245ef9f2a5SBarry Smith if (in[l] < 0) continue; 4252515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 426e32f2f54SBarry 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); 4273b2fbd54SBarry Smith #endif 428bfeeae90SHong Zhang col = in[l]; 429720833daSHong Zhang if (!A->structure_only) { 4304b0e389bSBarry Smith if (roworiented) { 4315ef9f2a5SBarry Smith value = v[l + k*n]; 432bef8e0ddSBarry Smith } else { 4334b0e389bSBarry Smith value = v[k + l*m]; 4344b0e389bSBarry Smith } 435720833daSHong Zhang } else { /* A->structure_only */ 436720833daSHong Zhang value = 1; /* avoid 'continue' below? */ 437720833daSHong Zhang } 438dcd36c23SBarry Smith if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES) && row != col) continue; 43936db0b34SBarry Smith 4402205254eSKarl Rupp if (col <= lastcol) low = 0; 4412205254eSKarl Rupp else high = nrow; 442e2ee6c50SBarry Smith lastcol = col; 443416022c9SBarry Smith while (high-low > 5) { 444416022c9SBarry Smith t = (low+high)/2; 445416022c9SBarry Smith if (rp[t] > col) high = t; 446416022c9SBarry Smith else low = t; 44717ab2063SBarry Smith } 448416022c9SBarry Smith for (i=low; i<high; i++) { 44917ab2063SBarry Smith if (rp[i] > col) break; 45017ab2063SBarry Smith if (rp[i] == col) { 451876c6284SHong Zhang if (!A->structure_only) { 452416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 45317ab2063SBarry Smith else ap[i] = value; 454720833daSHong Zhang } 455e44c0bd4SBarry Smith low = i + 1; 45617ab2063SBarry Smith goto noinsert; 45717ab2063SBarry Smith } 45817ab2063SBarry Smith } 459dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 460c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 461e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 462720833daSHong Zhang if (A->structure_only) { 463876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 464720833daSHong Zhang } else { 465fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 466720833daSHong Zhang } 467c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 468416022c9SBarry Smith /* shift up all the later entries in this row */ 469416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 47017ab2063SBarry Smith rp[ii+1] = rp[ii]; 471876c6284SHong Zhang if (!A->structure_only) ap[ii+1] = ap[ii]; 472720833daSHong Zhang } 47317ab2063SBarry Smith rp[i] = col; 474876c6284SHong Zhang if (!A->structure_only) ap[i] = value; 475416022c9SBarry Smith low = i + 1; 476e56f5c9eSBarry Smith A->nonzerostate++; 477e44c0bd4SBarry Smith noinsert:; 47817ab2063SBarry Smith } 47917ab2063SBarry Smith ailen[row] = nrow; 48017ab2063SBarry Smith } 4813a40ed3dSBarry Smith PetscFunctionReturn(0); 48217ab2063SBarry Smith } 48317ab2063SBarry Smith 48481824310SBarry Smith 485a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 4867eb43aa7SLois Curfman McInnes { 4877eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 48897f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 48997f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 49054f21887SBarry Smith MatScalar *ap,*aa = a->a; 4917eb43aa7SLois Curfman McInnes 4923a40ed3dSBarry Smith PetscFunctionBegin; 4937eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 4947eb43aa7SLois Curfman McInnes row = im[k]; 495e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 496e32f2f54SBarry 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); 497bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 4987eb43aa7SLois Curfman McInnes nrow = ailen[row]; 4997eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 500e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 501e32f2f54SBarry 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); 502bfeeae90SHong Zhang col = in[l]; 5037eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 5047eb43aa7SLois Curfman McInnes while (high-low > 5) { 5057eb43aa7SLois Curfman McInnes t = (low+high)/2; 5067eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 5077eb43aa7SLois Curfman McInnes else low = t; 5087eb43aa7SLois Curfman McInnes } 5097eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 5107eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 5117eb43aa7SLois Curfman McInnes if (rp[i] == col) { 512b49de8d1SLois Curfman McInnes *v++ = ap[i]; 5137eb43aa7SLois Curfman McInnes goto finished; 5147eb43aa7SLois Curfman McInnes } 5157eb43aa7SLois Curfman McInnes } 51697e567efSBarry Smith *v++ = 0.0; 5177eb43aa7SLois Curfman McInnes finished:; 5187eb43aa7SLois Curfman McInnes } 5197eb43aa7SLois Curfman McInnes } 5203a40ed3dSBarry Smith PetscFunctionReturn(0); 5217eb43aa7SLois Curfman McInnes } 5227eb43aa7SLois Curfman McInnes 52317ab2063SBarry Smith 524dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 52517ab2063SBarry Smith { 526416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 5276849ba73SBarry Smith PetscErrorCode ierr; 5286f69ff64SBarry Smith PetscInt i,*col_lens; 5296f69ff64SBarry Smith int fd; 530b37d52dbSMark F. Adams FILE *file; 53117ab2063SBarry Smith 5323a40ed3dSBarry Smith PetscFunctionBegin; 533b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 534854ce69bSBarry Smith ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr); 5352205254eSKarl Rupp 5360700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 537d0f46423SBarry Smith col_lens[1] = A->rmap->n; 538d0f46423SBarry Smith col_lens[2] = A->cmap->n; 539416022c9SBarry Smith col_lens[3] = a->nz; 540416022c9SBarry Smith 541416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 542d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 543416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 54417ab2063SBarry Smith } 545d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 546606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 547416022c9SBarry Smith 548416022c9SBarry Smith /* store column indices (zero start index) */ 5496f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 550416022c9SBarry Smith 551416022c9SBarry Smith /* store nonzero values */ 5526f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 553b37d52dbSMark F. Adams 554b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 555b37d52dbSMark F. Adams if (file) { 55633d57670SJed Brown fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs)); 557b37d52dbSMark F. Adams } 5583a40ed3dSBarry Smith PetscFunctionReturn(0); 55917ab2063SBarry Smith } 560416022c9SBarry Smith 5617dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 5627dc0baabSHong Zhang { 5637dc0baabSHong Zhang PetscErrorCode ierr; 5647dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 5657dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 5667dc0baabSHong Zhang 5677dc0baabSHong Zhang PetscFunctionBegin; 5687dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 5697dc0baabSHong Zhang for (i=0; i<m; i++) { 5707dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 5717dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 5727dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 5737dc0baabSHong Zhang } 5747dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 5757dc0baabSHong Zhang } 5767dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 5777dc0baabSHong Zhang PetscFunctionReturn(0); 5787dc0baabSHong Zhang } 5797dc0baabSHong Zhang 58009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 581cd155464SBarry Smith 582dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 583416022c9SBarry Smith { 584416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 585dfbe8321SBarry Smith PetscErrorCode ierr; 58660e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 587e060cb09SBarry Smith const char *name; 588f3ef73ceSBarry Smith PetscViewerFormat format; 58917ab2063SBarry Smith 5903a40ed3dSBarry Smith PetscFunctionBegin; 5917dc0baabSHong Zhang if (A->structure_only) { 5927dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 5937dc0baabSHong Zhang PetscFunctionReturn(0); 5947dc0baabSHong Zhang } 59543e49210SHong Zhang 596b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 59771c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 59897f1f81fSBarry Smith PetscInt nofinalvalue = 0; 59960e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 600c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 601d00d2cf4SBarry Smith nofinalvalue = 1; 602d00d2cf4SBarry Smith } 603d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 604d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 60577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 606fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 607fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 608fbfe6fa7SJed Brown #else 60977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 610fbfe6fa7SJed Brown #endif 611b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 61217ab2063SBarry Smith 61317ab2063SBarry Smith for (i=0; i<m; i++) { 61460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 615aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 616a9bf72d8SJed 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); 61717ab2063SBarry Smith #else 61860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 61917ab2063SBarry Smith #endif 62017ab2063SBarry Smith } 62117ab2063SBarry Smith } 622d00d2cf4SBarry Smith if (nofinalvalue) { 623c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 624c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 625c337ccceSJed Brown #else 626d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 627c337ccceSJed Brown #endif 628d00d2cf4SBarry Smith } 629317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 630fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 631d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 63268369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 633cd155464SBarry Smith PetscFunctionReturn(0); 634fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 635d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 63644cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 63777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 63860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 639aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 64036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 64160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 64236db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 64360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 64436db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 64560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 6466831982aSBarry Smith } 64744cd7ae7SLois Curfman McInnes #else 64860e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 64944cd7ae7SLois Curfman McInnes #endif 65044cd7ae7SLois Curfman McInnes } 651b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 65244cd7ae7SLois Curfman McInnes } 653d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 654fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 65597f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 656d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 657854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 658496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 659496be53dSLois Curfman McInnes sptr[i] = nzd+1; 66060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 661496be53dSLois Curfman McInnes if (a->j[j] >= i) { 662aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 66336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 664496be53dSLois Curfman McInnes #else 665496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 666496be53dSLois Curfman McInnes #endif 667496be53dSLois Curfman McInnes } 668496be53dSLois Curfman McInnes } 669496be53dSLois Curfman McInnes } 6702e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 67177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 6722e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 6732205254eSKarl Rupp if (i+4<m) { 6742205254eSKarl 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); 6752205254eSKarl Rupp } else if (i+3<m) { 6762205254eSKarl 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); 6772205254eSKarl Rupp } else if (i+2<m) { 6782205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 6792205254eSKarl Rupp } else if (i+1<m) { 6802205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 6812205254eSKarl Rupp } else if (i<m) { 6822205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 6832205254eSKarl Rupp } else { 6842205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 6852205254eSKarl Rupp } 686496be53dSLois Curfman McInnes } 687b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 688606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 689496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 69060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 69177431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 692496be53dSLois Curfman McInnes } 693b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 694496be53dSLois Curfman McInnes } 695b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 696496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 69760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 698496be53dSLois Curfman McInnes if (a->j[j] >= i) { 699aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 70036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 70160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7026831982aSBarry Smith } 703496be53dSLois Curfman McInnes #else 70460e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 705496be53dSLois Curfman McInnes #endif 706496be53dSLois Curfman McInnes } 707496be53dSLois Curfman McInnes } 708b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 709496be53dSLois Curfman McInnes } 710d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 711fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 71297f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 71387828ca2SBarry Smith PetscScalar value; 71468f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 71568f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 71668f1ed48SBarry Smith 71768f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 71868f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 71968f1ed48SBarry Smith realonly = PETSC_FALSE; 72068f1ed48SBarry Smith break; 72168f1ed48SBarry Smith } 72268f1ed48SBarry Smith } 72368f1ed48SBarry Smith #endif 72402594712SBarry Smith 725d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 72602594712SBarry Smith for (i=0; i<m; i++) { 72702594712SBarry Smith jcnt = 0; 728d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 729e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 73002594712SBarry Smith value = a->a[cnt++]; 731e24b481bSBarry Smith jcnt++; 73202594712SBarry Smith } else { 73302594712SBarry Smith value = 0.0; 73402594712SBarry Smith } 735aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 73668f1ed48SBarry Smith if (realonly) { 73760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 73868f1ed48SBarry Smith } else { 73960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 74068f1ed48SBarry Smith } 74102594712SBarry Smith #else 74260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 74302594712SBarry Smith #endif 74402594712SBarry Smith } 745b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 74602594712SBarry Smith } 747d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7483c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 749150b93efSMatthew G. Knepley PetscInt fshift=1; 750d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7513c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 75219303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 7533c215bfdSMatthew Knepley #else 75419303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 7553c215bfdSMatthew Knepley #endif 756d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 7573c215bfdSMatthew Knepley for (i=0; i<m; i++) { 75860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 7593c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 760a9a0e077SKarl 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); 7613c215bfdSMatthew Knepley #else 762150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 7633c215bfdSMatthew Knepley #endif 7643c215bfdSMatthew Knepley } 7653c215bfdSMatthew Knepley } 766d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7673a40ed3dSBarry Smith } else { 768d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 769d5f3da31SBarry Smith if (A->factortype) { 77016cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 77116cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 77216cd7e1dSShri Abhyankar /* L part */ 77360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 77416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 77516cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 77660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 77716cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 7786712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 77916cd7e1dSShri Abhyankar } else { 78060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 78116cd7e1dSShri Abhyankar } 78216cd7e1dSShri Abhyankar #else 78360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 78416cd7e1dSShri Abhyankar #endif 78516cd7e1dSShri Abhyankar } 78616cd7e1dSShri Abhyankar /* diagonal */ 78716cd7e1dSShri Abhyankar j = a->diag[i]; 78816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 78916cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 79060e0710aSBarry 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); 79116cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 7926712e2f1SBarry 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); 79316cd7e1dSShri Abhyankar } else { 79460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 79516cd7e1dSShri Abhyankar } 79616cd7e1dSShri Abhyankar #else 79760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 79816cd7e1dSShri Abhyankar #endif 79916cd7e1dSShri Abhyankar 80016cd7e1dSShri Abhyankar /* U part */ 80160e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 80216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 80316cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 80460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 80516cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 80622ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 80716cd7e1dSShri Abhyankar } else { 80860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 80916cd7e1dSShri Abhyankar } 81016cd7e1dSShri Abhyankar #else 81160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 81216cd7e1dSShri Abhyankar #endif 81316cd7e1dSShri Abhyankar } 81416cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 81516cd7e1dSShri Abhyankar } 81616cd7e1dSShri Abhyankar } else { 81717ab2063SBarry Smith for (i=0; i<m; i++) { 81877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 81960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 820aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 82136db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 82260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 82336db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 82460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8253a40ed3dSBarry Smith } else { 82660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 82717ab2063SBarry Smith } 82817ab2063SBarry Smith #else 82960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 83017ab2063SBarry Smith #endif 83117ab2063SBarry Smith } 832b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 83317ab2063SBarry Smith } 83416cd7e1dSShri Abhyankar } 835d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 83617ab2063SBarry Smith } 837b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8383a40ed3dSBarry Smith PetscFunctionReturn(0); 839416022c9SBarry Smith } 840416022c9SBarry Smith 8419804daf3SBarry Smith #include <petscdraw.h> 842dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 843416022c9SBarry Smith { 844480ef9eaSBarry Smith Mat A = (Mat) Aa; 845416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 846dfbe8321SBarry Smith PetscErrorCode ierr; 847383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 848383922c3SLisandro Dalcin int color; 849b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 850b0a32e0cSBarry Smith PetscViewer viewer; 851f3ef73ceSBarry Smith PetscViewerFormat format; 852cddf8d76SBarry Smith 8533a40ed3dSBarry Smith PetscFunctionBegin; 854480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 855b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 856b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 857383922c3SLisandro Dalcin 858416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 8590513a670SBarry Smith 860fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 861383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 8620513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 863b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 864416022c9SBarry Smith for (i=0; i<m; i++) { 865cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 866bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 867bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 86836db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 869b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 870cddf8d76SBarry Smith } 871cddf8d76SBarry Smith } 872b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 873cddf8d76SBarry Smith for (i=0; i<m; i++) { 874cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 875bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 876bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 877cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 878b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 879cddf8d76SBarry Smith } 880cddf8d76SBarry Smith } 881b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 882cddf8d76SBarry Smith for (i=0; i<m; i++) { 883cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 884bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 885bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 88636db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 887b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 888416022c9SBarry Smith } 889416022c9SBarry Smith } 890383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 8910513a670SBarry Smith } else { 8920513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 8930513a670SBarry Smith /* first determine max of all nonzero values */ 894b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 895383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 896b0a32e0cSBarry Smith PetscDraw popup; 8970513a670SBarry Smith 8980513a670SBarry Smith for (i=0; i<nz; i++) { 8990513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 9000513a670SBarry Smith } 901383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 902b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 90345f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 904383922c3SLisandro Dalcin 905383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 9060513a670SBarry Smith for (i=0; i<m; i++) { 907383922c3SLisandro Dalcin y_l = m - i - 1.0; 908383922c3SLisandro Dalcin y_r = y_l + 1.0; 909bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 910383922c3SLisandro Dalcin x_l = a->j[j]; 911383922c3SLisandro Dalcin x_r = x_l + 1.0; 912b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 913b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 9140513a670SBarry Smith count++; 9150513a670SBarry Smith } 9160513a670SBarry Smith } 917383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 9180513a670SBarry Smith } 919480ef9eaSBarry Smith PetscFunctionReturn(0); 920480ef9eaSBarry Smith } 921cddf8d76SBarry Smith 9229804daf3SBarry Smith #include <petscdraw.h> 923dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 924480ef9eaSBarry Smith { 925dfbe8321SBarry Smith PetscErrorCode ierr; 926b0a32e0cSBarry Smith PetscDraw draw; 92736db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 928ace3abfcSBarry Smith PetscBool isnull; 929480ef9eaSBarry Smith 930480ef9eaSBarry Smith PetscFunctionBegin; 931b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 932b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 933480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 934480ef9eaSBarry Smith 935d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 936480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 937b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 938832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 939b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 9400298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 941832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 9423a40ed3dSBarry Smith PetscFunctionReturn(0); 943416022c9SBarry Smith } 944416022c9SBarry Smith 945dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 946416022c9SBarry Smith { 947dfbe8321SBarry Smith PetscErrorCode ierr; 948ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 949416022c9SBarry Smith 9503a40ed3dSBarry Smith PetscFunctionBegin; 951251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 952251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 953251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 954c45a1595SBarry Smith if (iascii) { 9553a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 9560f5bd95cSBarry Smith } else if (isbinary) { 9573a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 9580f5bd95cSBarry Smith } else if (isdraw) { 9593a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 96011aeaf0aSBarry Smith } 9614108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 9623a40ed3dSBarry Smith PetscFunctionReturn(0); 96317ab2063SBarry Smith } 96419bcc07fSBarry Smith 965dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 96617ab2063SBarry Smith { 967416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9686849ba73SBarry Smith PetscErrorCode ierr; 96997f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 970d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 97154f21887SBarry Smith MatScalar *aa = a->a,*ap; 9723447b6efSHong Zhang PetscReal ratio = 0.6; 97317ab2063SBarry Smith 9743a40ed3dSBarry Smith PetscFunctionBegin; 9753a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 97617ab2063SBarry Smith 97743ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 97817ab2063SBarry Smith for (i=1; i<m; i++) { 979416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 98017ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 98194a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 98217ab2063SBarry Smith if (fshift) { 983bfeeae90SHong Zhang ip = aj + ai[i]; 984bfeeae90SHong Zhang ap = aa + ai[i]; 98517ab2063SBarry Smith N = ailen[i]; 98617ab2063SBarry Smith for (j=0; j<N; j++) { 98717ab2063SBarry Smith ip[j-fshift] = ip[j]; 988876c6284SHong Zhang if (!A->structure_only) ap[j-fshift] = ap[j]; 98917ab2063SBarry Smith } 99017ab2063SBarry Smith } 99117ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 99217ab2063SBarry Smith } 99317ab2063SBarry Smith if (m) { 99417ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 99517ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 99617ab2063SBarry Smith } 9977b083b7cSBarry Smith 99817ab2063SBarry Smith /* reset ilen and imax for each row */ 9997b083b7cSBarry Smith a->nonzerorowcnt = 0; 1000396832f4SHong Zhang if (A->structure_only) { 1001396832f4SHong Zhang ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 1002396832f4SHong Zhang } else { /* !A->structure_only */ 100317ab2063SBarry Smith for (i=0; i<m; i++) { 100417ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 10057b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 100617ab2063SBarry Smith } 1007396832f4SHong Zhang } 1008bfeeae90SHong Zhang a->nz = ai[m]; 100965e19b50SBarry 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); 101017ab2063SBarry Smith 101109f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1012d0f46423SBarry 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); 1013ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1014ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 10152205254eSKarl Rupp 10168e58a170SBarry Smith A->info.mallocs += a->reallocs; 1017dd5f02e7SSatish Balay a->reallocs = 0; 10186712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 101936db0b34SBarry Smith a->rmax = rmax; 10204e220ebcSLois Curfman McInnes 1021396832f4SHong Zhang if (!A->structure_only) { 102211e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1023396832f4SHong Zhang } 10244108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 1025acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 10263a40ed3dSBarry Smith PetscFunctionReturn(0); 102717ab2063SBarry Smith } 102817ab2063SBarry Smith 102999cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 103099cafbc1SBarry Smith { 103199cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 103299cafbc1SBarry Smith PetscInt i,nz = a->nz; 103354f21887SBarry Smith MatScalar *aa = a->a; 1034acf2f550SJed Brown PetscErrorCode ierr; 103599cafbc1SBarry Smith 103699cafbc1SBarry Smith PetscFunctionBegin; 103799cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1038acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 103999cafbc1SBarry Smith PetscFunctionReturn(0); 104099cafbc1SBarry Smith } 104199cafbc1SBarry Smith 104299cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 104399cafbc1SBarry Smith { 104499cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 104599cafbc1SBarry Smith PetscInt i,nz = a->nz; 104654f21887SBarry Smith MatScalar *aa = a->a; 1047acf2f550SJed Brown PetscErrorCode ierr; 104899cafbc1SBarry Smith 104999cafbc1SBarry Smith PetscFunctionBegin; 105099cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1051acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 105299cafbc1SBarry Smith PetscFunctionReturn(0); 105399cafbc1SBarry Smith } 105499cafbc1SBarry Smith 1055dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 105617ab2063SBarry Smith { 1057416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1058dfbe8321SBarry Smith PetscErrorCode ierr; 10593a40ed3dSBarry Smith 10603a40ed3dSBarry Smith PetscFunctionBegin; 1061d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 1062acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 10633a40ed3dSBarry Smith PetscFunctionReturn(0); 106417ab2063SBarry Smith } 1065416022c9SBarry Smith 1066dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 106717ab2063SBarry Smith { 1068416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1069dfbe8321SBarry Smith PetscErrorCode ierr; 1070d5d45c9bSBarry Smith 10713a40ed3dSBarry Smith PetscFunctionBegin; 1072aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1073d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 107417ab2063SBarry Smith #endif 1075e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 10766bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 10776bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 107805b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1079d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 108005b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 108171f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 108205b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 10836bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 108405b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 10856bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 1086cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 10870b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1088a30b2313SHong Zhang 10894108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1090bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1091901853e0SKris Buschelman 1092dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1093bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1094bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1095bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1096bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1097bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1098bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1099af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1100af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1101af8000cdSHong Zhang #endif 110263c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 110363c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 11043dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 110563c07aadSStefano Zampini #endif 1106b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1107bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1108bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1109bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1110bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 11113a40ed3dSBarry Smith PetscFunctionReturn(0); 111217ab2063SBarry Smith } 111317ab2063SBarry Smith 1114ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 111517ab2063SBarry Smith { 1116416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11174846f1f5SKris Buschelman PetscErrorCode ierr; 11183a40ed3dSBarry Smith 11193a40ed3dSBarry Smith PetscFunctionBegin; 1120a65d3064SKris Buschelman switch (op) { 1121a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 11224e0d8c25SBarry Smith a->roworiented = flg; 1123a65d3064SKris Buschelman break; 1124a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1125a9817697SBarry Smith a->keepnonzeropattern = flg; 1126a65d3064SKris Buschelman break; 1127512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1128512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1129a65d3064SKris Buschelman break; 1130a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 11314e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1132a65d3064SKris Buschelman break; 1133a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 11344e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1135a65d3064SKris Buschelman break; 113628b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 113728b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 113828b2fa4aSMatthew Knepley break; 1139a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 11404e0d8c25SBarry Smith a->ignorezeroentries = flg; 11410df259c2SBarry Smith break; 11423d472b54SHong Zhang case MAT_SPD: 1143b1646e73SJed Brown case MAT_SYMMETRIC: 1144b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1145b1646e73SJed Brown case MAT_HERMITIAN: 1146b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1147957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 11485021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 11495021d80fSJed Brown break; 11504e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1151a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1152a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1153290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1154a65d3064SKris Buschelman break; 1155b87ac2d8SJed Brown case MAT_USE_INODES: 1156b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1157b87ac2d8SJed Brown break; 1158c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1159c10200c1SHong Zhang A->submat_singleis = flg; 1160c10200c1SHong Zhang break; 1161a65d3064SKris Buschelman default: 1162e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1163a65d3064SKris Buschelman } 11644108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 11653a40ed3dSBarry Smith PetscFunctionReturn(0); 116617ab2063SBarry Smith } 116717ab2063SBarry Smith 1168dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 116917ab2063SBarry Smith { 1170416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11716849ba73SBarry Smith PetscErrorCode ierr; 1172d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 117335e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 117417ab2063SBarry Smith 11753a40ed3dSBarry Smith PetscFunctionBegin; 1176d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1177e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 117835e7444dSHong Zhang 1179d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1180d3e70bfaSHong Zhang PetscInt *diag=a->diag; 118135e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 11822c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 118335e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 118435e7444dSHong Zhang PetscFunctionReturn(0); 118535e7444dSHong Zhang } 118635e7444dSHong Zhang 11872dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 11881ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 118935e7444dSHong Zhang for (i=0; i<n; i++) { 119035e7444dSHong Zhang nz = ai[i+1] - ai[i]; 11912f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 119235e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 119335e7444dSHong Zhang if (aj[j] == i) { 119435e7444dSHong Zhang x[i] = aa[j]; 119517ab2063SBarry Smith break; 119617ab2063SBarry Smith } 119717ab2063SBarry Smith } 119817ab2063SBarry Smith } 11991ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 12003a40ed3dSBarry Smith PetscFunctionReturn(0); 120117ab2063SBarry Smith } 120217ab2063SBarry Smith 1203c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1204dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 120517ab2063SBarry Smith { 1206416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1207d9ca1df4SBarry Smith PetscScalar *y; 1208d9ca1df4SBarry Smith const PetscScalar *x; 1209dfbe8321SBarry Smith PetscErrorCode ierr; 1210d0f46423SBarry Smith PetscInt m = A->rmap->n; 12115c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1212d9ca1df4SBarry Smith const MatScalar *v; 1213a77337e4SBarry Smith PetscScalar alpha; 1214d9ca1df4SBarry Smith PetscInt n,i,j; 1215d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 12163447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1217ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 12185c897100SBarry Smith #endif 121917ab2063SBarry Smith 12203a40ed3dSBarry Smith PetscFunctionBegin; 12212e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1222d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 12231ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 12245c897100SBarry Smith 12255c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1226bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 12275c897100SBarry Smith #else 12283447b6efSHong Zhang if (usecprow) { 12293447b6efSHong Zhang m = cprow.nrows; 12303447b6efSHong Zhang ii = cprow.i; 12317b2bb3b9SHong Zhang ridx = cprow.rindex; 12323447b6efSHong Zhang } else { 12333447b6efSHong Zhang ii = a->i; 12343447b6efSHong Zhang } 123517ab2063SBarry Smith for (i=0; i<m; i++) { 12363447b6efSHong Zhang idx = a->j + ii[i]; 12373447b6efSHong Zhang v = a->a + ii[i]; 12383447b6efSHong Zhang n = ii[i+1] - ii[i]; 12393447b6efSHong Zhang if (usecprow) { 12407b2bb3b9SHong Zhang alpha = x[ridx[i]]; 12413447b6efSHong Zhang } else { 124217ab2063SBarry Smith alpha = x[i]; 12433447b6efSHong Zhang } 124404fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 124517ab2063SBarry Smith } 12465c897100SBarry Smith #endif 1247dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1248d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12491ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12503a40ed3dSBarry Smith PetscFunctionReturn(0); 125117ab2063SBarry Smith } 125217ab2063SBarry Smith 1253dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 12545c897100SBarry Smith { 1255dfbe8321SBarry Smith PetscErrorCode ierr; 12565c897100SBarry Smith 12575c897100SBarry Smith PetscFunctionBegin; 1258170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 12595c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 12605c897100SBarry Smith PetscFunctionReturn(0); 12615c897100SBarry Smith } 12625c897100SBarry Smith 1263c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 126478b84d54SShri Abhyankar 1265dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 126617ab2063SBarry Smith { 1267416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1268d9fead3dSBarry Smith PetscScalar *y; 126954f21887SBarry Smith const PetscScalar *x; 127054f21887SBarry Smith const MatScalar *aa; 1271dfbe8321SBarry Smith PetscErrorCode ierr; 1272003131ecSBarry Smith PetscInt m=A->rmap->n; 12730298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 12747b083b7cSBarry Smith PetscInt n,i; 1275362ced78SSatish Balay PetscScalar sum; 1276ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 127717ab2063SBarry Smith 1278b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 127997952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1280fee21e36SBarry Smith #endif 1281fee21e36SBarry Smith 12823a40ed3dSBarry Smith PetscFunctionBegin; 12833649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 12841ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1285416022c9SBarry Smith ii = a->i; 12864eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 12874f390cb1SBarry Smith ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr); 128897952fefSHong Zhang m = a->compressedrow.nrows; 128997952fefSHong Zhang ii = a->compressedrow.i; 129097952fefSHong Zhang ridx = a->compressedrow.rindex; 129197952fefSHong Zhang for (i=0; i<m; i++) { 129297952fefSHong Zhang n = ii[i+1] - ii[i]; 129397952fefSHong Zhang aj = a->j + ii[i]; 129497952fefSHong Zhang aa = a->a + ii[i]; 129597952fefSHong Zhang sum = 0.0; 1296003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1297003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 129897952fefSHong Zhang y[*ridx++] = sum; 129997952fefSHong Zhang } 130097952fefSHong Zhang } else { /* do not use compressed row format */ 1301b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 13023d3eaba7SBarry Smith aj = a->j; 13033d3eaba7SBarry Smith aa = a->a; 1304b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1305b05257ddSBarry Smith #else 130617ab2063SBarry Smith for (i=0; i<m; i++) { 1307003131ecSBarry Smith n = ii[i+1] - ii[i]; 1308003131ecSBarry Smith aj = a->j + ii[i]; 1309003131ecSBarry Smith aa = a->a + ii[i]; 131017ab2063SBarry Smith sum = 0.0; 1311003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 131217ab2063SBarry Smith y[i] = sum; 131317ab2063SBarry Smith } 13148d195f9aSBarry Smith #endif 1315b05257ddSBarry Smith } 13167b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 13173649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 13181ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13193a40ed3dSBarry Smith PetscFunctionReturn(0); 132017ab2063SBarry Smith } 132117ab2063SBarry Smith 1322b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1323b434eb95SMatthew G. Knepley { 1324b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1325b434eb95SMatthew G. Knepley PetscScalar *y; 1326b434eb95SMatthew G. Knepley const PetscScalar *x; 1327b434eb95SMatthew G. Knepley const MatScalar *aa; 1328b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1329b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1330b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1331b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1332b434eb95SMatthew G. Knepley PetscScalar sum; 1333b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1334b434eb95SMatthew G. Knepley 1335b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1336b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1337b434eb95SMatthew G. Knepley #endif 1338b434eb95SMatthew G. Knepley 1339b434eb95SMatthew G. Knepley PetscFunctionBegin; 1340b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1341b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1342b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1343b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1344b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1345b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1346b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1347b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1348b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1349b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1350b434eb95SMatthew G. Knepley sum = 0.0; 1351b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1352b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1353b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1354b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1355b434eb95SMatthew G. Knepley } 1356b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 13573d3eaba7SBarry Smith ii = a->i; 1358b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1359b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1360b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1361b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1362b434eb95SMatthew G. Knepley sum = 0.0; 1363b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1364b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1365b434eb95SMatthew G. Knepley y[i] = sum; 1366b434eb95SMatthew G. Knepley } 1367b434eb95SMatthew G. Knepley } 1368b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1369b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1370b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1371b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1372b434eb95SMatthew G. Knepley } 1373b434eb95SMatthew G. Knepley 1374b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1375b434eb95SMatthew G. Knepley { 1376b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1377b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1378b434eb95SMatthew G. Knepley const PetscScalar *x; 1379b434eb95SMatthew G. Knepley const MatScalar *aa; 1380b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1381b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1382b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1383b434eb95SMatthew G. Knepley PetscScalar sum; 1384b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1385b434eb95SMatthew G. Knepley 1386b434eb95SMatthew G. Knepley PetscFunctionBegin; 1387b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1388d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1389b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1390b434eb95SMatthew G. Knepley if (zz != yy) { 1391b434eb95SMatthew G. Knepley ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 1392b434eb95SMatthew G. Knepley } 1393b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1394b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1395b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1396b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1397b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1398b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1399b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1400b434eb95SMatthew G. Knepley sum = y[*ridx]; 1401b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1402b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1403b434eb95SMatthew G. Knepley } 1404b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 14053d3eaba7SBarry Smith ii = a->i; 1406b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1407b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1408b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1409b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1410b434eb95SMatthew G. Knepley sum = y[i]; 1411b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1412b434eb95SMatthew G. Knepley z[i] = sum; 1413b434eb95SMatthew G. Knepley } 1414b434eb95SMatthew G. Knepley } 1415b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1416b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1417d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1418b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1419b434eb95SMatthew G. Knepley } 1420b434eb95SMatthew G. Knepley 1421c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1422dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 142317ab2063SBarry Smith { 1424416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1425f15663dcSBarry Smith PetscScalar *y,*z; 1426f15663dcSBarry Smith const PetscScalar *x; 142754f21887SBarry Smith const MatScalar *aa; 1428dfbe8321SBarry Smith PetscErrorCode ierr; 1429d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1430d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1431362ced78SSatish Balay PetscScalar sum; 1432ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 14339ea0dfa2SSatish Balay 14343a40ed3dSBarry Smith PetscFunctionBegin; 1435f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1436d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 14374eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 14384eb6d288SHong Zhang if (zz != yy) { 14394eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 14404eb6d288SHong Zhang } 144197952fefSHong Zhang m = a->compressedrow.nrows; 144297952fefSHong Zhang ii = a->compressedrow.i; 144397952fefSHong Zhang ridx = a->compressedrow.rindex; 144497952fefSHong Zhang for (i=0; i<m; i++) { 144597952fefSHong Zhang n = ii[i+1] - ii[i]; 144697952fefSHong Zhang aj = a->j + ii[i]; 144797952fefSHong Zhang aa = a->a + ii[i]; 144897952fefSHong Zhang sum = y[*ridx]; 1449f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 145097952fefSHong Zhang z[*ridx++] = sum; 145197952fefSHong Zhang } 145297952fefSHong Zhang } else { /* do not use compressed row format */ 14533d3eaba7SBarry Smith ii = a->i; 1454f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 14553d3eaba7SBarry Smith aj = a->j; 14563d3eaba7SBarry Smith aa = a->a; 1457f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1458f15663dcSBarry Smith #else 145917ab2063SBarry Smith for (i=0; i<m; i++) { 1460f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1461f15663dcSBarry Smith aj = a->j + ii[i]; 1462f15663dcSBarry Smith aa = a->a + ii[i]; 146317ab2063SBarry Smith sum = y[i]; 1464f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 146517ab2063SBarry Smith z[i] = sum; 146617ab2063SBarry Smith } 146702ab625aSSatish Balay #endif 1468f15663dcSBarry Smith } 1469dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1470f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1471d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 14728154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 14736b375ea7SVictor Minden /* 1474918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1475918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1476918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 14776b375ea7SVictor Minden */ 1478918e98c3SVictor Minden #endif 14793a40ed3dSBarry Smith PetscFunctionReturn(0); 148017ab2063SBarry Smith } 148117ab2063SBarry Smith 148217ab2063SBarry Smith /* 148317ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 148417ab2063SBarry Smith */ 1485dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 148617ab2063SBarry Smith { 1487416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14886849ba73SBarry Smith PetscErrorCode ierr; 1489d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 149017ab2063SBarry Smith 14913a40ed3dSBarry Smith PetscFunctionBegin; 149209f38230SBarry Smith if (!a->diag) { 1493785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 14943bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 149509f38230SBarry Smith } 1496d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 149709f38230SBarry Smith a->diag[i] = a->i[i+1]; 1498bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1499bfeeae90SHong Zhang if (a->j[j] == i) { 150009f38230SBarry Smith a->diag[i] = j; 150117ab2063SBarry Smith break; 150217ab2063SBarry Smith } 150317ab2063SBarry Smith } 150417ab2063SBarry Smith } 15053a40ed3dSBarry Smith PetscFunctionReturn(0); 150617ab2063SBarry Smith } 150717ab2063SBarry Smith 1508be5855fcSBarry Smith /* 1509be5855fcSBarry Smith Checks for missing diagonals 1510be5855fcSBarry Smith */ 1511ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1512be5855fcSBarry Smith { 1513be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15147734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1515be5855fcSBarry Smith 1516be5855fcSBarry Smith PetscFunctionBegin; 151709f38230SBarry Smith *missing = PETSC_FALSE; 15187734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 151909f38230SBarry Smith *missing = PETSC_TRUE; 152009f38230SBarry Smith if (d) *d = 0; 1521955c1f14SBarry Smith PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n"); 152209f38230SBarry Smith } else { 1523f1e2ffcdSBarry Smith diag = a->diag; 1524d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 15257734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 152609f38230SBarry Smith *missing = PETSC_TRUE; 152709f38230SBarry Smith if (d) *d = i; 1528955c1f14SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D\n",i); 1529358d2f5dSShri Abhyankar break; 153009f38230SBarry Smith } 1531be5855fcSBarry Smith } 1532be5855fcSBarry Smith } 1533be5855fcSBarry Smith PetscFunctionReturn(0); 1534be5855fcSBarry Smith } 1535be5855fcSBarry Smith 1536422a814eSBarry Smith /* 1537422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1538422a814eSBarry Smith */ 15397087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 154071f1c65dSBarry Smith { 154171f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 154271f1c65dSBarry Smith PetscErrorCode ierr; 1543d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 154454f21887SBarry Smith MatScalar *v = a->a; 154554f21887SBarry Smith PetscScalar *idiag,*mdiag; 154671f1c65dSBarry Smith 154771f1c65dSBarry Smith PetscFunctionBegin; 154871f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 154971f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 155071f1c65dSBarry Smith diag = a->diag; 155171f1c65dSBarry Smith if (!a->idiag) { 1552dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 15533bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 155471f1c65dSBarry Smith v = a->a; 155571f1c65dSBarry Smith } 155671f1c65dSBarry Smith mdiag = a->mdiag; 155771f1c65dSBarry Smith idiag = a->idiag; 155871f1c65dSBarry Smith 1559422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 156071f1c65dSBarry Smith for (i=0; i<m; i++) { 156171f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1562899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1563899639b0SHong Zhang if (PetscRealPart(fshift)) { 1564899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 15657b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 15667b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 15677b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 15687b6c816cSBarry Smith } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1569899639b0SHong Zhang } 157071f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 157171f1c65dSBarry Smith } 157271f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 157371f1c65dSBarry Smith } else { 157471f1c65dSBarry Smith for (i=0; i<m; i++) { 157571f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 157671f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 157771f1c65dSBarry Smith } 1578dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 157971f1c65dSBarry Smith } 158071f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 158171f1c65dSBarry Smith PetscFunctionReturn(0); 158271f1c65dSBarry Smith } 158371f1c65dSBarry Smith 1584c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 158541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 158617ab2063SBarry Smith { 1587416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1588e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 15893d3eaba7SBarry Smith const MatScalar *v,*idiag=0,*mdiag; 159054f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1591dfbe8321SBarry Smith PetscErrorCode ierr; 15923d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 159397f1f81fSBarry Smith const PetscInt *idx,*diag; 159417ab2063SBarry Smith 15953a40ed3dSBarry Smith PetscFunctionBegin; 1596b965ef7fSBarry Smith its = its*lits; 159791723122SBarry Smith 159871f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 159971f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 160071f1c65dSBarry Smith a->fshift = fshift; 160171f1c65dSBarry Smith a->omega = omega; 1602ed480e8bSBarry Smith 160371f1c65dSBarry Smith diag = a->diag; 160471f1c65dSBarry Smith t = a->ssor_work; 1605ed480e8bSBarry Smith idiag = a->idiag; 160671f1c65dSBarry Smith mdiag = a->mdiag; 1607ed480e8bSBarry Smith 16081ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 16093649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1610ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 161117ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 161217ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1613ed480e8bSBarry Smith bs = b; 161417ab2063SBarry Smith for (i=0; i<m; i++) { 161571f1c65dSBarry Smith d = fshift + mdiag[i]; 1616416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1617ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1618ed480e8bSBarry Smith v = a->a + diag[i] + 1; 161917ab2063SBarry Smith sum = b[i]*d/omega; 1620003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 162117ab2063SBarry Smith x[i] = sum; 162217ab2063SBarry Smith } 16231ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16243649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1625efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16263a40ed3dSBarry Smith PetscFunctionReturn(0); 162717ab2063SBarry Smith } 1628c783ea89SBarry Smith 16292205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 16302205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 163117ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1632887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 163317ab2063SBarry Smith 163417ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 163517ab2063SBarry Smith 1636887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 163717ab2063SBarry Smith */ 163817ab2063SBarry Smith scale = (2.0/omega) - 1.0; 163917ab2063SBarry Smith 164017ab2063SBarry Smith /* x = (E + U)^{-1} b */ 164117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1642416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1643ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1644ed480e8bSBarry Smith v = a->a + diag[i] + 1; 164517ab2063SBarry Smith sum = b[i]; 1646e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1647ed480e8bSBarry Smith x[i] = sum*idiag[i]; 164817ab2063SBarry Smith } 164917ab2063SBarry Smith 165017ab2063SBarry Smith /* t = b - (2*E - D)x */ 1651416022c9SBarry Smith v = a->a; 16522205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 165317ab2063SBarry Smith 165417ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1655ed480e8bSBarry Smith ts = t; 1656416022c9SBarry Smith diag = a->diag; 165717ab2063SBarry Smith for (i=0; i<m; i++) { 1658416022c9SBarry Smith n = diag[i] - a->i[i]; 1659ed480e8bSBarry Smith idx = a->j + a->i[i]; 1660ed480e8bSBarry Smith v = a->a + a->i[i]; 166117ab2063SBarry Smith sum = t[i]; 1662003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1663ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1664733d66baSBarry Smith /* x = x + t */ 1665733d66baSBarry Smith x[i] += t[i]; 166617ab2063SBarry Smith } 166717ab2063SBarry Smith 1668dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 16691ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16703649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 16713a40ed3dSBarry Smith PetscFunctionReturn(0); 167217ab2063SBarry Smith } 167317ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 167417ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 167517ab2063SBarry Smith for (i=0; i<m; i++) { 1676416022c9SBarry Smith n = diag[i] - a->i[i]; 1677ed480e8bSBarry Smith idx = a->j + a->i[i]; 1678ed480e8bSBarry Smith v = a->a + a->i[i]; 167917ab2063SBarry Smith sum = b[i]; 1680e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16815c99c7daSBarry Smith t[i] = sum; 1682ed480e8bSBarry Smith x[i] = sum*idiag[i]; 168317ab2063SBarry Smith } 16845c99c7daSBarry Smith xb = t; 1685efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16863a40ed3dSBarry Smith } else xb = b; 168717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 168817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1689416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1690ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1691ed480e8bSBarry Smith v = a->a + diag[i] + 1; 169217ab2063SBarry Smith sum = xb[i]; 1693e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16945c99c7daSBarry Smith if (xb == b) { 1695ed480e8bSBarry Smith x[i] = sum*idiag[i]; 16965c99c7daSBarry Smith } else { 1697b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 169817ab2063SBarry Smith } 16995c99c7daSBarry Smith } 1700b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 170117ab2063SBarry Smith } 170217ab2063SBarry Smith its--; 170317ab2063SBarry Smith } 170417ab2063SBarry Smith while (its--) { 170517ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 170617ab2063SBarry Smith for (i=0; i<m; i++) { 1707b19a5dc2SMark Adams /* lower */ 1708b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1709ed480e8bSBarry Smith idx = a->j + a->i[i]; 1710ed480e8bSBarry Smith v = a->a + a->i[i]; 171117ab2063SBarry Smith sum = b[i]; 1712e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1713b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1714b19a5dc2SMark Adams /* upper */ 1715b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1716b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1717b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1718b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1719b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 172017ab2063SBarry Smith } 1721b19a5dc2SMark Adams xb = t; 17229f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1723b19a5dc2SMark Adams } else xb = b; 172417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 172517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1726b19a5dc2SMark Adams sum = xb[i]; 1727b19a5dc2SMark Adams if (xb == b) { 1728b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1729416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1730ed480e8bSBarry Smith idx = a->j + a->i[i]; 1731ed480e8bSBarry Smith v = a->a + a->i[i]; 1732e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1733ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1734b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1735b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1736b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1737b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1738b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1739b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 174017ab2063SBarry Smith } 1741b19a5dc2SMark Adams } 1742b19a5dc2SMark Adams if (xb == b) { 17439f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1744b19a5dc2SMark Adams } else { 1745b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1746b19a5dc2SMark Adams } 174717ab2063SBarry Smith } 174817ab2063SBarry Smith } 17491ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17503649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1751365a8a9eSBarry Smith PetscFunctionReturn(0); 175217ab2063SBarry Smith } 175317ab2063SBarry Smith 17542af78befSBarry Smith 1755dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 175617ab2063SBarry Smith { 1757416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17584e220ebcSLois Curfman McInnes 17593a40ed3dSBarry Smith PetscFunctionBegin; 17604e220ebcSLois Curfman McInnes info->block_size = 1.0; 17614e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 17624e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 17634e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 17644e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 17658e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 17667adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1767d5f3da31SBarry Smith if (A->factortype) { 17684e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 17694e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 17704e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 17714e220ebcSLois Curfman McInnes } else { 17724e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 17734e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 17744e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 17754e220ebcSLois Curfman McInnes } 17763a40ed3dSBarry Smith PetscFunctionReturn(0); 177717ab2063SBarry Smith } 177817ab2063SBarry Smith 17792b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 178017ab2063SBarry Smith { 1781416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1782c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 17836849ba73SBarry Smith PetscErrorCode ierr; 178497b48c8fSBarry Smith const PetscScalar *xx; 178597b48c8fSBarry Smith PetscScalar *bb; 1786c7da8527SEric Chamberland PetscInt d = 0; 178717ab2063SBarry Smith 17883a40ed3dSBarry Smith PetscFunctionBegin; 178997b48c8fSBarry Smith if (x && b) { 179097b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 179197b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 179297b48c8fSBarry Smith for (i=0; i<N; i++) { 179397b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 179497b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 179597b48c8fSBarry Smith } 179697b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 179797b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 179897b48c8fSBarry Smith } 179997b48c8fSBarry Smith 1800a9817697SBarry Smith if (a->keepnonzeropattern) { 1801f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1802e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1803bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1804f1e2ffcdSBarry Smith } 1805f4df32b1SMatthew Knepley if (diag != 0.0) { 1806c7da8527SEric Chamberland for (i=0; i<N; i++) { 1807c7da8527SEric Chamberland d = rows[i]; 1808c7da8527SEric 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); 1809c7da8527SEric Chamberland } 1810f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1811f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1812f1e2ffcdSBarry Smith } 1813f1e2ffcdSBarry Smith } 1814f1e2ffcdSBarry Smith } else { 1815f4df32b1SMatthew Knepley if (diag != 0.0) { 181617ab2063SBarry Smith for (i=0; i<N; i++) { 1817e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18187ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1819416022c9SBarry Smith a->ilen[rows[i]] = 1; 1820f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1821bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 18227ae801bdSBarry Smith } else { /* in case row was completely empty */ 1823f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 182417ab2063SBarry Smith } 182517ab2063SBarry Smith } 18263a40ed3dSBarry Smith } else { 182717ab2063SBarry Smith for (i=0; i<N; i++) { 1828e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1829416022c9SBarry Smith a->ilen[rows[i]] = 0; 183017ab2063SBarry Smith } 183117ab2063SBarry Smith } 1832e56f5c9eSBarry Smith A->nonzerostate++; 1833f1e2ffcdSBarry Smith } 183443a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18353a40ed3dSBarry Smith PetscFunctionReturn(0); 183617ab2063SBarry Smith } 183717ab2063SBarry Smith 18386e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 18396e169961SBarry Smith { 18406e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18416e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 18426e169961SBarry Smith PetscErrorCode ierr; 18432b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 18446e169961SBarry Smith const PetscScalar *xx; 18456e169961SBarry Smith PetscScalar *bb; 18466e169961SBarry Smith 18476e169961SBarry Smith PetscFunctionBegin; 18486e169961SBarry Smith if (x && b) { 18496e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 18506e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 18512b40b63fSBarry Smith vecs = PETSC_TRUE; 18526e169961SBarry Smith } 18531795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 18546e169961SBarry Smith for (i=0; i<N; i++) { 18556e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18566e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 18572205254eSKarl Rupp 18586e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 18596e169961SBarry Smith } 18606e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 18616e169961SBarry Smith if (!zeroed[i]) { 18626e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 18636e169961SBarry Smith if (zeroed[a->j[j]]) { 18642b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 18656e169961SBarry Smith a->a[j] = 0.0; 18666e169961SBarry Smith } 18676e169961SBarry Smith } 18682b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 18696e169961SBarry Smith } 18706e169961SBarry Smith if (x && b) { 18716e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 18726e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 18736e169961SBarry Smith } 18746e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 18756e169961SBarry Smith if (diag != 0.0) { 18766e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 18771d5a398dSstefano_zampini if (missing) { 18781d5a398dSstefano_zampini if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 18791d5a398dSstefano_zampini else { 18801d5a398dSstefano_zampini for (i=0; i<N; i++) { 18811d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 18821d5a398dSstefano_zampini } 18831d5a398dSstefano_zampini } 18841d5a398dSstefano_zampini } else { 18856e169961SBarry Smith for (i=0; i<N; i++) { 18866e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 18876e169961SBarry Smith } 18886e169961SBarry Smith } 18891d5a398dSstefano_zampini } 18906e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18916e169961SBarry Smith PetscFunctionReturn(0); 18926e169961SBarry Smith } 18936e169961SBarry Smith 1894a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 189517ab2063SBarry Smith { 1896416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 189797f1f81fSBarry Smith PetscInt *itmp; 189817ab2063SBarry Smith 18993a40ed3dSBarry Smith PetscFunctionBegin; 1900e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 190117ab2063SBarry Smith 1902416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1903bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 190417ab2063SBarry Smith if (idx) { 1905bfeeae90SHong Zhang itmp = a->j + a->i[row]; 190626fbe8dcSKarl Rupp if (*nz) *idx = itmp; 190717ab2063SBarry Smith else *idx = 0; 190817ab2063SBarry Smith } 19093a40ed3dSBarry Smith PetscFunctionReturn(0); 191017ab2063SBarry Smith } 191117ab2063SBarry Smith 1912bfeeae90SHong Zhang /* remove this function? */ 1913a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 191417ab2063SBarry Smith { 19153a40ed3dSBarry Smith PetscFunctionBegin; 19163a40ed3dSBarry Smith PetscFunctionReturn(0); 191717ab2063SBarry Smith } 191817ab2063SBarry Smith 1919dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 192017ab2063SBarry Smith { 1921416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 192254f21887SBarry Smith MatScalar *v = a->a; 192336db0b34SBarry Smith PetscReal sum = 0.0; 19246849ba73SBarry Smith PetscErrorCode ierr; 192597f1f81fSBarry Smith PetscInt i,j; 192617ab2063SBarry Smith 19273a40ed3dSBarry Smith PetscFunctionBegin; 192817ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1929570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1930570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 1931570b7f6dSBarry Smith *nrm = BLASnrm2_(&nz,v,&one); 1932570b7f6dSBarry Smith #else 1933416022c9SBarry Smith for (i=0; i<a->nz; i++) { 193436db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 193517ab2063SBarry Smith } 19368f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1937570b7f6dSBarry Smith #endif 193851f70360SJed Brown ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 19393a40ed3dSBarry Smith } else if (type == NORM_1) { 194036db0b34SBarry Smith PetscReal *tmp; 194197f1f81fSBarry Smith PetscInt *jj = a->j; 19421795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 1943064f8208SBarry Smith *nrm = 0.0; 1944416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1945bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 194617ab2063SBarry Smith } 1947d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1948064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 194917ab2063SBarry Smith } 1950606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 195151f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 19523a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1953064f8208SBarry Smith *nrm = 0.0; 1954d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1955bfeeae90SHong Zhang v = a->a + a->i[j]; 195617ab2063SBarry Smith sum = 0.0; 1957416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1958cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 195917ab2063SBarry Smith } 1960064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 196117ab2063SBarry Smith } 196251f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 1963f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 19643a40ed3dSBarry Smith PetscFunctionReturn(0); 196517ab2063SBarry Smith } 196617ab2063SBarry Smith 19674e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 19684e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 19694e938277SHong Zhang { 19704e938277SHong Zhang PetscErrorCode ierr; 19714e938277SHong Zhang PetscInt i,j,anzj; 19724e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 19734e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 19744e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 19754e938277SHong Zhang 19764e938277SHong Zhang PetscFunctionBegin; 19774e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 1978854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 1979785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 1980785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 19814e938277SHong Zhang 19824e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 19834e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 198426fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 19854e938277SHong Zhang /* Form ati for csr format of A^T. */ 198626fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 19874e938277SHong Zhang 19884e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 19894e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 19904e938277SHong Zhang 19914e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 19924e938277SHong Zhang for (i=0;i<am;i++) { 19934e938277SHong Zhang anzj = ai[i+1] - ai[i]; 19944e938277SHong Zhang for (j=0;j<anzj;j++) { 19954e938277SHong Zhang atj[atfill[*aj]] = i; 19964e938277SHong Zhang atfill[*aj++] += 1; 19974e938277SHong Zhang } 19984e938277SHong Zhang } 19994e938277SHong Zhang 20004e938277SHong Zhang /* Clean up temporary space and complete requests. */ 20014e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2002ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 200333d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2004a2f3521dSMark F. Adams 20054e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 20064e938277SHong Zhang b->free_a = PETSC_FALSE; 20074e938277SHong Zhang b->free_ij = PETSC_TRUE; 20084e938277SHong Zhang b->nonew = 0; 20094e938277SHong Zhang PetscFunctionReturn(0); 20104e938277SHong Zhang } 20114e938277SHong Zhang 2012fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 201317ab2063SBarry Smith { 2014416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2015416022c9SBarry Smith Mat C; 20166849ba73SBarry Smith PetscErrorCode ierr; 2017d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 201854f21887SBarry Smith MatScalar *array = a->a; 201917ab2063SBarry Smith 20203a40ed3dSBarry Smith PetscFunctionBegin; 2021cf37664fSBarry Smith if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 2022fc4dec0aSBarry Smith 2023cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 2024854ce69bSBarry Smith ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr); 2025bfeeae90SHong Zhang 2026bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 2027ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2028d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 202933d57670SJed Brown ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 20307adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2031ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 2032606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 2033a541d17aSBarry Smith } else { 2034a541d17aSBarry Smith C = *B; 2035a541d17aSBarry Smith } 2036a541d17aSBarry Smith 203717ab2063SBarry Smith for (i=0; i<m; i++) { 203817ab2063SBarry Smith len = ai[i+1]-ai[i]; 203987d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 2040b9b97703SBarry Smith array += len; 2041b9b97703SBarry Smith aj += len; 204217ab2063SBarry Smith } 20436d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20446d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 204517ab2063SBarry Smith 2046cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 2047416022c9SBarry Smith *B = C; 204817ab2063SBarry Smith } else { 204928be2f97SBarry Smith ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 205017ab2063SBarry Smith } 20513a40ed3dSBarry Smith PetscFunctionReturn(0); 205217ab2063SBarry Smith } 205317ab2063SBarry Smith 20547087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2055cd0d46ebSvictorle { 20563d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 205754f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 205854f21887SBarry Smith MatScalar *va,*vb; 20596849ba73SBarry Smith PetscErrorCode ierr; 206097f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2061cd0d46ebSvictorle 2062cd0d46ebSvictorle PetscFunctionBegin; 2063cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2064cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20655485867bSBarry Smith if (ma!=nb || na!=mb) { 20665485867bSBarry Smith *f = PETSC_FALSE; 20675485867bSBarry Smith PetscFunctionReturn(0); 20685485867bSBarry Smith } 2069cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2070cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2071cd0d46ebSvictorle va = aij->a; vb = bij->a; 2072785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2073785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2074cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2075cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2076cd0d46ebSvictorle 2077cd0d46ebSvictorle *f = PETSC_TRUE; 2078cd0d46ebSvictorle for (i=0; i<ma; i++) { 2079cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 208097f1f81fSBarry Smith PetscInt idc,idr; 20815485867bSBarry Smith PetscScalar vc,vr; 2082cd0d46ebSvictorle /* column/row index/value */ 20835485867bSBarry Smith idc = adx[aptr[i]]; 20845485867bSBarry Smith idr = bdx[bptr[idc]]; 20855485867bSBarry Smith vc = va[aptr[i]]; 20865485867bSBarry Smith vr = vb[bptr[idc]]; 20875485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 20885485867bSBarry Smith *f = PETSC_FALSE; 20895485867bSBarry Smith goto done; 2090cd0d46ebSvictorle } else { 20915485867bSBarry Smith aptr[i]++; 20925485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2093cd0d46ebSvictorle } 2094cd0d46ebSvictorle } 2095cd0d46ebSvictorle } 2096cd0d46ebSvictorle done: 2097cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 20983aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2099cd0d46ebSvictorle PetscFunctionReturn(0); 2100cd0d46ebSvictorle } 2101cd0d46ebSvictorle 21027087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 21031cbb95d3SBarry Smith { 21043d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 210554f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 210654f21887SBarry Smith MatScalar *va,*vb; 21071cbb95d3SBarry Smith PetscErrorCode ierr; 21081cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 21091cbb95d3SBarry Smith 21101cbb95d3SBarry Smith PetscFunctionBegin; 21111cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 21121cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 21131cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 21141cbb95d3SBarry Smith *f = PETSC_FALSE; 21151cbb95d3SBarry Smith PetscFunctionReturn(0); 21161cbb95d3SBarry Smith } 21171cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 21181cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 21191cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2120785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2121785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 21221cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 21231cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 21241cbb95d3SBarry Smith 21251cbb95d3SBarry Smith *f = PETSC_TRUE; 21261cbb95d3SBarry Smith for (i=0; i<ma; i++) { 21271cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 21281cbb95d3SBarry Smith PetscInt idc,idr; 21291cbb95d3SBarry Smith PetscScalar vc,vr; 21301cbb95d3SBarry Smith /* column/row index/value */ 21311cbb95d3SBarry Smith idc = adx[aptr[i]]; 21321cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 21331cbb95d3SBarry Smith vc = va[aptr[i]]; 21341cbb95d3SBarry Smith vr = vb[bptr[idc]]; 21351cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 21361cbb95d3SBarry Smith *f = PETSC_FALSE; 21371cbb95d3SBarry Smith goto done; 21381cbb95d3SBarry Smith } else { 21391cbb95d3SBarry Smith aptr[i]++; 21401cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 21411cbb95d3SBarry Smith } 21421cbb95d3SBarry Smith } 21431cbb95d3SBarry Smith } 21441cbb95d3SBarry Smith done: 21451cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 21461cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 21471cbb95d3SBarry Smith PetscFunctionReturn(0); 21481cbb95d3SBarry Smith } 21491cbb95d3SBarry Smith 2150ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21519e29f15eSvictorle { 2152dfbe8321SBarry Smith PetscErrorCode ierr; 21536e111a19SKarl Rupp 21549e29f15eSvictorle PetscFunctionBegin; 21555485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21569e29f15eSvictorle PetscFunctionReturn(0); 21579e29f15eSvictorle } 21589e29f15eSvictorle 2159ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21601cbb95d3SBarry Smith { 21611cbb95d3SBarry Smith PetscErrorCode ierr; 21626e111a19SKarl Rupp 21631cbb95d3SBarry Smith PetscFunctionBegin; 21641cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21651cbb95d3SBarry Smith PetscFunctionReturn(0); 21661cbb95d3SBarry Smith } 21671cbb95d3SBarry Smith 2168dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 216917ab2063SBarry Smith { 2170416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 217154f21887SBarry Smith PetscScalar *l,*r,x; 217254f21887SBarry Smith MatScalar *v; 2173dfbe8321SBarry Smith PetscErrorCode ierr; 2174d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 217517ab2063SBarry Smith 21763a40ed3dSBarry Smith PetscFunctionBegin; 217717ab2063SBarry Smith if (ll) { 21783ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 21793ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2180e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2181e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 21821ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2183416022c9SBarry Smith v = a->a; 218417ab2063SBarry Smith for (i=0; i<m; i++) { 218517ab2063SBarry Smith x = l[i]; 2186416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 21872205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 218817ab2063SBarry Smith } 21891ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2190efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 219117ab2063SBarry Smith } 219217ab2063SBarry Smith if (rr) { 2193e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2194e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 21951ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2196416022c9SBarry Smith v = a->a; jj = a->j; 21972205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 21981ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2199efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 220017ab2063SBarry Smith } 2201acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 22023a40ed3dSBarry Smith PetscFunctionReturn(0); 220317ab2063SBarry Smith } 220417ab2063SBarry Smith 22057dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 220617ab2063SBarry Smith { 2207db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 22086849ba73SBarry Smith PetscErrorCode ierr; 2209d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 221097f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 22115d0c19d7SBarry Smith const PetscInt *irow,*icol; 22125d0c19d7SBarry Smith PetscInt nrows,ncols; 221397f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 221454f21887SBarry Smith MatScalar *a_new,*mat_a; 2215416022c9SBarry Smith Mat C; 2216cdc6f3adSToby Isaac PetscBool stride; 221717ab2063SBarry Smith 22183a40ed3dSBarry Smith PetscFunctionBegin; 221999141d43SSatish Balay 222017ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2221b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2222b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 222317ab2063SBarry Smith 2224251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2225ff718158SBarry Smith if (stride) { 2226ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2227ff718158SBarry Smith } else { 2228ff718158SBarry Smith first = 0; 2229ff718158SBarry Smith step = 0; 2230ff718158SBarry Smith } 2231fee21e36SBarry Smith if (stride && step == 1) { 223202834360SBarry Smith /* special case of contiguous rows */ 2233dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 223402834360SBarry Smith /* loop over new rows determining lens and starting points */ 223502834360SBarry Smith for (i=0; i<nrows; i++) { 2236bfeeae90SHong Zhang kstart = ai[irow[i]]; 2237a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2238a91a9bebSLisandro Dalcin starts[i] = kstart; 223902834360SBarry Smith for (k=kstart; k<kend; k++) { 2240bfeeae90SHong Zhang if (aj[k] >= first) { 224102834360SBarry Smith starts[i] = k; 224202834360SBarry Smith break; 224302834360SBarry Smith } 224402834360SBarry Smith } 2245a2744918SBarry Smith sum = 0; 224602834360SBarry Smith while (k < kend) { 2247bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2248a2744918SBarry Smith sum++; 224902834360SBarry Smith } 2250a2744918SBarry Smith lens[i] = sum; 225102834360SBarry Smith } 225202834360SBarry Smith /* create submatrix */ 2253cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 225497f1f81fSBarry Smith PetscInt n_cols,n_rows; 225508480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2256e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2257d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 225808480c60SBarry Smith C = *B; 22593a40ed3dSBarry Smith } else { 22603bef6203SJed Brown PetscInt rbs,cbs; 2261ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2262f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22633bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 22643bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 22653bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 22667adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2267ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 226808480c60SBarry Smith } 2269db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2270db02288aSLois Curfman McInnes 227102834360SBarry Smith /* loop over rows inserting into submatrix */ 2272db02288aSLois Curfman McInnes a_new = c->a; 2273db02288aSLois Curfman McInnes j_new = c->j; 2274db02288aSLois Curfman McInnes i_new = c->i; 2275bfeeae90SHong Zhang 227602834360SBarry Smith for (i=0; i<nrows; i++) { 2277a2744918SBarry Smith ii = starts[i]; 2278a2744918SBarry Smith lensi = lens[i]; 2279a2744918SBarry Smith for (k=0; k<lensi; k++) { 2280a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 228102834360SBarry Smith } 228287828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2283a2744918SBarry Smith a_new += lensi; 2284a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2285a2744918SBarry Smith c->ilen[i] = lensi; 228602834360SBarry Smith } 22870e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 22883a40ed3dSBarry Smith } else { 228902834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 22901795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2291854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 22924dcab191SBarry Smith for (i=0; i<ncols; i++) { 22934dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 22944dcab191SBarry 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); 22954dcab191SBarry Smith #endif 22964dcab191SBarry Smith smap[icol[i]] = i+1; 22974dcab191SBarry Smith } 22984dcab191SBarry Smith 229902834360SBarry Smith /* determine lens of each row */ 230002834360SBarry Smith for (i=0; i<nrows; i++) { 2301bfeeae90SHong Zhang kstart = ai[irow[i]]; 230202834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 230302834360SBarry Smith lens[i] = 0; 230402834360SBarry Smith for (k=kstart; k<kend; k++) { 2305bfeeae90SHong Zhang if (smap[aj[k]]) { 230602834360SBarry Smith lens[i]++; 230702834360SBarry Smith } 230802834360SBarry Smith } 230902834360SBarry Smith } 231017ab2063SBarry Smith /* Create and fill new matrix */ 2311a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2312ace3abfcSBarry Smith PetscBool equal; 23130f5bd95cSBarry Smith 231499141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2315e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2316d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 2317f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2318d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 231908480c60SBarry Smith C = *B; 23203a40ed3dSBarry Smith } else { 23213bef6203SJed Brown PetscInt rbs,cbs; 2322ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2323f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 23243bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 23253bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 23263bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 23277adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2328ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 232908480c60SBarry Smith } 233099141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 233117ab2063SBarry Smith for (i=0; i<nrows; i++) { 233299141d43SSatish Balay row = irow[i]; 2333bfeeae90SHong Zhang kstart = ai[row]; 233499141d43SSatish Balay kend = kstart + a->ilen[row]; 2335bfeeae90SHong Zhang mat_i = c->i[i]; 233699141d43SSatish Balay mat_j = c->j + mat_i; 233799141d43SSatish Balay mat_a = c->a + mat_i; 233899141d43SSatish Balay mat_ilen = c->ilen + i; 233917ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2340bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2341ed480e8bSBarry Smith *mat_j++ = tcol - 1; 234299141d43SSatish Balay *mat_a++ = a->a[k]; 234399141d43SSatish Balay (*mat_ilen)++; 234499141d43SSatish Balay 234517ab2063SBarry Smith } 234617ab2063SBarry Smith } 234717ab2063SBarry Smith } 234802834360SBarry Smith /* Free work space */ 234902834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2350606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2351606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2352cdc6f3adSToby Isaac /* sort */ 2353cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2354cdc6f3adSToby Isaac PetscInt ilen; 2355cdc6f3adSToby Isaac 2356cdc6f3adSToby Isaac mat_i = c->i[i]; 2357cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2358cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2359cdc6f3adSToby Isaac ilen = c->ilen[i]; 2360390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2361cdc6f3adSToby Isaac } 236202834360SBarry Smith } 23636d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23646d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 236517ab2063SBarry Smith 236617ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2367416022c9SBarry Smith *B = C; 23683a40ed3dSBarry Smith PetscFunctionReturn(0); 236917ab2063SBarry Smith } 237017ab2063SBarry Smith 2371fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 237282d44351SHong Zhang { 237382d44351SHong Zhang PetscErrorCode ierr; 237482d44351SHong Zhang Mat B; 237582d44351SHong Zhang 237682d44351SHong Zhang PetscFunctionBegin; 2377c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 237882d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 237982d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 238033d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 238182d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 238282d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 238382d44351SHong Zhang *subMat = B; 2384c2d650bdSHong Zhang } else { 2385c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2386c2d650bdSHong Zhang } 238782d44351SHong Zhang PetscFunctionReturn(0); 238882d44351SHong Zhang } 238982d44351SHong Zhang 23909a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2391a871dcd8SBarry Smith { 239263b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2393dfbe8321SBarry Smith PetscErrorCode ierr; 239463b91edcSBarry Smith Mat outA; 2395ace3abfcSBarry Smith PetscBool row_identity,col_identity; 239663b91edcSBarry Smith 23973a40ed3dSBarry Smith PetscFunctionBegin; 2398e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 23991df811f5SHong Zhang 2400b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2401b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2402a871dcd8SBarry Smith 240363b91edcSBarry Smith outA = inA; 2404d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2405f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2406f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 24072205254eSKarl Rupp 2408c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 24096bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 24102205254eSKarl Rupp 2411c3122656SLisandro Dalcin a->row = row; 24122205254eSKarl Rupp 2413c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 24146bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 24152205254eSKarl Rupp 2416c3122656SLisandro Dalcin a->col = col; 241763b91edcSBarry Smith 241836db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 24196bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 24204c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 24213bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2422f0ec6fceSSatish Balay 242394a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2424854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 24253bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 242694a9d846SBarry Smith } 242763b91edcSBarry Smith 2428f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2429137fb511SHong Zhang if (row_identity && col_identity) { 2430ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2431137fb511SHong Zhang } else { 2432719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2433137fb511SHong Zhang } 24343a40ed3dSBarry Smith PetscFunctionReturn(0); 2435a871dcd8SBarry Smith } 2436a871dcd8SBarry Smith 2437f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2438f0b747eeSBarry Smith { 2439f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2440f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2441efee365bSSatish Balay PetscErrorCode ierr; 2442c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 24433a40ed3dSBarry Smith 24443a40ed3dSBarry Smith PetscFunctionBegin; 2445c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 24468b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2447efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2448acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 24493a40ed3dSBarry Smith PetscFunctionReturn(0); 2450f0b747eeSBarry Smith } 2451f0b747eeSBarry Smith 24525c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj) 245316b64355SHong Zhang { 245416b64355SHong Zhang PetscErrorCode ierr; 245516b64355SHong Zhang PetscInt i; 245616b64355SHong Zhang 245716b64355SHong Zhang PetscFunctionBegin; 245816b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 245916b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 246016b64355SHong Zhang 246116b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 246216b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 246316b64355SHong Zhang } 246416b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 246516b64355SHong Zhang 246616b64355SHong Zhang if (submatj->rbuf1) { 246716b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 246816b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 246916b64355SHong Zhang } 247016b64355SHong Zhang 247116b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 247216b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 247316b64355SHong Zhang } 247416b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 247516b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 247616b64355SHong Zhang } 247716b64355SHong Zhang 247816b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 247916b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 248016b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 248116b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 248216b64355SHong Zhang #else 248316b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 248416b64355SHong Zhang #endif 248516b64355SHong Zhang 248616b64355SHong Zhang if (!submatj->allcolumns) { 248716b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 248816b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 248916b64355SHong Zhang #else 249016b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 249116b64355SHong Zhang #endif 249216b64355SHong Zhang } 249316b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 249416b64355SHong Zhang 249516b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 249616b64355SHong Zhang PetscFunctionReturn(0); 249716b64355SHong Zhang } 249816b64355SHong Zhang 249916b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C) 250016b64355SHong Zhang { 250116b64355SHong Zhang PetscErrorCode ierr; 250216b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 25035c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 250416b64355SHong Zhang 250516b64355SHong Zhang PetscFunctionBegin; 250616b64355SHong Zhang ierr = submatj->destroy(C);CHKERRQ(ierr); 2507e69d178cSHong Zhang ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr); 250816b64355SHong Zhang PetscFunctionReturn(0); 250916b64355SHong Zhang } 251016b64355SHong Zhang 25117dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2512cddf8d76SBarry Smith { 2513dfbe8321SBarry Smith PetscErrorCode ierr; 251497f1f81fSBarry Smith PetscInt i; 2515cddf8d76SBarry Smith 25163a40ed3dSBarry Smith PetscFunctionBegin; 2517cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2518df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2519cddf8d76SBarry Smith } 2520cddf8d76SBarry Smith 2521cddf8d76SBarry Smith for (i=0; i<n; i++) { 25227dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2523cddf8d76SBarry Smith } 25243a40ed3dSBarry Smith PetscFunctionReturn(0); 2525cddf8d76SBarry Smith } 2526cddf8d76SBarry Smith 252797f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 25284dcbc457SBarry Smith { 2529e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25306849ba73SBarry Smith PetscErrorCode ierr; 25315d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 25325d0c19d7SBarry Smith const PetscInt *idx; 253397f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2534f1af5d2fSBarry Smith PetscBT table; 2535bbd702dbSSatish Balay 25363a40ed3dSBarry Smith PetscFunctionBegin; 2537d0f46423SBarry Smith m = A->rmap->n; 2538e4d965acSSatish Balay ai = a->i; 2539bfeeae90SHong Zhang aj = a->j; 25408a047759SSatish Balay 2541e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 254206763907SSatish Balay 2543854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 254453b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 254506763907SSatish Balay 2546e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2547b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2548e4d965acSSatish Balay isz = 0; 25496831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2550e4d965acSSatish Balay 2551e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 25524dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2553b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2554e4d965acSSatish Balay 2555dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2556e4d965acSSatish Balay for (j=0; j<n; ++j) { 25572205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 25584dcbc457SBarry Smith } 255906763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 25606bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2561e4d965acSSatish Balay 256204a348a9SBarry Smith k = 0; 256304a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 256404a348a9SBarry Smith n = isz; 256506763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2566e4d965acSSatish Balay row = nidx[k]; 2567e4d965acSSatish Balay start = ai[row]; 2568e4d965acSSatish Balay end = ai[row+1]; 256904a348a9SBarry Smith for (l = start; l<end; l++) { 2570efb16452SHong Zhang val = aj[l]; 25712205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2572e4d965acSSatish Balay } 2573e4d965acSSatish Balay } 2574e4d965acSSatish Balay } 257570b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2576e4d965acSSatish Balay } 257794bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2578606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 25793a40ed3dSBarry Smith PetscFunctionReturn(0); 25804dcbc457SBarry Smith } 258117ab2063SBarry Smith 25820513a670SBarry Smith /* -------------------------------------------------------------- */ 2583dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 25840513a670SBarry Smith { 25850513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25866849ba73SBarry Smith PetscErrorCode ierr; 25873b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 25885d0c19d7SBarry Smith const PetscInt *row,*col; 25895d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 259056cd22aeSBarry Smith IS icolp,irowp; 25910298fd71SBarry Smith PetscInt *cwork = NULL; 25920298fd71SBarry Smith PetscScalar *vwork = NULL; 25930513a670SBarry Smith 25943a40ed3dSBarry Smith PetscFunctionBegin; 25954c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 259656cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 25974c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 259856cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 25990513a670SBarry Smith 26000513a670SBarry Smith /* determine lengths of permuted rows */ 2601854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 26022205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2603ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2604f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 260533d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 26067adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2607ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2608606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 26090513a670SBarry Smith 2610785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 26110513a670SBarry Smith for (i=0; i<m; i++) { 261232ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 26132205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2614cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 261532ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 26160513a670SBarry Smith } 2617606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 26182205254eSKarl Rupp 26193c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 26202205254eSKarl Rupp 26210513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 26220513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 262356cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 262456cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 26256bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 26266bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 26273a40ed3dSBarry Smith PetscFunctionReturn(0); 26280513a670SBarry Smith } 26290513a670SBarry Smith 2630dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2631cb5b572fSBarry Smith { 2632dfbe8321SBarry Smith PetscErrorCode ierr; 2633cb5b572fSBarry Smith 2634cb5b572fSBarry Smith PetscFunctionBegin; 263533f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 263633f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2637be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2638be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2639be6bf707SBarry Smith 2640700c5bfcSBarry 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"); 2641d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2642cb5b572fSBarry Smith } else { 2643cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2644cb5b572fSBarry Smith } 2645cb5b572fSBarry Smith PetscFunctionReturn(0); 2646cb5b572fSBarry Smith } 2647cb5b572fSBarry Smith 26484994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2649273d9f13SBarry Smith { 2650dfbe8321SBarry Smith PetscErrorCode ierr; 2651273d9f13SBarry Smith 2652273d9f13SBarry Smith PetscFunctionBegin; 2653ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2654273d9f13SBarry Smith PetscFunctionReturn(0); 2655273d9f13SBarry Smith } 2656273d9f13SBarry Smith 26578c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 26586c0721eeSBarry Smith { 26596c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 26606e111a19SKarl Rupp 26616c0721eeSBarry Smith PetscFunctionBegin; 26626c0721eeSBarry Smith *array = a->a; 26636c0721eeSBarry Smith PetscFunctionReturn(0); 26646c0721eeSBarry Smith } 26656c0721eeSBarry Smith 26668c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 26676c0721eeSBarry Smith { 26686c0721eeSBarry Smith PetscFunctionBegin; 26696c0721eeSBarry Smith PetscFunctionReturn(0); 26706c0721eeSBarry Smith } 2671273d9f13SBarry Smith 26728229c054SShri Abhyankar /* 26738229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 26748229c054SShri Abhyankar have different nonzero structure. 26758229c054SShri Abhyankar */ 2676b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 2677ec7775f6SShri Abhyankar { 2678b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 2679ec7775f6SShri Abhyankar 2680ec7775f6SShri Abhyankar PetscFunctionBegin; 2681ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2682ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 2683b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 2684b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 2685b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 26868af7cee1SJed Brown nnz[i] = 0; 26878af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 2688b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 2689b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 26908af7cee1SJed Brown nnz[i]++; 26918af7cee1SJed Brown } 26928af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2693ec7775f6SShri Abhyankar } 2694ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2695ec7775f6SShri Abhyankar } 2696ec7775f6SShri Abhyankar 2697b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2698b264fe52SHong Zhang { 2699b264fe52SHong Zhang PetscInt m = Y->rmap->N; 2700b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2701b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2702b264fe52SHong Zhang PetscErrorCode ierr; 2703b264fe52SHong Zhang 2704b264fe52SHong Zhang PetscFunctionBegin; 2705b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 2706b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 2707b264fe52SHong Zhang PetscFunctionReturn(0); 2708b264fe52SHong Zhang } 2709b264fe52SHong Zhang 2710f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2711ac90fabeSBarry Smith { 2712dfbe8321SBarry Smith PetscErrorCode ierr; 2713ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2714c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2715ac90fabeSBarry Smith 2716ac90fabeSBarry Smith PetscFunctionBegin; 2717c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2718ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2719f4df32b1SMatthew Knepley PetscScalar alpha = a; 27208b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2721acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2722a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 2723ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2724ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2725ac90fabeSBarry Smith } else { 27268229c054SShri Abhyankar Mat B; 27278229c054SShri Abhyankar PetscInt *nnz; 2728785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 2729ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 2730bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 27314aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 273233d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr); 2733176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 27348229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2735ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2736ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 273728be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 27388229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2739ac90fabeSBarry Smith } 2740ac90fabeSBarry Smith PetscFunctionReturn(0); 2741ac90fabeSBarry Smith } 2742ac90fabeSBarry Smith 27437087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2744354c94deSBarry Smith { 2745354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2746354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 2747354c94deSBarry Smith PetscInt i,nz; 2748354c94deSBarry Smith PetscScalar *a; 2749354c94deSBarry Smith 2750354c94deSBarry Smith PetscFunctionBegin; 2751354c94deSBarry Smith nz = aij->nz; 2752354c94deSBarry Smith a = aij->a; 27532205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 2754354c94deSBarry Smith #else 2755354c94deSBarry Smith PetscFunctionBegin; 2756354c94deSBarry Smith #endif 2757354c94deSBarry Smith PetscFunctionReturn(0); 2758354c94deSBarry Smith } 2759354c94deSBarry Smith 2760985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2761e34fafa9SBarry Smith { 2762e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2763e34fafa9SBarry Smith PetscErrorCode ierr; 2764d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2765e34fafa9SBarry Smith PetscReal atmp; 2766985db425SBarry Smith PetscScalar *x; 2767e34fafa9SBarry Smith MatScalar *aa; 2768e34fafa9SBarry Smith 2769e34fafa9SBarry Smith PetscFunctionBegin; 2770e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2771e34fafa9SBarry Smith aa = a->a; 2772e34fafa9SBarry Smith ai = a->i; 2773e34fafa9SBarry Smith aj = a->j; 2774e34fafa9SBarry Smith 2775985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2776e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2777e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2778e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2779e34fafa9SBarry Smith for (i=0; i<m; i++) { 2780e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 27819189402eSHong Zhang x[i] = 0.0; 2782e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 2783985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2784985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2785985db425SBarry Smith aa++; aj++; 2786985db425SBarry Smith } 2787985db425SBarry Smith } 2788985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2789985db425SBarry Smith PetscFunctionReturn(0); 2790985db425SBarry Smith } 2791985db425SBarry Smith 2792985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2793985db425SBarry Smith { 2794985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2795985db425SBarry Smith PetscErrorCode ierr; 2796d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2797985db425SBarry Smith PetscScalar *x; 2798985db425SBarry Smith MatScalar *aa; 2799985db425SBarry Smith 2800985db425SBarry Smith PetscFunctionBegin; 2801e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2802985db425SBarry Smith aa = a->a; 2803985db425SBarry Smith ai = a->i; 2804985db425SBarry Smith aj = a->j; 2805985db425SBarry Smith 2806985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2807985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2808985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2809e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2810985db425SBarry Smith for (i=0; i<m; i++) { 2811985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2812d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2813985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2814985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2815985db425SBarry Smith x[i] = 0.0; 2816985db425SBarry Smith if (idx) { 2817985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2818985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2819985db425SBarry Smith if (aj[j] > j) { 2820985db425SBarry Smith idx[i] = j; 2821985db425SBarry Smith break; 2822985db425SBarry Smith } 2823985db425SBarry Smith } 2824985db425SBarry Smith } 2825985db425SBarry Smith } 2826985db425SBarry Smith for (j=0; j<ncols; j++) { 2827985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2828985db425SBarry Smith aa++; aj++; 2829985db425SBarry Smith } 2830985db425SBarry Smith } 2831985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2832985db425SBarry Smith PetscFunctionReturn(0); 2833985db425SBarry Smith } 2834985db425SBarry Smith 2835c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2836c87e5d42SMatthew Knepley { 2837c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2838c87e5d42SMatthew Knepley PetscErrorCode ierr; 2839c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2840c87e5d42SMatthew Knepley PetscReal atmp; 2841c87e5d42SMatthew Knepley PetscScalar *x; 2842c87e5d42SMatthew Knepley MatScalar *aa; 2843c87e5d42SMatthew Knepley 2844c87e5d42SMatthew Knepley PetscFunctionBegin; 2845e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2846c87e5d42SMatthew Knepley aa = a->a; 2847c87e5d42SMatthew Knepley ai = a->i; 2848c87e5d42SMatthew Knepley aj = a->j; 2849c87e5d42SMatthew Knepley 2850c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2851c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2852c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 285360e0710aSBarry 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); 2854c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2855c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2856289a08f5SMatthew Knepley if (ncols) { 2857289a08f5SMatthew Knepley /* Get first nonzero */ 2858289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 2859289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 28602205254eSKarl Rupp if (atmp > 1.0e-12) { 28612205254eSKarl Rupp x[i] = atmp; 28622205254eSKarl Rupp if (idx) idx[i] = aj[j]; 28632205254eSKarl Rupp break; 28642205254eSKarl Rupp } 2865289a08f5SMatthew Knepley } 286612431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 2867289a08f5SMatthew Knepley } else { 2868289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2869289a08f5SMatthew Knepley } 2870c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 2871c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2872289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2873c87e5d42SMatthew Knepley aa++; aj++; 2874c87e5d42SMatthew Knepley } 2875c87e5d42SMatthew Knepley } 2876c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2877c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2878c87e5d42SMatthew Knepley } 2879c87e5d42SMatthew Knepley 2880985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2881985db425SBarry Smith { 2882985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2883985db425SBarry Smith PetscErrorCode ierr; 2884d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 2885d9ca1df4SBarry Smith const PetscInt *ai,*aj; 2886985db425SBarry Smith PetscScalar *x; 2887d9ca1df4SBarry Smith const MatScalar *aa; 2888985db425SBarry Smith 2889985db425SBarry Smith PetscFunctionBegin; 2890e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2891985db425SBarry Smith aa = a->a; 2892985db425SBarry Smith ai = a->i; 2893985db425SBarry Smith aj = a->j; 2894985db425SBarry Smith 2895985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2896985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2897985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2898e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2899985db425SBarry Smith for (i=0; i<m; i++) { 2900985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2901d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2902985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2903985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2904985db425SBarry Smith x[i] = 0.0; 2905985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2906985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2907985db425SBarry Smith for (j=0; j<ncols; j++) { 2908985db425SBarry Smith if (aj[j] > j) { 2909985db425SBarry Smith idx[i] = j; 2910985db425SBarry Smith break; 2911985db425SBarry Smith } 2912985db425SBarry Smith } 2913985db425SBarry Smith } 2914985db425SBarry Smith } 2915985db425SBarry Smith for (j=0; j<ncols; j++) { 2916985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2917985db425SBarry Smith aa++; aj++; 2918e34fafa9SBarry Smith } 2919e34fafa9SBarry Smith } 2920e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2921e34fafa9SBarry Smith PetscFunctionReturn(0); 2922e34fafa9SBarry Smith } 2923bbead8a2SBarry Smith 2924bbead8a2SBarry Smith #include <petscblaslapack.h> 2925af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h> 2926bbead8a2SBarry Smith 2927713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 2928bbead8a2SBarry Smith { 2929bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 2930bbead8a2SBarry Smith PetscErrorCode ierr; 293133d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 2932bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 2933bbead8a2SBarry Smith PetscReal shift = 0.0; 29341a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 2935bbead8a2SBarry Smith 2936bbead8a2SBarry Smith PetscFunctionBegin; 2937a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 29384a0d0026SBarry Smith if (a->ibdiagvalid) { 29394a0d0026SBarry Smith if (values) *values = a->ibdiag; 29404a0d0026SBarry Smith PetscFunctionReturn(0); 29414a0d0026SBarry Smith } 2942bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 2943bbead8a2SBarry Smith if (!a->ibdiag) { 2944785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 29453bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 2946bbead8a2SBarry Smith } 2947bbead8a2SBarry Smith diag = a->ibdiag; 2948bbead8a2SBarry Smith if (values) *values = a->ibdiag; 2949bbead8a2SBarry Smith /* factor and invert each block */ 2950bbead8a2SBarry Smith switch (bs) { 2951bbead8a2SBarry Smith case 1: 2952bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2953bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 2954ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 2955ec1892c8SHong Zhang if (allowzeropivot) { 29567b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 29577b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 29587b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 29597b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 29607b6c816cSBarry 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); 2961ec1892c8SHong Zhang } 2962bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 2963bbead8a2SBarry Smith } 2964bbead8a2SBarry Smith break; 2965bbead8a2SBarry Smith case 2: 2966bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2967bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 2968bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 2969a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29707b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 297196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 2972bbead8a2SBarry Smith diag += 4; 2973bbead8a2SBarry Smith } 2974bbead8a2SBarry Smith break; 2975bbead8a2SBarry Smith case 3: 2976bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2977bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 2978bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 2979a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29807b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 298196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 2982bbead8a2SBarry Smith diag += 9; 2983bbead8a2SBarry Smith } 2984bbead8a2SBarry Smith break; 2985bbead8a2SBarry Smith case 4: 2986bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2987bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 2988bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 2989a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29907b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 299196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 2992bbead8a2SBarry Smith diag += 16; 2993bbead8a2SBarry Smith } 2994bbead8a2SBarry Smith break; 2995bbead8a2SBarry Smith case 5: 2996bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2997bbead8a2SBarry 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; 2998bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 2999a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 30007b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 300196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3002bbead8a2SBarry Smith diag += 25; 3003bbead8a2SBarry Smith } 3004bbead8a2SBarry Smith break; 3005bbead8a2SBarry Smith case 6: 3006bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3007bbead8a2SBarry 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; 3008bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3009a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 30107b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 301196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3012bbead8a2SBarry Smith diag += 36; 3013bbead8a2SBarry Smith } 3014bbead8a2SBarry Smith break; 3015bbead8a2SBarry Smith case 7: 3016bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3017bbead8a2SBarry 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; 3018bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3019a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 30207b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 302196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3022bbead8a2SBarry Smith diag += 49; 3023bbead8a2SBarry Smith } 3024bbead8a2SBarry Smith break; 3025bbead8a2SBarry Smith default: 3026dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3027bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3028bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3029bbead8a2SBarry Smith IJ[j] = bs*i + j; 3030bbead8a2SBarry Smith } 3031bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 30325f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 30337b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 303496b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3035bbead8a2SBarry Smith diag += bs2; 3036bbead8a2SBarry Smith } 3037bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3038bbead8a2SBarry Smith } 3039bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3040bbead8a2SBarry Smith PetscFunctionReturn(0); 3041bbead8a2SBarry Smith } 3042bbead8a2SBarry Smith 304373a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 304473a71a0fSBarry Smith { 304573a71a0fSBarry Smith PetscErrorCode ierr; 304673a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 304773a71a0fSBarry Smith PetscScalar a; 304873a71a0fSBarry Smith PetscInt m,n,i,j,col; 304973a71a0fSBarry Smith 305073a71a0fSBarry Smith PetscFunctionBegin; 305173a71a0fSBarry Smith if (!x->assembled) { 305273a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 305373a71a0fSBarry Smith for (i=0; i<m; i++) { 305473a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 305573a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 305673a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 305773a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 305873a71a0fSBarry Smith } 305973a71a0fSBarry Smith } 306073a71a0fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded"); 306173a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 306273a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 306373a71a0fSBarry Smith PetscFunctionReturn(0); 306473a71a0fSBarry Smith } 306573a71a0fSBarry Smith 30667d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a) 30677d68702bSBarry Smith { 30687d68702bSBarry Smith PetscErrorCode ierr; 30697d68702bSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)Y->data; 30707d68702bSBarry Smith 30717d68702bSBarry Smith PetscFunctionBegin; 30726f33a894SBarry Smith if (!Y->preallocated || !aij->nz) { 30737d68702bSBarry Smith ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr); 30747d68702bSBarry Smith } 30757d68702bSBarry Smith ierr = MatShift_Basic(Y,a);CHKERRQ(ierr); 30767d68702bSBarry Smith PetscFunctionReturn(0); 30777d68702bSBarry Smith } 30787d68702bSBarry Smith 3079682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 30800a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3081cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3082cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3083cb5b572fSBarry Smith MatMult_SeqAIJ, 308497304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 30857c922b88SBarry Smith MatMultTranspose_SeqAIJ, 30867c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3087db4efbfdSBarry Smith 0, 3088db4efbfdSBarry Smith 0, 3089db4efbfdSBarry Smith 0, 3090db4efbfdSBarry Smith /* 10*/ 0, 3091cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3092cb5b572fSBarry Smith 0, 309341f059aeSBarry Smith MatSOR_SeqAIJ, 309417ab2063SBarry Smith MatTranspose_SeqAIJ, 309597304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3096cb5b572fSBarry Smith MatEqual_SeqAIJ, 3097cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3098cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3099cb5b572fSBarry Smith MatNorm_SeqAIJ, 310097304618SKris Buschelman /* 20*/ 0, 3101cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3102cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3103cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3104d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3105db4efbfdSBarry Smith 0, 3106db4efbfdSBarry Smith 0, 3107db4efbfdSBarry Smith 0, 3108db4efbfdSBarry Smith 0, 31094994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3110db4efbfdSBarry Smith 0, 3111db4efbfdSBarry Smith 0, 31128c778c55SBarry Smith 0, 31138c778c55SBarry Smith 0, 3114d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3115cb5b572fSBarry Smith 0, 3116cb5b572fSBarry Smith 0, 3117cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3118cb5b572fSBarry Smith 0, 3119d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 31207dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3121cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3122cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3123cb5b572fSBarry Smith MatCopy_SeqAIJ, 3124d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3125cb5b572fSBarry Smith MatScale_SeqAIJ, 31267d68702bSBarry Smith MatShift_SeqAIJ, 312779299369SBarry Smith MatDiagonalSet_SeqAIJ, 31286e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 312973a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 31303b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 31313b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 31323b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3133a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 313493dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3135b9617806SBarry Smith 0, 31360513a670SBarry Smith 0, 3137cda55fadSBarry Smith MatPermute_SeqAIJ, 3138cda55fadSBarry Smith 0, 3139d519adbfSMatthew Knepley /* 59*/ 0, 3140b9b97703SBarry Smith MatDestroy_SeqAIJ, 3141b9b97703SBarry Smith MatView_SeqAIJ, 3142357abbc8SBarry Smith 0, 3143321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3144321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3145321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3146ee4f033dSBarry Smith 0, 3147ee4f033dSBarry Smith 0, 3148ee4f033dSBarry Smith 0, 3149d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3150c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3151ee4f033dSBarry Smith 0, 3152dcf5cc72SBarry Smith 0, 31532c93a97aSBarry Smith 0, 31542c93a97aSBarry Smith /* 74*/ 0, 31553acb8795SBarry Smith MatFDColoringApply_AIJ, 315697304618SKris Buschelman 0, 315797304618SKris Buschelman 0, 315897304618SKris Buschelman 0, 31596ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 316097304618SKris Buschelman 0, 316197304618SKris Buschelman 0, 316297304618SKris Buschelman 0, 3163bc011b1eSHong Zhang MatLoad_SeqAIJ, 3164d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 31651cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 31666284ec50SHong Zhang 0, 31676284ec50SHong Zhang 0, 3168bc011b1eSHong Zhang 0, 3169d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 317026be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 317126be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 317265e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 31734a1b09b7SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy, 317465e8a0caSHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 31756fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 31766fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 31776fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 31782121bac1SHong Zhang 0, 31792121bac1SHong Zhang /* 99*/ 0, 3180609c6c4dSKris Buschelman 0, 3181609c6c4dSKris Buschelman 0, 318287d4246cSBarry Smith MatConjugate_SeqAIJ, 318387d4246cSBarry Smith 0, 3184d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 318599cafbc1SBarry Smith MatRealPart_SeqAIJ, 3186f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3187f5edf698SHong Zhang 0, 31882bebee5dSHong Zhang 0, 3189cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3190985db425SBarry Smith 0, 31912af78befSBarry Smith MatGetRowMin_SeqAIJ, 31922af78befSBarry Smith 0, 3193599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3194d519adbfSMatthew Knepley /*114*/ 0, 3195599ef60dSHong Zhang 0, 31963c2a7987SHong Zhang 0, 3197fe97e370SBarry Smith 0, 3198fbdbba38SShri Abhyankar 0, 3199fbdbba38SShri Abhyankar /*119*/ 0, 3200fbdbba38SShri Abhyankar 0, 3201fbdbba38SShri Abhyankar 0, 320282d44351SHong Zhang 0, 3203b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 32040716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3205bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 320637868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 320737868618SMatthew G Knepley 0, 320837868618SMatthew G Knepley 0, 32095df89d91SHong Zhang /*129*/ 0, 321075648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 321175648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 321275648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3213b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3214b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 32152b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 32162b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 32172b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 32183964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 32193964eb88SJed Brown /*139*/0, 3220f9426fe0SMark Adams 0, 32211919a2e2SJed Brown 0, 32223a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 32239c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 32249c8f2541SHong Zhang /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ 32259e29f15eSvictorle }; 322617ab2063SBarry Smith 32277087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3228bef8e0ddSBarry Smith { 3229bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 323097f1f81fSBarry Smith PetscInt i,nz,n; 3231bef8e0ddSBarry Smith 3232bef8e0ddSBarry Smith PetscFunctionBegin; 3233bef8e0ddSBarry Smith nz = aij->maxnz; 3234d0f46423SBarry Smith n = mat->rmap->n; 3235bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3236bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3237bef8e0ddSBarry Smith } 3238bef8e0ddSBarry Smith aij->nz = nz; 3239bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3240bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3241bef8e0ddSBarry Smith } 3242bef8e0ddSBarry Smith PetscFunctionReturn(0); 3243bef8e0ddSBarry Smith } 3244bef8e0ddSBarry Smith 3245bef8e0ddSBarry Smith /*@ 3246bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3247bef8e0ddSBarry Smith in the matrix. 3248bef8e0ddSBarry Smith 3249bef8e0ddSBarry Smith Input Parameters: 3250bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3251bef8e0ddSBarry Smith - indices - the column indices 3252bef8e0ddSBarry Smith 325315091d37SBarry Smith Level: advanced 325415091d37SBarry Smith 3255bef8e0ddSBarry Smith Notes: 3256bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3257bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3258bef8e0ddSBarry Smith of the MatSetValues() operation. 3259bef8e0ddSBarry Smith 3260bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3261d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3262bef8e0ddSBarry Smith 3263bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3264bef8e0ddSBarry Smith 3265b9617806SBarry Smith The indices should start with zero, not one. 3266b9617806SBarry Smith 3267bef8e0ddSBarry Smith @*/ 32687087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3269bef8e0ddSBarry Smith { 32704ac538c5SBarry Smith PetscErrorCode ierr; 3271bef8e0ddSBarry Smith 3272bef8e0ddSBarry Smith PetscFunctionBegin; 32730700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 32744482741eSBarry Smith PetscValidPointer(indices,2); 32754ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3276bef8e0ddSBarry Smith PetscFunctionReturn(0); 3277bef8e0ddSBarry Smith } 3278bef8e0ddSBarry Smith 3279be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3280be6bf707SBarry Smith 32817087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3282be6bf707SBarry Smith { 3283be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 32846849ba73SBarry Smith PetscErrorCode ierr; 3285d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3286be6bf707SBarry Smith 3287be6bf707SBarry Smith PetscFunctionBegin; 3288169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3289be6bf707SBarry Smith 3290be6bf707SBarry Smith /* allocate space for values if not already there */ 3291be6bf707SBarry Smith if (!aij->saved_values) { 3292854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 32933bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3294be6bf707SBarry Smith } 3295be6bf707SBarry Smith 3296be6bf707SBarry Smith /* copy values over */ 329787828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3298be6bf707SBarry Smith PetscFunctionReturn(0); 3299be6bf707SBarry Smith } 3300be6bf707SBarry Smith 3301be6bf707SBarry Smith /*@ 3302be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3303be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3304be6bf707SBarry Smith nonlinear portion. 3305be6bf707SBarry Smith 3306be6bf707SBarry Smith Collect on Mat 3307be6bf707SBarry Smith 3308be6bf707SBarry Smith Input Parameters: 33090e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3310be6bf707SBarry Smith 331115091d37SBarry Smith Level: advanced 331215091d37SBarry Smith 3313be6bf707SBarry Smith Common Usage, with SNESSolve(): 3314be6bf707SBarry Smith $ Create Jacobian matrix 3315be6bf707SBarry Smith $ Set linear terms into matrix 3316be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3317be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3318be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3319512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3320be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3321be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3322be6bf707SBarry Smith $ In your Jacobian routine 3323be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3324be6bf707SBarry Smith $ Set nonlinear terms in matrix 3325be6bf707SBarry Smith 3326be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3327be6bf707SBarry Smith $ // build linear portion of Jacobian 3328512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3329be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3330be6bf707SBarry Smith $ loop over nonlinear iterations 3331be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3332be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3333be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3334be6bf707SBarry Smith $ Solve linear system with Jacobian 3335be6bf707SBarry Smith $ endloop 3336be6bf707SBarry Smith 3337be6bf707SBarry Smith Notes: 3338be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3339512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3340be6bf707SBarry Smith calling this routine. 3341be6bf707SBarry Smith 33420c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 33430c468ba9SBarry Smith and does not allocated additional space. 33440c468ba9SBarry Smith 3345be6bf707SBarry Smith .seealso: MatRetrieveValues() 3346be6bf707SBarry Smith 3347be6bf707SBarry Smith @*/ 33487087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3349be6bf707SBarry Smith { 33504ac538c5SBarry Smith PetscErrorCode ierr; 3351be6bf707SBarry Smith 3352be6bf707SBarry Smith PetscFunctionBegin; 33530700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3354e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3355e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33564ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3357be6bf707SBarry Smith PetscFunctionReturn(0); 3358be6bf707SBarry Smith } 3359be6bf707SBarry Smith 33607087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3361be6bf707SBarry Smith { 3362be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 33636849ba73SBarry Smith PetscErrorCode ierr; 3364d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3365be6bf707SBarry Smith 3366be6bf707SBarry Smith PetscFunctionBegin; 3367169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3368f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3369be6bf707SBarry Smith /* copy values over */ 337087828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3371be6bf707SBarry Smith PetscFunctionReturn(0); 3372be6bf707SBarry Smith } 3373be6bf707SBarry Smith 3374be6bf707SBarry Smith /*@ 3375be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3376be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3377be6bf707SBarry Smith nonlinear portion. 3378be6bf707SBarry Smith 3379be6bf707SBarry Smith Collect on Mat 3380be6bf707SBarry Smith 3381be6bf707SBarry Smith Input Parameters: 3382386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3383be6bf707SBarry Smith 338415091d37SBarry Smith Level: advanced 338515091d37SBarry Smith 3386be6bf707SBarry Smith .seealso: MatStoreValues() 3387be6bf707SBarry Smith 3388be6bf707SBarry Smith @*/ 33897087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3390be6bf707SBarry Smith { 33914ac538c5SBarry Smith PetscErrorCode ierr; 3392be6bf707SBarry Smith 3393be6bf707SBarry Smith PetscFunctionBegin; 33940700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3395e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3396e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33974ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3398be6bf707SBarry Smith PetscFunctionReturn(0); 3399be6bf707SBarry Smith } 3400be6bf707SBarry Smith 3401f83d6046SBarry Smith 3402be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 340317ab2063SBarry Smith /*@C 3404682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 34050d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 34066e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 340751c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 34082bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 340917ab2063SBarry Smith 3410db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3411db81eaa0SLois Curfman McInnes 341217ab2063SBarry Smith Input Parameters: 3413db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 341417ab2063SBarry Smith . m - number of rows 341517ab2063SBarry Smith . n - number of columns 341617ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 341751c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 34180298fd71SBarry Smith (possibly different for each row) or NULL 341917ab2063SBarry Smith 342017ab2063SBarry Smith Output Parameter: 3421416022c9SBarry Smith . A - the matrix 342217ab2063SBarry Smith 3423175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3424ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3425175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3426175b88e8SBarry Smith 3427b259b22eSLois Curfman McInnes Notes: 342849a6f317SBarry Smith If nnz is given then nz is ignored 342949a6f317SBarry Smith 343017ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 343117ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 34320002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 343344cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 343417ab2063SBarry Smith 343517ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34360298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 34373d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 34386da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 343917ab2063SBarry Smith 3440682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 34414fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3442682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 34436c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 34446c7ebb05SLois Curfman McInnes 34456c7ebb05SLois Curfman McInnes Options Database Keys: 3446698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 34479db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 344817ab2063SBarry Smith 3449027ccd11SLois Curfman McInnes Level: intermediate 3450027ccd11SLois Curfman McInnes 345169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 345236db0b34SBarry Smith 345317ab2063SBarry Smith @*/ 34547087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 345517ab2063SBarry Smith { 3456dfbe8321SBarry Smith PetscErrorCode ierr; 34576945ee14SBarry Smith 34583a40ed3dSBarry Smith PetscFunctionBegin; 3459f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3460117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3461c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3462d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3463273d9f13SBarry Smith PetscFunctionReturn(0); 3464273d9f13SBarry Smith } 3465273d9f13SBarry Smith 3466273d9f13SBarry Smith /*@C 3467273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3468273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3469273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3470273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3471273d9f13SBarry Smith 3472273d9f13SBarry Smith Collective on MPI_Comm 3473273d9f13SBarry Smith 3474273d9f13SBarry Smith Input Parameters: 34751c4f3114SJed Brown + B - The matrix 3476273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3477273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 34780298fd71SBarry Smith (possibly different for each row) or NULL 3479273d9f13SBarry Smith 3480273d9f13SBarry Smith Notes: 348149a6f317SBarry Smith If nnz is given then nz is ignored 348249a6f317SBarry Smith 3483273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3484273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3485273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3486273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3487273d9f13SBarry Smith 3488273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34890298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3490273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3491273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3492273d9f13SBarry Smith 3493aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3494aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3495aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3496aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3497aa95bbe8SBarry Smith 3498a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3499a96a251dSBarry Smith entries or columns indices 3500a96a251dSBarry Smith 3501273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3502273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3503273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3504273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3505273d9f13SBarry Smith 3506273d9f13SBarry Smith Options Database Keys: 3507698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3508698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3509273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3510273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3511273d9f13SBarry Smith the user still MUST index entries starting at 0! 3512273d9f13SBarry Smith 3513273d9f13SBarry Smith Level: intermediate 3514273d9f13SBarry Smith 351569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3516273d9f13SBarry Smith 3517273d9f13SBarry Smith @*/ 35187087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3519273d9f13SBarry Smith { 35204ac538c5SBarry Smith PetscErrorCode ierr; 3521a23d5eceSKris Buschelman 3522a23d5eceSKris Buschelman PetscFunctionBegin; 35236ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 35246ba663aaSJed Brown PetscValidType(B,1); 35254ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3526a23d5eceSKris Buschelman PetscFunctionReturn(0); 3527a23d5eceSKris Buschelman } 3528a23d5eceSKris Buschelman 35297087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3530a23d5eceSKris Buschelman { 3531273d9f13SBarry Smith Mat_SeqAIJ *b; 35322576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 35336849ba73SBarry Smith PetscErrorCode ierr; 353497f1f81fSBarry Smith PetscInt i; 3535273d9f13SBarry Smith 3536273d9f13SBarry Smith PetscFunctionBegin; 35372576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3538a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3539c461c341SBarry Smith skipallocation = PETSC_TRUE; 3540c461c341SBarry Smith nz = 0; 3541c461c341SBarry Smith } 354226283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 354326283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3544899cda47SBarry Smith 3545435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 354660e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 3547b73539f3SBarry Smith if (nnz) { 3548d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 354960e0710aSBarry 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]); 355060e0710aSBarry 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); 3551b73539f3SBarry Smith } 3552b73539f3SBarry Smith } 3553b73539f3SBarry Smith 3554273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 35552205254eSKarl Rupp 3556273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3557273d9f13SBarry Smith 3558ab93d7beSBarry Smith if (!skipallocation) { 35592ee49352SLisandro Dalcin if (!b->imax) { 3560dcca6d9dSJed Brown ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr); 35613bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 35622ee49352SLisandro Dalcin } 3563273d9f13SBarry Smith if (!nnz) { 3564435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3565c62bd62aSJed Brown else if (nz < 0) nz = 1; 3566d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3567d0f46423SBarry Smith nz = nz*B->rmap->n; 3568273d9f13SBarry Smith } else { 3569273d9f13SBarry Smith nz = 0; 3570d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3571273d9f13SBarry Smith } 3572ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 35732205254eSKarl Rupp for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0; 3574ab93d7beSBarry Smith 3575273d9f13SBarry Smith /* allocate the matrix space */ 357653dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 35772ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3578396832f4SHong Zhang if (B->structure_only) { 35795848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 35805848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 3581396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 3582396832f4SHong Zhang } else { 3583dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 35843bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3585396832f4SHong Zhang } 3586bfeeae90SHong Zhang b->i[0] = 0; 3587d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 35885da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 35895da197adSKris Buschelman } 3590396832f4SHong Zhang if (B->structure_only) { 3591396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 3592396832f4SHong Zhang b->free_a = PETSC_FALSE; 3593396832f4SHong Zhang } else { 3594273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3595e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3596396832f4SHong Zhang } 3597e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3598c461c341SBarry Smith } else { 3599e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3600e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3601c461c341SBarry Smith } 3602273d9f13SBarry Smith 3603273d9f13SBarry Smith b->nz = 0; 3604273d9f13SBarry Smith b->maxnz = nz; 3605273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 36062205254eSKarl Rupp if (realalloc) { 36072205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 36082205254eSKarl Rupp } 3609cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 3610cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 3611273d9f13SBarry Smith PetscFunctionReturn(0); 3612273d9f13SBarry Smith } 3613273d9f13SBarry Smith 361458d36128SBarry Smith /*@ 3615a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3616a1661176SMatthew Knepley 3617a1661176SMatthew Knepley Input Parameters: 3618a1661176SMatthew Knepley + B - the matrix 3619a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3620a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3621a1661176SMatthew Knepley - v - optional values in the matrix 3622a1661176SMatthew Knepley 3623a1661176SMatthew Knepley Level: developer 3624a1661176SMatthew Knepley 362558d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 362658d36128SBarry Smith 3627a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3628a1661176SMatthew Knepley 3629a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3630a1661176SMatthew Knepley @*/ 3631a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3632a1661176SMatthew Knepley { 3633a1661176SMatthew Knepley PetscErrorCode ierr; 3634a1661176SMatthew Knepley 3635a1661176SMatthew Knepley PetscFunctionBegin; 36360700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 36376ba663aaSJed Brown PetscValidType(B,1); 36384ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3639a1661176SMatthew Knepley PetscFunctionReturn(0); 3640a1661176SMatthew Knepley } 3641a1661176SMatthew Knepley 36427087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3643a1661176SMatthew Knepley { 3644a1661176SMatthew Knepley PetscInt i; 3645a1661176SMatthew Knepley PetscInt m,n; 3646a1661176SMatthew Knepley PetscInt nz; 3647a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3648a1661176SMatthew Knepley PetscScalar *values; 3649a1661176SMatthew Knepley PetscErrorCode ierr; 3650a1661176SMatthew Knepley 3651a1661176SMatthew Knepley PetscFunctionBegin; 365265e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3653779a8d59SSatish Balay 3654779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3655779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3656779a8d59SSatish Balay 3657779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3658854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 3659a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3660b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3661a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 366265e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3663a1661176SMatthew Knepley nnz[i] = nz; 3664a1661176SMatthew Knepley } 3665a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3666a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3667a1661176SMatthew Knepley 3668a1661176SMatthew Knepley if (v) { 3669a1661176SMatthew Knepley values = (PetscScalar*) v; 3670a1661176SMatthew Knepley } else { 36711795a4d1SJed Brown ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr); 3672a1661176SMatthew Knepley } 3673a1661176SMatthew Knepley 3674a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3675b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3676b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3677a1661176SMatthew Knepley } 3678a1661176SMatthew Knepley 3679a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3680a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3681a1661176SMatthew Knepley 3682a1661176SMatthew Knepley if (!v) { 3683a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3684a1661176SMatthew Knepley } 36857827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3686a1661176SMatthew Knepley PetscFunctionReturn(0); 3687a1661176SMatthew Knepley } 3688a1661176SMatthew Knepley 3689c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 3690af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 3691170fe5c8SBarry Smith 3692170fe5c8SBarry Smith /* 3693170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3694170fe5c8SBarry Smith 3695170fe5c8SBarry Smith n p p 3696170fe5c8SBarry Smith ( ) ( ) ( ) 3697170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3698170fe5c8SBarry Smith ( ) ( ) ( ) 3699170fe5c8SBarry Smith 3700170fe5c8SBarry Smith */ 3701170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3702170fe5c8SBarry Smith { 3703170fe5c8SBarry Smith PetscErrorCode ierr; 3704170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3705170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3706170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 37071de00fd4SBarry Smith PetscInt i,n,m,q,p; 3708170fe5c8SBarry Smith const PetscInt *ii,*idx; 3709170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3710170fe5c8SBarry Smith PetscScalar *c,*c_q; 3711170fe5c8SBarry Smith 3712170fe5c8SBarry Smith PetscFunctionBegin; 3713d0f46423SBarry Smith m = A->rmap->n; 3714d0f46423SBarry Smith n = A->cmap->n; 3715d0f46423SBarry Smith p = B->cmap->n; 3716170fe5c8SBarry Smith a = sub_a->v; 3717170fe5c8SBarry Smith b = sub_b->a; 3718170fe5c8SBarry Smith c = sub_c->v; 3719170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3720170fe5c8SBarry Smith 3721170fe5c8SBarry Smith ii = sub_b->i; 3722170fe5c8SBarry Smith idx = sub_b->j; 3723170fe5c8SBarry Smith for (i=0; i<n; i++) { 3724170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3725170fe5c8SBarry Smith while (q-->0) { 3726170fe5c8SBarry Smith c_q = c + m*(*idx); 3727170fe5c8SBarry Smith a_q = a + m*i; 3728854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 3729170fe5c8SBarry Smith idx++; 3730170fe5c8SBarry Smith b++; 3731170fe5c8SBarry Smith } 3732170fe5c8SBarry Smith } 3733170fe5c8SBarry Smith PetscFunctionReturn(0); 3734170fe5c8SBarry Smith } 3735170fe5c8SBarry Smith 3736170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3737170fe5c8SBarry Smith { 3738170fe5c8SBarry Smith PetscErrorCode ierr; 3739d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3740170fe5c8SBarry Smith Mat Cmat; 3741170fe5c8SBarry Smith 3742170fe5c8SBarry Smith PetscFunctionBegin; 374360e0710aSBarry 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); 3744ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 3745170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 374633d57670SJed Brown ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr); 3747170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 37480298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 3749d73949e8SHong Zhang 3750d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 37512205254eSKarl Rupp 3752170fe5c8SBarry Smith *C = Cmat; 3753170fe5c8SBarry Smith PetscFunctionReturn(0); 3754170fe5c8SBarry Smith } 3755170fe5c8SBarry Smith 3756170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3757150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3758170fe5c8SBarry Smith { 3759170fe5c8SBarry Smith PetscErrorCode ierr; 3760170fe5c8SBarry Smith 3761170fe5c8SBarry Smith PetscFunctionBegin; 3762170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 37633ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3764170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 37653ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3766170fe5c8SBarry Smith } 37673ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3768170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 37693ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3770170fe5c8SBarry Smith PetscFunctionReturn(0); 3771170fe5c8SBarry Smith } 3772170fe5c8SBarry Smith 3773170fe5c8SBarry Smith 37740bad9183SKris Buschelman /*MC 3775fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 37760bad9183SKris Buschelman based on compressed sparse row format. 37770bad9183SKris Buschelman 37780bad9183SKris Buschelman Options Database Keys: 37790bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 37800bad9183SKris Buschelman 37810bad9183SKris Buschelman Level: beginner 37820bad9183SKris Buschelman 3783f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 37840bad9183SKris Buschelman M*/ 37850bad9183SKris Buschelman 3786ccd284c7SBarry Smith /*MC 3787ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 3788ccd284c7SBarry Smith 3789ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 3790ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 3791ccd284c7SBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported 3792ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3793ccd284c7SBarry Smith the above preallocation routines for simplicity. 3794ccd284c7SBarry Smith 3795ccd284c7SBarry Smith Options Database Keys: 3796ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 3797ccd284c7SBarry Smith 3798ccd284c7SBarry Smith Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when 3799ccd284c7SBarry Smith enough exist. 3800ccd284c7SBarry Smith 3801ccd284c7SBarry Smith Level: beginner 3802ccd284c7SBarry Smith 3803ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 3804ccd284c7SBarry Smith M*/ 3805ccd284c7SBarry Smith 3806ccd284c7SBarry Smith /*MC 3807ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 3808ccd284c7SBarry Smith 3809ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 3810ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 3811ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 3812ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3813ccd284c7SBarry Smith the above preallocation routines for simplicity. 3814ccd284c7SBarry Smith 3815ccd284c7SBarry Smith Options Database Keys: 3816ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 3817ccd284c7SBarry Smith 3818ccd284c7SBarry Smith Level: beginner 3819ccd284c7SBarry Smith 3820ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 3821ccd284c7SBarry Smith M*/ 3822ccd284c7SBarry Smith 3823cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 3824af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3825cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 3826af8000cdSHong Zhang #endif 382763c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 382863c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 38293dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 383063c07aadSStefano Zampini #endif 3831cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 383242c9c57cSBarry Smith 3833b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 383429b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 383529b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3836b3866ffcSBarry Smith #endif 383717667f90SBarry Smith 3838c0c8ee5eSDmitry Karpeev 38398c778c55SBarry Smith /*@C 38408397e458SBarry Smith MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored 38418c778c55SBarry Smith 38428c778c55SBarry Smith Not Collective 38438c778c55SBarry Smith 38448c778c55SBarry Smith Input Parameter: 3845579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 38468c778c55SBarry Smith 38478c778c55SBarry Smith Output Parameter: 38488c778c55SBarry Smith . array - pointer to the data 38498c778c55SBarry Smith 38508c778c55SBarry Smith Level: intermediate 38518c778c55SBarry Smith 3852774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 38538c778c55SBarry Smith @*/ 38548c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 38558c778c55SBarry Smith { 38568c778c55SBarry Smith PetscErrorCode ierr; 38578c778c55SBarry Smith 38588c778c55SBarry Smith PetscFunctionBegin; 38598c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 38608c778c55SBarry Smith PetscFunctionReturn(0); 38618c778c55SBarry Smith } 38628c778c55SBarry Smith 386321e72a00SBarry Smith /*@C 386421e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 386521e72a00SBarry Smith 386621e72a00SBarry Smith Not Collective 386721e72a00SBarry Smith 386821e72a00SBarry Smith Input Parameter: 3869579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 387021e72a00SBarry Smith 387121e72a00SBarry Smith Output Parameter: 387221e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 387321e72a00SBarry Smith 387421e72a00SBarry Smith Level: intermediate 387521e72a00SBarry Smith 387621e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 387721e72a00SBarry Smith @*/ 387821e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 387921e72a00SBarry Smith { 388021e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 388121e72a00SBarry Smith 388221e72a00SBarry Smith PetscFunctionBegin; 388321e72a00SBarry Smith *nz = aij->rmax; 388421e72a00SBarry Smith PetscFunctionReturn(0); 388521e72a00SBarry Smith } 388621e72a00SBarry Smith 38878c778c55SBarry Smith /*@C 3888579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 38898c778c55SBarry Smith 38908c778c55SBarry Smith Not Collective 38918c778c55SBarry Smith 38928c778c55SBarry Smith Input Parameters: 3893579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 38948c778c55SBarry Smith . array - pointer to the data 38958c778c55SBarry Smith 38968c778c55SBarry Smith Level: intermediate 38978c778c55SBarry Smith 3898774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 38998c778c55SBarry Smith @*/ 39008c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 39018c778c55SBarry Smith { 39028c778c55SBarry Smith PetscErrorCode ierr; 39038c778c55SBarry Smith 39048c778c55SBarry Smith PetscFunctionBegin; 39058c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 39068c778c55SBarry Smith PetscFunctionReturn(0); 39078c778c55SBarry Smith } 39088c778c55SBarry Smith 39098cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 3910273d9f13SBarry Smith { 3911273d9f13SBarry Smith Mat_SeqAIJ *b; 3912dfbe8321SBarry Smith PetscErrorCode ierr; 391338baddfdSBarry Smith PetscMPIInt size; 3914273d9f13SBarry Smith 3915273d9f13SBarry Smith PetscFunctionBegin; 3916ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 3917e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3918273d9f13SBarry Smith 3919b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 39202205254eSKarl Rupp 3921b0a32e0cSBarry Smith B->data = (void*)b; 39222205254eSKarl Rupp 3923549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 39242205254eSKarl Rupp 3925416022c9SBarry Smith b->row = 0; 3926416022c9SBarry Smith b->col = 0; 392782bf6240SBarry Smith b->icol = 0; 3928b810aeb4SBarry Smith b->reallocs = 0; 392936db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3930f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3931416022c9SBarry Smith b->nonew = 0; 3932416022c9SBarry Smith b->diag = 0; 3933416022c9SBarry Smith b->solve_work = 0; 39342a1b7f2aSHong Zhang B->spptr = 0; 3935be6bf707SBarry Smith b->saved_values = 0; 3936d7f994e1SBarry Smith b->idiag = 0; 393771f1c65dSBarry Smith b->mdiag = 0; 393871f1c65dSBarry Smith b->ssor_work = 0; 393971f1c65dSBarry Smith b->omega = 1.0; 394071f1c65dSBarry Smith b->fshift = 0.0; 394171f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3942bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 3943a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 394417ab2063SBarry Smith 394535d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3946bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 3947bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 39488c778c55SBarry Smith 3949b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3950bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 3951bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 3952b3866ffcSBarry Smith #endif 395317f1a0eaSHong Zhang 3954bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3955bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3956bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3957bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 3958bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3959bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 3960bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 3961af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3962af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 3963af8000cdSHong Zhang #endif 396463c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 396563c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 39663dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr); 396763c07aadSStefano Zampini #endif 3968b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 3969bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3970bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3971bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3972bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 3973bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 3974bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 3975bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 3976bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 39774108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 397817667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 39793a40ed3dSBarry Smith PetscFunctionReturn(0); 398017ab2063SBarry Smith } 398117ab2063SBarry Smith 3982b24902e0SBarry Smith /* 3983b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 3984b24902e0SBarry Smith */ 3985ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 398617ab2063SBarry Smith { 3987416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 39886849ba73SBarry Smith PetscErrorCode ierr; 3989d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 399017ab2063SBarry Smith 39913a40ed3dSBarry Smith PetscFunctionBegin; 3992273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3993273d9f13SBarry Smith 3994d5f3da31SBarry Smith C->factortype = A->factortype; 3995416022c9SBarry Smith c->row = 0; 3996416022c9SBarry Smith c->col = 0; 399782bf6240SBarry Smith c->icol = 0; 39986ad4291fSHong Zhang c->reallocs = 0; 399917ab2063SBarry Smith 40006ad4291fSHong Zhang C->assembled = PETSC_TRUE; 400117ab2063SBarry Smith 4002aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4003aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4004eec197d1SBarry Smith 4005dcca6d9dSJed Brown ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr); 40063bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 400717ab2063SBarry Smith for (i=0; i<m; i++) { 4008416022c9SBarry Smith c->imax[i] = a->imax[i]; 4009416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 401017ab2063SBarry Smith } 401117ab2063SBarry Smith 401217ab2063SBarry Smith /* allocate the matrix space */ 4013f77e22a1SHong Zhang if (mallocmatspace) { 4014dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 40153bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 40162205254eSKarl Rupp 4017f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 40182205254eSKarl Rupp 401997f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 402017ab2063SBarry Smith if (m > 0) { 402197f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 4022be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 4023bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 4024be6bf707SBarry Smith } else { 4025bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 402617ab2063SBarry Smith } 402708480c60SBarry Smith } 4028f77e22a1SHong Zhang } 402917ab2063SBarry Smith 40306ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4031416022c9SBarry Smith c->roworiented = a->roworiented; 4032416022c9SBarry Smith c->nonew = a->nonew; 4033416022c9SBarry Smith if (a->diag) { 4034854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 40353bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 403617ab2063SBarry Smith for (i=0; i<m; i++) { 4037416022c9SBarry Smith c->diag[i] = a->diag[i]; 403817ab2063SBarry Smith } 40393a40ed3dSBarry Smith } else c->diag = 0; 40402205254eSKarl Rupp 40416ad4291fSHong Zhang c->solve_work = 0; 40426ad4291fSHong Zhang c->saved_values = 0; 40436ad4291fSHong Zhang c->idiag = 0; 404471f1c65dSBarry Smith c->ssor_work = 0; 4045a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4046e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4047e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 40486ad4291fSHong Zhang 4049893ad86cSHong Zhang c->rmax = a->rmax; 4050416022c9SBarry Smith c->nz = a->nz; 40518ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4052273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4053754ec7b1SSatish Balay 40546ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 40556ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4056cd6b891eSBarry Smith if (a->compressedrow.use) { 40576ad4291fSHong Zhang i = a->compressedrow.nrows; 4058dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 40596ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 40606ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 406127ea64f8SHong Zhang } else { 406227ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 40630298fd71SBarry Smith c->compressedrow.i = NULL; 40640298fd71SBarry Smith c->compressedrow.rindex = NULL; 40656ad4291fSHong Zhang } 4066ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4067e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 40684846f1f5SKris Buschelman 40692205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4070140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 40713a40ed3dSBarry Smith PetscFunctionReturn(0); 407217ab2063SBarry Smith } 407317ab2063SBarry Smith 4074b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4075b24902e0SBarry Smith { 4076b24902e0SBarry Smith PetscErrorCode ierr; 4077b24902e0SBarry Smith 4078b24902e0SBarry Smith PetscFunctionBegin; 4079ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 40804b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4081cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 408233d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4083cfd3f464SBarry Smith } 4084a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4085f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4086b24902e0SBarry Smith PetscFunctionReturn(0); 4087b24902e0SBarry Smith } 4088b24902e0SBarry Smith 4089112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4090fbdbba38SShri Abhyankar { 4091fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4092fbdbba38SShri Abhyankar PetscErrorCode ierr; 4093fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4094fbdbba38SShri Abhyankar int fd; 4095fbdbba38SShri Abhyankar PetscMPIInt size; 4096fbdbba38SShri Abhyankar MPI_Comm comm; 40973059b6faSBarry Smith PetscInt bs = newMat->rmap->bs; 4098fbdbba38SShri Abhyankar 4099fbdbba38SShri Abhyankar PetscFunctionBegin; 4100c98fd787SBarry Smith /* force binary viewer to load .info file if it has not yet done so */ 4101c98fd787SBarry Smith ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4102fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4103fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4104fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4105bbead8a2SBarry Smith 41060298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 41070298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4108bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 41093059b6faSBarry Smith if (bs < 0) bs = 1; 41103059b6faSBarry Smith ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr); 4111bbead8a2SBarry Smith 4112fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 4113fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 4114fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4115fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4116fbdbba38SShri Abhyankar 4117bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4118fbdbba38SShri Abhyankar 4119fbdbba38SShri Abhyankar /* read in row lengths */ 4120785e854fSJed Brown ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr); 4121fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 4122fbdbba38SShri Abhyankar 4123fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4124fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 412560e0710aSBarry 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); 4126fbdbba38SShri Abhyankar 4127fbdbba38SShri Abhyankar /* set global size if not set already*/ 4128f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4129fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4130aabbc4fbSShri Abhyankar } else { 41319d36ed5fSBarry Smith /* if sizes and type are already set, check if the matrix global sizes are correct */ 4132fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 41334c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 41344c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 41354c5b953cSHong Zhang } 413660e0710aSBarry 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); 4137aabbc4fbSShri Abhyankar } 4138fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4139fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4140fbdbba38SShri Abhyankar 4141fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 4142fbdbba38SShri Abhyankar 4143fbdbba38SShri Abhyankar /* read in nonzero values */ 4144fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 4145fbdbba38SShri Abhyankar 4146fbdbba38SShri Abhyankar /* set matrix "i" values */ 4147fbdbba38SShri Abhyankar a->i[0] = 0; 4148fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4149fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4150fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4151fbdbba38SShri Abhyankar } 4152fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4153fbdbba38SShri Abhyankar 4154fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4155fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4156fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4157fbdbba38SShri Abhyankar } 4158fbdbba38SShri Abhyankar 4159ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 41607264ac53SSatish Balay { 41617264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4162dfbe8321SBarry Smith PetscErrorCode ierr; 4163eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4164eeffb40dSHong Zhang PetscInt k; 4165eeffb40dSHong Zhang #endif 41667264ac53SSatish Balay 41673a40ed3dSBarry Smith PetscFunctionBegin; 4168bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4169d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4170ca44d042SBarry Smith *flg = PETSC_FALSE; 4171ca44d042SBarry Smith PetscFunctionReturn(0); 4172bcd2baecSBarry Smith } 41737264ac53SSatish Balay 41747264ac53SSatish Balay /* if the a->i are the same */ 4175d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4176abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 41777264ac53SSatish Balay 41787264ac53SSatish Balay /* if a->j are the same */ 417997f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4180abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4181bcd2baecSBarry Smith 4182bcd2baecSBarry Smith /* if a->a are the same */ 4183eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4184eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4185eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4186eeffb40dSHong Zhang *flg = PETSC_FALSE; 41873a40ed3dSBarry Smith PetscFunctionReturn(0); 4188eeffb40dSHong Zhang } 4189eeffb40dSHong Zhang } 4190eeffb40dSHong Zhang #else 4191eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4192eeffb40dSHong Zhang #endif 4193eeffb40dSHong Zhang PetscFunctionReturn(0); 41947264ac53SSatish Balay } 419536db0b34SBarry Smith 419605869f15SSatish Balay /*@ 419736db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 419836db0b34SBarry Smith provided by the user. 419936db0b34SBarry Smith 4200c75a6043SHong Zhang Collective on MPI_Comm 420136db0b34SBarry Smith 420236db0b34SBarry Smith Input Parameters: 420336db0b34SBarry Smith + comm - must be an MPI communicator of size 1 420436db0b34SBarry Smith . m - number of rows 420536db0b34SBarry Smith . n - number of columns 420636db0b34SBarry Smith . i - row indices 420736db0b34SBarry Smith . j - column indices 420836db0b34SBarry Smith - a - matrix values 420936db0b34SBarry Smith 421036db0b34SBarry Smith Output Parameter: 421136db0b34SBarry Smith . mat - the matrix 421236db0b34SBarry Smith 421336db0b34SBarry Smith Level: intermediate 421436db0b34SBarry Smith 421536db0b34SBarry Smith Notes: 42160551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4217292fb18eSBarry Smith once the matrix is destroyed and not before 421836db0b34SBarry Smith 421936db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 422036db0b34SBarry Smith 4221bfeeae90SHong Zhang The i and j indices are 0 based 422236db0b34SBarry Smith 4223a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4224a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 42258eef79e4SBarry Smith as shown 4226a4552177SSatish Balay 42278eef79e4SBarry Smith $ 1 0 0 42288eef79e4SBarry Smith $ 2 0 3 42298eef79e4SBarry Smith $ 4 5 6 42308eef79e4SBarry Smith $ 42318eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 42328eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 42338eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4234a4552177SSatish Balay 42359985e31cSBarry Smith 423669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 423736db0b34SBarry Smith 423836db0b34SBarry Smith @*/ 4239c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 424036db0b34SBarry Smith { 4241dfbe8321SBarry Smith PetscErrorCode ierr; 4242cbcfb4deSHong Zhang PetscInt ii; 424336db0b34SBarry Smith Mat_SeqAIJ *aij; 4244cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4245cbcfb4deSHong Zhang PetscInt jj; 4246cbcfb4deSHong Zhang #endif 424736db0b34SBarry Smith 424836db0b34SBarry Smith PetscFunctionBegin; 424941096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4250f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4251f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4252a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4253ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4254ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4255ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4256dcca6d9dSJed Brown ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr); 4257ab93d7beSBarry Smith 425836db0b34SBarry Smith aij->i = i; 425936db0b34SBarry Smith aij->j = j; 426036db0b34SBarry Smith aij->a = a; 426136db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 426236db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4263e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4264e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 426536db0b34SBarry Smith 426636db0b34SBarry Smith for (ii=0; ii<m; ii++) { 426736db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 42682515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 426960e0710aSBarry 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]); 42709985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4271e32f2f54SBarry Smith if (j[jj] < j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is not sorted",jj-i[ii],j[jj],ii); 4272e32f2f54SBarry Smith if (j[jj] == j[jj]-1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is identical to previous entry",jj-i[ii],j[jj],ii); 42739985e31cSBarry Smith } 427436db0b34SBarry Smith #endif 427536db0b34SBarry Smith } 42762515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 427736db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 427860e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 427960e0710aSBarry 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]); 428036db0b34SBarry Smith } 428136db0b34SBarry Smith #endif 428236db0b34SBarry Smith 4283b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4284b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 428536db0b34SBarry Smith PetscFunctionReturn(0); 428636db0b34SBarry Smith } 428780ef6e79SMatthew G Knepley /*@C 4288d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 42898a0b0e6bSVictor Minden provided by the user. 42908a0b0e6bSVictor Minden 42918a0b0e6bSVictor Minden Collective on MPI_Comm 42928a0b0e6bSVictor Minden 42938a0b0e6bSVictor Minden Input Parameters: 42948a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 42958a0b0e6bSVictor Minden . m - number of rows 42968a0b0e6bSVictor Minden . n - number of columns 42978a0b0e6bSVictor Minden . i - row indices 42988a0b0e6bSVictor Minden . j - column indices 42991230e6d1SVictor Minden . a - matrix values 43001230e6d1SVictor Minden . nz - number of nonzeros 43011230e6d1SVictor Minden - idx - 0 or 1 based 43028a0b0e6bSVictor Minden 43038a0b0e6bSVictor Minden Output Parameter: 43048a0b0e6bSVictor Minden . mat - the matrix 43058a0b0e6bSVictor Minden 43068a0b0e6bSVictor Minden Level: intermediate 43078a0b0e6bSVictor Minden 43088a0b0e6bSVictor Minden Notes: 43098a0b0e6bSVictor Minden The i and j indices are 0 based 43108a0b0e6bSVictor Minden 43118a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 43128a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 43138a0b0e6bSVictor Minden as shown: 43148a0b0e6bSVictor Minden 43158a0b0e6bSVictor Minden 1 0 0 43168a0b0e6bSVictor Minden 2 0 3 43178a0b0e6bSVictor Minden 4 5 6 43188a0b0e6bSVictor Minden 43198a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 43208a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 43218a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 43228a0b0e6bSVictor Minden 43238a0b0e6bSVictor Minden 432469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 43258a0b0e6bSVictor Minden 43268a0b0e6bSVictor Minden @*/ 4327c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 43288a0b0e6bSVictor Minden { 43298a0b0e6bSVictor Minden PetscErrorCode ierr; 4330d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 43318a0b0e6bSVictor Minden 43328a0b0e6bSVictor Minden 43338a0b0e6bSVictor Minden PetscFunctionBegin; 43341795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 43351230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4336c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 43371230e6d1SVictor Minden } 43388a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 43398a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 43408a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 43411230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 43421230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 43431230e6d1SVictor Minden if (idx) { 43441230e6d1SVictor Minden row = i[ii] - 1; 43451230e6d1SVictor Minden col = j[ii] - 1; 43461230e6d1SVictor Minden } else { 43471230e6d1SVictor Minden row = i[ii]; 43481230e6d1SVictor Minden col = j[ii]; 43498a0b0e6bSVictor Minden } 43501230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 43518a0b0e6bSVictor Minden } 43528a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 43538a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4354d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 43558a0b0e6bSVictor Minden PetscFunctionReturn(0); 43568a0b0e6bSVictor Minden } 435736db0b34SBarry Smith 4358acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4359acf2f550SJed Brown { 4360acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4361acf2f550SJed Brown PetscErrorCode ierr; 4362acf2f550SJed Brown 4363acf2f550SJed Brown PetscFunctionBegin; 4364acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4365acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 43662205254eSKarl Rupp 4367acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4368acf2f550SJed Brown PetscFunctionReturn(0); 4369acf2f550SJed Brown } 4370acf2f550SJed Brown 43719c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 43729c8f2541SHong Zhang { 43739c8f2541SHong Zhang PetscErrorCode ierr; 43748761c3d6SHong Zhang PetscMPIInt size; 43759c8f2541SHong Zhang 43769c8f2541SHong Zhang PetscFunctionBegin; 43778761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 43788761c3d6SHong Zhang if (size == 1 && scall == MAT_REUSE_MATRIX) { 43798761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 43808761c3d6SHong Zhang } else { 43819c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 43828761c3d6SHong Zhang } 43839c8f2541SHong Zhang PetscFunctionReturn(0); 43849c8f2541SHong Zhang } 43859c8f2541SHong Zhang 438681824310SBarry Smith /* 438753dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 438853dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 438953dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 439053dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 439153dd7562SDmitry Karpeev */ 439253dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 439353dd7562SDmitry Karpeev { 439453dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 439553dd7562SDmitry Karpeev PetscErrorCode ierr; 439653dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 439753dd7562SDmitry Karpeev PetscBool seqaij; 439853dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 439953dd7562SDmitry Karpeev PetscScalar v; 440053dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 440153dd7562SDmitry Karpeev 440253dd7562SDmitry Karpeev PetscFunctionBegin; 440353dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 440453dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 440553dd7562SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 440653dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 440753dd7562SDmitry Karpeev if (rowemb) { 440853dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 440953dd7562SDmitry 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); 441053dd7562SDmitry Karpeev } else { 44116c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 441253dd7562SDmitry Karpeev } 441353dd7562SDmitry Karpeev if (colemb) { 441453dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 441553dd7562SDmitry 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); 441653dd7562SDmitry Karpeev } else { 441753dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 441853dd7562SDmitry Karpeev } 441953dd7562SDmitry Karpeev 442053dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 442153dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 442253dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 442353dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 442453dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 442553dd7562SDmitry Karpeev } 442653dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 442753dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 442853dd7562SDmitry Karpeev } 442953dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 443053dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 443153dd7562SDmitry Karpeev } 443253dd7562SDmitry Karpeev count = 0; 443353dd7562SDmitry Karpeev rowindices = NULL; 443453dd7562SDmitry Karpeev colindices = NULL; 443553dd7562SDmitry Karpeev if (rowemb) { 443653dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 443753dd7562SDmitry Karpeev } 443853dd7562SDmitry Karpeev if (colemb) { 443953dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 444053dd7562SDmitry Karpeev } 444153dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 444253dd7562SDmitry Karpeev PetscInt row; 444353dd7562SDmitry Karpeev row = i; 444453dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 444553dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 444653dd7562SDmitry Karpeev PetscInt col; 444753dd7562SDmitry Karpeev col = Baij->j[count]; 444853dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 444953dd7562SDmitry Karpeev v = Baij->a[count]; 445053dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 445153dd7562SDmitry Karpeev ++count; 445253dd7562SDmitry Karpeev } 445353dd7562SDmitry Karpeev } 445453dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 445553dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 445653dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 445753dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 445853dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 445953dd7562SDmitry Karpeev PetscFunctionReturn(0); 446053dd7562SDmitry Karpeev } 446153dd7562SDmitry Karpeev 446253dd7562SDmitry Karpeev 446353dd7562SDmitry Karpeev /* 446481824310SBarry Smith Special version for direct calls from Fortran 446581824310SBarry Smith */ 4466af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 446781824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 446881824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 446981824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 447081824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 447181824310SBarry Smith #endif 447281824310SBarry Smith 447381824310SBarry Smith /* Change these macros so can be used in void function */ 447481824310SBarry Smith #undef CHKERRQ 4475ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 447681824310SBarry Smith #undef SETERRQ2 4477e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 44784994cf47SJed Brown #undef SETERRQ3 44794994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 448081824310SBarry Smith 44818cc058d9SJed 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) 448281824310SBarry Smith { 448381824310SBarry Smith Mat A = *AA; 448481824310SBarry Smith PetscInt m = *mm, n = *nn; 448581824310SBarry Smith InsertMode is = *isis; 448681824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 448781824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 448881824310SBarry Smith PetscInt *imax,*ai,*ailen; 448981824310SBarry Smith PetscErrorCode ierr; 449081824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 449154f21887SBarry Smith MatScalar *ap,value,*aa; 4492ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4493ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 449481824310SBarry Smith 449581824310SBarry Smith PetscFunctionBegin; 44964994cf47SJed Brown MatCheckPreallocated(A,1); 449781824310SBarry Smith imax = a->imax; 449881824310SBarry Smith ai = a->i; 449981824310SBarry Smith ailen = a->ilen; 450081824310SBarry Smith aj = a->j; 450181824310SBarry Smith aa = a->a; 450281824310SBarry Smith 450381824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 450481824310SBarry Smith row = im[k]; 450581824310SBarry Smith if (row < 0) continue; 450681824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4507ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 450881824310SBarry Smith #endif 450981824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 451081824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 451181824310SBarry Smith low = 0; 451281824310SBarry Smith high = nrow; 451381824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 451481824310SBarry Smith if (in[l] < 0) continue; 451581824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4516ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 451781824310SBarry Smith #endif 451881824310SBarry Smith col = in[l]; 45192205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 45202205254eSKarl Rupp else value = v[k + l*m]; 45212205254eSKarl Rupp 452281824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 452381824310SBarry Smith 45242205254eSKarl Rupp if (col <= lastcol) low = 0; 45252205254eSKarl Rupp else high = nrow; 452681824310SBarry Smith lastcol = col; 452781824310SBarry Smith while (high-low > 5) { 452881824310SBarry Smith t = (low+high)/2; 452981824310SBarry Smith if (rp[t] > col) high = t; 453081824310SBarry Smith else low = t; 453181824310SBarry Smith } 453281824310SBarry Smith for (i=low; i<high; i++) { 453381824310SBarry Smith if (rp[i] > col) break; 453481824310SBarry Smith if (rp[i] == col) { 453581824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 453681824310SBarry Smith else ap[i] = value; 453781824310SBarry Smith goto noinsert; 453881824310SBarry Smith } 453981824310SBarry Smith } 454081824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 454181824310SBarry Smith if (nonew == 1) goto noinsert; 4542ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4543fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 454481824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 454581824310SBarry Smith /* shift up all the later entries in this row */ 454681824310SBarry Smith for (ii=N; ii>=i; ii--) { 454781824310SBarry Smith rp[ii+1] = rp[ii]; 454881824310SBarry Smith ap[ii+1] = ap[ii]; 454981824310SBarry Smith } 455081824310SBarry Smith rp[i] = col; 455181824310SBarry Smith ap[i] = value; 4552e56f5c9eSBarry Smith A->nonzerostate++; 455381824310SBarry Smith noinsert:; 455481824310SBarry Smith low = i + 1; 455581824310SBarry Smith } 455681824310SBarry Smith ailen[row] = nrow; 455781824310SBarry Smith } 455881824310SBarry Smith PetscFunctionReturnVoid(); 455981824310SBarry Smith } 45609f7953f8SBarry Smith 4561